John DiMattia
3 min readJul 26, 2014

I feel like I’ve been googling “d3 responsive charts” every time I start to do some d3 work and I’d like to once and for all record what I’ve learned so I can stop doing that. The way to do responsive charts seem to fall into roughly three camps.

  1. Use svg attribute viewBox with attribute preserveAspectRatio. Example: first answer on this stackoverflow. The idea being you specify an explicit, pixel based height and width in viewBox and write all your code to use those numbers. Then when the height and width attributes of the svg element are changed, your chart will scale accordingly.

Pros: It’s easy. You can also make the svg width and height attributes 100% so you don’t have to watch the window resize event.

Cons: There’s the issue of your text size staying the same, but really this method falls short on the full definition of being responsive. Yes, the chart will change size for a smaller screen. But what about progressive enhancement? The idea of starting with just what’s useful and necessary for small screens and then adding more with more screen real estate. Things can get crowded quickly and become unreadable by just shrinking a chart that looks good at the desktop size. So really the main con of the viewBox method is you aren’t choosing which elements should or should not go into each breakpoint (phone, tablet or bootstrap xs, sm, md) of your chart size.

2. Watch window width and when your chart container changes size, blow everything away and re-render. Example: npr team. Here the idea is to watch for changes in window width, figure out the size of the chart container, then call something like svg.selectAll(‘*’).remove(); to remove everything and re-render it all with the new width and a new height calculated from the container width and an aspect ratio.

Pros: You can decide what should and shouldn’t go into certain sizes by only adding certain elements when width > some breakpoint width. You have total control over the re-rendering process.

Cons: Seems wasteful to remove everything and have to redraw it just because the size updated. But I mean, how often does page width change? Unless someone’s playing accordian with their browser window, it should really only happen on load.

3. Watch window width and when your chart container changes size, update just what needs updating (i.e. don’t blow away everything). Example: Safari books. Same as number 2 above, but since you can (in d3) dynamically update things like the number of ticks on an axis and the data points of a line, you don’t have to blow everything away.

Pros: Your whole chart won’t be blown away, just the parts that need updating will update. You could even animate the transition if you want to get fancy. Seems like the “most correct” way to do it.

Cons: It’s way easier to just blow the whole thing away and re-render instead of separating out the things that need to change from the things that don’t. The code this way might also be more confusing for d3 newcomers to read as, for example, you’ll be defining an axis and setting it’s domain in one part of the code, but then updating that same axis’ range in the re-render function.

So there you have it, everything I know about making d3 responsive charts.