When is D3 not enough for maps?

So this isn’t specific to Observable, but I’ve been really enjoying this site and figured people in here might give a better answer than somewhere like Stack Exchange.

I have several world map visualizations which are essentially just a Choropleth with shaded countries and a small amount of markers at specific lat/lng coords. D3 has been great and I have not needed any additional map software like Leaflet or Google Maps.

Soon I will need to add a new overlay showing clusters determined by geohashes and potentially a lot more markers.

I’m having a hard time deciding whether I am best porting these visualizations over to something like Leaflet, or sticking with pure D3 (or even trying Vega). I know some of my stakeholders would prefer a “full” mapping solution as it more easily provides things like labels at any zoom level.

I realise the two aren’t mutually exclusive - I’ve seen Mike’s D3 (v3) + Leaflet example, but I’m still trying to figure out for my use case which is the best approach.

Any suggestions would be appreciated.


Challenge accepted! :slight_smile:

There is more to maps in JS than just d3 and leaflet…

Please try to venture out and check out mapbox with deck.gl overlay.

see sample map here:

have fun!


Hi there Simon,

With enough elbow grease, you can do a lot with D3 - even recreate much of what Leaflet does. There are a few examples of zooming & panning with tiles (d3.tile), and a few years back I worked on one of the examples of d3 as a full-fledged map browsing & editing client (iD).

The most natural breaking-off point for D3 versus something like Leaflet, Google Maps or Mapbox, is world-scale data. If you need to zoom into the street level and show details anywhere, then you’ll need to load additional data dynamically, and for that you’ll need the things Leaflet and similar map clients have pre-built: tile loading, unloading, figuring out URLs, and so on. They’ll also bring things like pre-built zoom & pan controls, the ability to store the map’s centerpoint using a hash in the URL, and a pretty wide range of ‘other stuff’.

The other big difference is how things are rendered: if you’re planning on showing a lot of data on a map - thousands of markers, lots of text, raster data, and so on - there are very few ways to beat the performance of something like Mapbox GL, which has many person-years spent optimizing how it carefully loads data and uses WebGL, instead of SVG or Canvas, to display it. (disclosure: previous employer!)

The other advantage of a map-specific library is that they all (Leaflet, Google, Mapbox, OpenLayers, etc) tend to implement a certain set of interactions that people have grown used to: double-click zooming, double-right-click zoom out, scroll zoom with fixed centerpoint, etc. There are no technical reasons why you can’t recreate all these behaviors in D3, but it might devolve into a sort of whack-a-mole to get everything your stakeholders think is ‘standard’ implemented. Plus, you have a bunch of extremely performant clustering algorithms right off the open-source shelf, like supercluster and MarkerClusterer

But, there’s plenty of praises to sing about the D3 approach. First of all, it tends to be self-contained: mapping frameworks tend to rely on some company or organization, and that means relying on them for reliability, and potentially forking over some money, on an ongoing basis. D3 on the other hand, you can typically set up to just load data locally, without any additional infrastructure.

And if you’re already building other visualizations on the page, it’s great to handle both geo- and non-geo- visualizations with the same toolkit, so you can share things like color scales for those choropleth maps - and if your project is inherited by a D3-wizard developer, then they’ll have one less tool to learn.

And - one final thing - D3 handles geographical projects like a pro, whereas typical mapping software is really built around Web Mercator (the projection of Google Maps) first. It’s possible to use most of the map-specific tools with other projections, but at this point in time, it’s typically inconvenient. So if your maps are in Albers, or some other projection, and really need to be, D3 is likely a good choice.

Hope that’s helpful! There are a lot of points in each column, but neither’s a bad choice - it’s just a matter of what you want to build :slight_smile:



Thanks @tom, that is incredibly helpful.

I will definitely check out Mapbox GL, and will be using Observable to prototype these new visualisations.

I’m still not sure what the best choice is for my particular use case, but I suspect I will just experiment with different approaches and get a feel for what works best. Your response has definitely given me a clearer picture of the tradeoffs.

1 Like

wow! really? great writeup! but I still think mapbox deck.gl is where high perf. maps are these days.

was interesting to read your biased post on d3 maps. There is just too much handy work to make them work IRL IMO

Thanks @RandomFractals. That viz is very impressive! I hadn’t even heard of DeckGL until now. Looking into it now.

1 Like

yeah, def. try them all and see what best fits your use case or user base.

This site has many samples of different maps for you to fork and experiment with

I will put my case here

If you need offline map - only markers, different kind of projections, binning, basic functionality (Zoom,Pan), Svg flexibility (css styling e.t.c.) and basically all the things d3 offers, then you can use D3

Where I faced difficulties ?

  • Performance - I needed 50 K+ points to be drawn
  • Street Level Zoom - I needed street level zooming
  • GeoLocation - I needed ability to search by city name
  • Responsivity - Although I provided basic responsivity, but panning felt pretty heavy on mobile devices

So, I switched to mapbox.gl , so far it feels great on all aspects, which I had difficulties , although, If I had not these requirements, I would choose raw d3 map

The main drawback is the pricing - online maps usually costs money, when you reach monthly views limit

Before I made the switching decision, I wanted to stress test maps , mapboxgl was a clear winner

1 Like

+1 :point_up_2:


I just created Maps collection of diff. maps I’ve created on observable that cover leaflet, d3 hex binning, mapbox deck.gl, vega maps, clustered markers, heatmaps, and even leaflet with pixi overlay for you to explore some of those options that are not covered in the oficial Maps Observable collection:

P.S.: I don’t joke when I say I map and graph data :slight_smile:

Our code bits here: RandomFractals (Taras Novak) · GitHub

Have fun!


1 Like

Hi Taras,

Thanks for taking the time to share this collection. My previous experience with mapping has really been limited to pretty basic use of Google Maps, Leaflet and D3 so I’m excited to explore some new possibilities.


Hi @bumbeishvili, thanks for that. Your use case actually sounds pretty similar to mine, so I definitely think I’ll be trying out mapbox.gl. That stress test is cool, too. That’s incredible how easily it handles an insane number of markers.

1 Like


I am happy to hear we won you over to try mapbox.gl. That mapping technology with deck.gl is truly a winning combo in high perf. maps today.

Take a look at this resent post from mapbox that combines both:

Also, now I am curious what is the nature of your maps and who are the end users?



this put a smile on my face today:

Looks like you are off to a good start on maps on observable.

I hope others on this forum don’t mind us sharing those works here.