假设我有一个直方图脚本,构建960 500 svg图形。我如何使这个响应,以便调整图形的宽度和高度是动态的?
<script>
var n = 10000, // number of trials
m = 10, // number of random variables
data = [];
// Generate an Irwin-Hall distribution.
for (var i = 0; i < n; i++) {
for (var s = 0, j = 0; j < m; j++) {
s += Math.random();
}
data.push(s);
}
var histogram = d3.layout.histogram()
(data);
var width = 960,
height = 500;
var x = d3.scale.ordinal()
.domain(histogram.map(function(d) { return d.x; }))
.rangeRoundBands([0, width]);
var y = d3.scale.linear()
.domain([0, d3.max(histogram.map(function(d) { return d.y; }))])
.range([0, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("rect")
.data(histogram)
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return height - y(d.y); })
.attr("height", function(d) { return y(d.y); });
svg.append("line")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", height)
.attr("y2", height);
</script>
完整的直方图示例要点如下:
https://gist.github.com/993912
以防人们还在问这个问题——以下是对我有用的方法:
Enclose the iframe in a div and use css to add a padding of, say, 40% to that div (the percentage depending on the aspect ratio you want). Then set both width and height of the iframe itself to 100%.
In the html doc containing the chart to be loaded in the iframe, set width to the width of the div that the svg is appended to (or to the width of the body) and set height to width * aspect ratio.
Write a function that reloads the iframe content upon window resize, so as to adapt the size of the chart when people rotate their phone.
在我的网站上有一个例子:
http://dirkmjk.nl/en/2016/05/embedding-d3js-charts-responsive-website
2016年12月30日更新
我上面描述的方法有一些缺点,特别是它没有考虑任何不在d3创建的svg中的标题和说明文字的高度。后来我想到了一个我认为更好的方法:
将D3图表的宽度设置为它所附的div的宽度,并使用纵横比来相应地设置它的高度;
使用HTML5的postMessage将嵌入页面的高度和url发送到父页面;
在父页面上,使用url识别相应的iframe(如果页面上有多个iframe,则很有用),并将其高度更新为嵌入页面的高度。
例子在我的网站上:http://dirkmjk.nl/en/2016/12/embedding-d3js-charts-responsive-website-better-solution
寻找“响应式SVG”,使SVG响应式非常简单,您不必再担心大小问题。
以下是我的做法:
d3.select("div#chartId")
.append("div")
.classed("svg-container", true) //container class to make it responsive
.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);
CSS代码:
.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;
}
更多信息/教程:
http://demosthenes.info/blog/744/Make-SVG-Responsive
http://soqr.fr/testsvg/embed-svg-liquid-layout-responsive-web-design.php