2013-07-13 77 views
42

我有這個D3圖表 - 幾乎是開箱即用。有沒有辦法讓它響應並使用寬度和高度變量,innerRadius和outerRadius的百分比?我在自適應網站上工作,需要根據屏幕大小/瀏覽器大小進行更改。響應D3圖表

的jsfiddle這裏:http://jsfiddle.net/BTfmH/1/

代碼:

<!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> 
+0

可能重複[什麼是使d3.js可視化佈局響應的最佳方式?](http://stackoverflow.com/questions/9400615/whats-the-best-way-to-make-a-d3 -js-visualization-layout-responsive) – user456584

回答

102

您可以使用的SVG元素viewBoxpreserveAspectRatio屬性的組合圖表調整大小。

請參見本的jsfiddle爲完整的例子: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 + ")"); 

你甚至不會需要一個resize處理程序使用此方法。

+0

非常感謝您的幫助!我特別欣賞這一點,因爲它沒有被解答/閒置這麼久! – TechyDude

+1

@TechyDude,沒問題 - 我自己需要這個,看到你的問題。我在其他地方找不到合適的答案,因此擴展了您的範例。 –

+0

@SamSehnert,感謝您的回答,我在https://jsfiddle.net/adityap16/11edxrnq/1/上做了類似的事情。但是當我將它移植到React時,我的情節變得非常小,你能想出任何原因嗎? –

6

您可以使用window.innerWidthwindow.innerHeight得到屏幕的尺寸,並相應地設置您的圖表,例如

var width = window.innerWidth, 
    height = window.innerHeight, 
    innerRadius = Math.min(width,height)/3, 
    outerRadius = innerRadius + 30; 
+0

感謝您的回覆Lars!這在確定基於窗口頁面的圖表方面確實有效。我將如何使用瀏覽器窗口調整大小? – TechyDude

+0

您可以使用'onresize'事件(請參閱,例如[這個問題](http://stackoverflow.com/questions/641857/javascript-window-resize-event)),但你將不得不重繪自己。 –