DEV Community

loading...
Cover image for Interactive SVG + JS map

Interactive SVG + JS map

lucafaggianelli profile image Luca Faggianelli ・3 min read

Now and then, on several web applications projects, I need to use maps to display data, sometimes it's a world map, sometimes a country map with regions and provinces, often I need a click-on-region event handler and I always need to display some data on the map as colors or numbers. You know what I'm talking about right? Not a Google Maps map, but a simple and plain map with country borders.

Of course there are libraries for this purpose, also free ones, but not so many and they're pretty heavy as they bring a lot of functionalities, whereas I just need a simple map, so I like to make my own map, also because it's fun 🙂. Let's make it!

Get started

The first step is to find a map in SVG format, I typically use simplemaps they have world and regional maps and they're free to use (check the license for details).

When I speak of regions I refer to geographical regions, that is any of country, region, province, state, area, etc.

Now we're ready to go, these are the features we're going to implement at the end of the article:

  1. Load the SVG map and render it into the HTML page
  2. Color the map regions based on supplied data
  3. Attach mouse events listeners (for click and hover) to regions

So let's start with step 1 and part of 2:

Yeah so easy! I only used a tiny library for SVG manipulation called Svg.js, even if it's not mandatory, it makes life a bit easier.
In the codepen above we load the map SVG file content with the fetch() method and we render it into the HTML, then we manipulate the map adding labels and changing the colors just for demo purpose.

Please note that I'm selecting the map regions with draw.find('path') but if you use another map, the regions may be represented by <g> elements or may be inside nested into other elements.

OK let's make this thing a bit more useful, I found Belgian population data (2019) on Wikipedia and we're going to plot it on our map, plus we'll make it interactive!

Better? Now we have real data and each region's color represent its population, the colors are shades between green and white, whereas the most populated region (Antwerp province) has a mix of 100% of green and 0% of white, while the least populated (Luxembourg province) has more white than green: this is called a heatmap. As for the interaction, if you hover a region, you get a popup and the region color changes. The color effect is done with CSS to demonstrate that you can style an SVG element (and its children) with plain CSS.

This is pretty basic, but it's good starting point for creating a fully featured map.
I'm going to extend this demo with more features and I'm going to package it into an NPM library, so stay tuned!

Well now I'm curious, do you use maps and for what? Do you use them in apps you develop or in blog post or whatever? What library do you use?
Questions and feedbacks are highly appreciated!

Luca

Discussion

pic
Editor guide
Collapse
khalyomede profile image
Khalyomede

Very cool! I did not know this tool.

On my previous job, we had to be able to drag, pan and rotate a map, and we first used npmjs.com/package/svg-pan-zoom, but we came up to some difficulties when adding the rotation. So we ended up creating our own SVG engine. It was fun to do!

Collapse
lucafaggianelli profile image
Luca Faggianelli Author

Thank you! Yeah pan and zoom may be very tricky, in fact also svg.js has some glitches in certain cases during panning, but overall is very useful and light.

Collapse
tavi profile image
Octavian Nita

Awesome! Is there any option to display a map with a 3D-ish/extruded like border?

Collapse
lucafaggianelli profile image
Luca Faggianelli Author

Thanks! It's a nice idea, you can play with SVG filters to add a drop shadow or even better you can create an extrusion effect with <feConvolveMatrix> filter. SVG filters is a tricky topic, here a nice article: smashingmagazine.com/2015/05/why-t...
And here a plugin for svg.js to handle filters github.com/svgdotjs/svg.filter.js

Collapse
tavi profile image