Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active November 20, 2016 05:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarryStevens/c9cf86eba753ba8650fb466e37d538d2 to your computer and use it in GitHub Desktop.
Save HarryStevens/c9cf86eba753ba8650fb466e37d538d2 to your computer and use it in GitHub Desktop.
India Mercator
license: gpl-3.0
height: 700

Draw a map of India with D3.js, Topojson, and five simple functions:

  • centerZoom - Automatically centers and scales your map to its container, and returns your map's outer boundaries in case you want to draw them.
  • drawOuterBoundary - Uses the boundary returned from centerZoom to draw a boundary around your whole map.
  • drawPlaces - Draws place names, if your topojson has places.
  • drawSubunits - Draws subunits.
  • colorSubunits - Colors the subunits.

This map uses a Mercator projection, and the colors are generated from d3.schemeCategory20. For a tutorial on converting Geojson to Topojson and for finding the coordinates of major cities, see this tutorial.

<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: "Helvetica Neue", sans-serif;
margin: 0;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js"></script>
<script>
var width = window.innerWidth, height = window.innerHeight;
var projection = d3.geoMercator();
var path = d3.geoPath()
.projection(projection)
.pointRadius(2);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g");
d3.json("india.json", function(error, data){
var boundary = centerZoom(data);
var subunits = drawSubUnits(data);
colorSubunits(subunits);
drawSubUnitLabels(data);
drawPlaces(data);
drawOuterBoundary(data, boundary);
});
function centerZoom(data){
var o = topojson.mesh(data, data.objects.polygons, function(a, b) { return a === b; });
projection
.scale(1)
.translate([0, 0]);
var b = path.bounds(o),
s = 1 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];
var p = projection
.scale(s)
.translate(t);
return o;
}
function drawOuterBoundary(data, boundary){
g.append("path")
.datum(boundary)
.attr("d", path)
.attr("class", "subunit-boundary")
.attr("fill", "none")
.attr("stroke", "#3a403d");
}
function drawPlaces(data){
g.append("path")
.datum(topojson.feature(data, data.objects.places))
.attr("d", path)
.attr("class", "place");
g.selectAll(".place-label")
.data(topojson.feature(data, data.objects.places).features)
.enter().append("text")
.attr("class", "place-label")
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
.attr("dy", ".35em")
.attr("x", 6)
.attr("text-anchor", "start")
.style("font-size", ".7em")
.style("text-shadow", "0px 0px 2px #fff")
.text(function(d) { return d.properties.name; });
}
function drawSubUnits(data){
var subunits = g.selectAll(".subunit")
.data(topojson.feature(data, data.objects.polygons).features)
.enter().append("path")
.attr("class", "subunit")
.attr("d", path)
.style("stroke", "#fff")
.style("stroke-width", "1px");
return subunits;
}
function drawSubUnitLabels(data){
g.selectAll(".subunit-label")
.data(topojson.feature(data, data.objects.polygons).features)
.enter().append("text")
.attr("class", "subunit-label")
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.style("font-size", ".5em")
.style("text-shadow", "0px 0px 2px #fff")
.style("text-transform", "uppercase")
.text(function(d) { return d.properties.st_nm; });
}
function colorSubunits(subunits) {
var c = d3.scaleOrdinal(d3.schemeCategory20);
subunits
.style("fill", function(d,i){ return c(i); })
.style("opacity", ".6");
}
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment