What's the Best Way to Make a D3.Js Visualisation Layout Responsive

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">

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');
.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.

Responsive D3 js chart

Set width=100% and height=100% and viewBox and preserveAspectRatio attributes for your SVG elements.

Following solution will give you direction,

var svg = d3.select('#chart').append("svg")
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox','0 0 '+Math.min(width,height)+' '+Math.min(width,height))
.append("g") ;

responsive D3 chart

You can make the chart resize using a combination of viewBox and preserveAspectRatio attributes on the SVG element.

See this jsfiddle for the full example: http://jsfiddle.net/BTfmH/12/

var svg = d3.select('.chart-container').append("svg")
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox','0 0 '+Math.min(width,height)+' '+Math.min(width,height))
.attr("transform", "translate(" + Math.min(width,height) / 2 + "," + Math.min(width,height) / 2 + ")");

You won't even need a resize handler with this method.

How to create responsive svg using d3.js

If you add a viewBox to the svg element e.g. viewBox="0 0 960 500" you won't need to resize any children.

Resize svg when window is resized in d3.js

Look for 'responsive SVG' it is pretty simple to make a SVG responsive and you don't have to worry about sizes any more.

Here is how I did it:

d3.select("div#chartId")   .append("div")   // Container class to make it responsive.   .classed("svg-container", true)    .append("svg")   // Responsive SVG needs these 2 attributes and no width and height attr.   .attr("preserveAspectRatio", "xMinYMin meet")   .attr("viewBox", "0 0 600 400")   // Class to make it responsive.   .classed("svg-content-responsive", true)   // Fill with a rectangle for visualization.   .append("rect")   .classed("rect", true)   .attr("width", 600)   .attr("height", 400);
.svg-container {  display: inline-block;  position: relative;  width: 100%;  padding-bottom: 100%; /* aspect ratio */  vertical-align: top;  overflow: hidden;}.svg-content-responsive {  display: inline-block;  position: absolute;  top: 10px;  left: 0;}
svg .rect { fill: gold; stroke: steelblue; stroke-width: 5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chartId"></div>

Related Topics

Leave a reply