Some simple, frequently used functions for creating a map with D3.js and Topojson.
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.See this tutorial for more on making maps with D3. I got most of the centerZoom
function from this block.
xxxxxxxxxx
<html>
<head>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
}
.subunit {
fill: #ddd;
stroke: #fff;
stroke-width: 1px;
}
.subunit-boundary {
fill: none;
stroke: #3a403d;
}
.place-label {
font-size: .7em;
text-shadow: 0px 0px 2px #fff;
}
</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("map.json", function(error, data) {
if (error) throw error;
var boundary = centerZoom(data);
drawSubUnits(data);
drawPlaces(data);
drawOuterBoundary(data, boundary);
});
// This function "centers" and "zooms" a map by setting its projection's scale and translate according to its outer boundary
// It also returns the boundary itself in case you want to draw it to the map
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];
projection
.scale(s)
.translate(t);
return o;
}
function drawOuterBoundary(data, boundary){
g.append("path")
.datum(boundary)
.attr("d", path)
.attr("class", "subunit-boundary");
}
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)
.style("text-anchor", "start")
.text(function(d) { return d.properties.name; });
}
function drawSubUnits(data){
g.selectAll(".subunit")
.data(topojson.feature(data, data.objects.polygons).features)
.enter().append("path")
.attr("class", "subunit")
.attr("d", path);
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js