Responsive D3 Map with Zoom and Pan Limits
D3 Geo Boilerplate: Responsive, Zoom Limits, TopoJson, and Tooltips
Here is the updated version, the new D3 World Map Template.
Over the last few weeks, I have been building a lot of D3 demos based on all kinds of world map data visualizations. D3 can be used to visualize any kind of data but I am mostly focusing on geographic information about the whole world. So, I create a world map using GeoJSON or TopoJSON, add zoom functionality, tooltips for each country, and repeat this whole process with every demo. As a result, I wanted to create a starting point, a boilerplate, that I could use for the next project which prompted this post. Here are the highlights:
- TopoJSON with Country Colors and Names
- Responsive with Zoom and Pan Limits
- Minimal CSS and Simple Tooltips
Before this demo, I have usually started these projects with Mike Bostock’s World Map example. It’s a great starting place where you get a colorful world map in TopoJSON. The geography is pulled from a Natural Earth shapefile, converted to TopoJSON, and it comes with ISO 3166-1 numeric codes to identify each country. I have used 1:110m before and it works when you are zoomed out but you really need more detail when a user zooms in. But, let’s consider colors and country identifiers.
That demo uses a topojson.neighbors call to greedily pick colors so that no adjacent country shares the same color. I like that but it does not necessarily need to be calculated. I decided to skip that process and dump the outcome straight into the TopoJSON. Same applies for ISO 3166 country codes. I kept the numbers, but I also need names for tooltips and using a separate resource to match numbers to names can be unnecessary extra processing (unless you are already processing some other data for the countries). Thus, I also dropped the country names into the TopoJSON, under properties, and with some playing around, I was able to make my final TopoJSON geo file even smaller in size than the original (613K vs 759K).
Now, I have seen a good D3 map example with constrained zoom limits and I have seen a good example of a map with responsive sizing but putting these things together and adding the ability to zoom or drag was not very straightforward. I had to actually redraw the map when the size of the browser window changes for the zoom constrains to work. To avoid the naturally occurring multiple browser resize events, I delayed the JavaScript execution by 200 milliseconds. The code also makes the border lines between countries smaller when you zoom in which is a nice touch.
It makes sense to provide country names to end users in tooltips, so I added mouseover and mouseout events and minimal CSS to render the map in the middle with a nice border and padding. The tooltips work nicely with zoom and pan, the world geography is constrained to the page and it appropriately changes to window size. It is not the perfect solution to all D3 geo needs but I think it will be a boilerplate for my next D3 World Map visualizations.
Here is the D3 World Map demo and zip with all the files.