Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

responsive D3 chart

I have this D3 chart - pretty much out of the box. Is there a way to make it responsive and use percentages for the width and height variables, innerRadius, and outerRadius? I'm workign on a responsive site and need this to change based on screen size/browser size.

jsfiddle here: http://jsfiddle.net/BTfmH/1/

Code:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> html, body {   margin:0;   padding:0;   width:100%;   height:100%; }  .chart-container { /*  width:50%;   height:50%;*/ } </style> <body> <script src="http://d3js.org/d3.v3.min.js"></script> <script>   var width = 350,       height = 350,       τ = 2 * Math.PI;    var arc = d3.svg.arc()       .innerRadius(100)       .outerRadius(135)       .startAngle(0);  var svg = d3.select("body").append("svg")       .attr("width", width)       .attr("height", height)     .append("g")       .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")    var background = svg.append("path")       .datum({endAngle: τ})       .style("fill", "green")       .attr("d", arc);    var foreground = svg.append("path")     .datum({endAngle: .127 * τ})       .style("fill", "grey")       .attr("d", arc);  setInterval(function() {   foreground.transition()       .duration(750)       .call(arcTween, Math.random() * τ); }, 1500);    function arcTween(transition, newAngle) {      transition.attrTween("d", function(d) {        var interpolate = d3.interpolate(d.endAngle, newAngle);        return function(t) {          d.endAngle = interpolate(t);          return arc(d);       };     }); } </script> 
like image 562
TechyDude Avatar asked Jul 13 '13 03:07

TechyDude


2 Answers

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('preserveAspectRatio','xMinYMin')     .append("g")     .attr("transform", "translate(" + Math.min(width,height) / 2 + "," + Math.min(width,height) / 2 + ")"); 

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

like image 176
Sam Sehnert Avatar answered Sep 16 '22 17:09

Sam Sehnert


You can use window.innerWidth and window.innerHeight to get the dimensions of the screen and set up your graph accordingly, e.g.

var width = window.innerWidth,     height = window.innerHeight,     innerRadius = Math.min(width,height)/3,     outerRadius = innerRadius + 30; 
like image 45
Lars Kotthoff Avatar answered Sep 16 '22 17:09

Lars Kotthoff