What’s the best way to make a d3.js visualisation layout responsive?

There’s another way to do this that doesn’t require redrawing the graph, and it involves modifying the viewBox and preserveAspectRatio attributes on the <svg> element:

<svg id="chart" viewBox="0 0 960 500"
  preserveAspectRatio="xMidYMid meet">
</svg>

Update 11/24/15: most modern browsers can infer the aspect ratio of SVG elements from the viewBox, so you may not need to keep the chart’s size up to date. If you need to support older browsers, you can resize your element when the window resizes like so:

var aspect = width / height,
    chart = d3.select('#chart');
d3.select(window)
  .on("resize", function() {
    var targetWidth = chart.node().getBoundingClientRect().width;
    chart.attr("width", targetWidth);
    chart.attr("height", targetWidth / aspect);
  });

And the svg contents will be scaled automatically. You can see a working example of this (with some modifications) here: just resize the window or the bottom right pane to see how it reacts.

Leave a Comment