How to make force layout graph in D3.js responsive to screen/browser size

MLister picture MLister · Aug 13, 2012 · Viewed 35.5k times · Source

I have a graph using force layout, but it has a fixed width w and height h:

var svg = d3.select("#viz").append("svg")
            .attr("id", "playgraph")
            .attr("width", w)
            .attr("height", h)

var force = d3.layout.force()
              .nodes(nodes)
              .links(links)
              .charge(-1600)
              .linkDistance(45)
              .size([w, h]); 

which results in a svg graph that does not scale or down despite of changes in screen or browser window size. In order to make it responsive (i.e. automatically resizes itself), I tried using viewBox and preserveAspectRatio attributes:

var svg = d3.select("#viz").append("svg")
            .attr("id", "playgraph")
            .attr("width", w)
            .attr("height", h)
            .attr("viewBox", "0, 0, 600, 400")
            .attr("preserveAspectRatio", "xMidYMid meet");

Unfortunately, this didn't work as nothing happens when I adjust the browser window size. I wonder if the .size([w, h]) of the force graph has anything to do with this.

Please shed some light on how to use viewBox and preserveAspectRatio attributes with force layout graphs.

Answer

methodofaction picture methodofaction · Aug 14, 2012

The problem is not within .size(), it's that you are stating the SVG dimensions in .attr("width", w) .attr("height", h). Remove these two attributes and you'll get it right...

var svg = d3.select("#viz").append("svg")
            .attr("id", "playgraph")
             //better to keep the viewBox dimensions with variables
            .attr("viewBox", "0 0 " + w + " " + h )
            .attr("preserveAspectRatio", "xMidYMid meet");

http://jsfiddle.net/aaSjd/