1. ホーム
  2. ジャバスクリプト

[解決済み】d3.jsのビジュアライゼーションレイアウトをレスポンシブにする最適な方法は?

2022-04-04 03:35:46

質問

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> 

ヒストグラムの全例gistは https://gist.github.com/993912

解決方法は?

グラフの再描画を必要としない、もうひとつの方法があります。 ビューボックス preserveAspectRatio 属性は <svg> 要素を使用します。

<svg id="chart" viewBox="0 0 960 500"
  preserveAspectRatio="xMidYMid meet">
</svg>

2015年11月24日更新 ほとんどのモダンブラウザは アスペクト比を推測する から、SVG 要素の viewBox そのため、グラフのサイズを常に最新に保つ必要はないかもしれません。古いブラウザに対応する必要がある場合は、このようにウィンドウのサイズ変更時に要素のサイズを変更することができます。

var aspect = width / height,
    chart = d3.select('#chart');
d3.select(window)
  .on("resize", function() {
    var targetWidth = chart.node().getBoundingClientRect().width;
    chart.attr("width", targetWidth);
    chart.attr("height", targetWidth / aspect);
  });

そして、svgのコンテンツは自動的に拡大縮小されます。この例を見てみましょう(若干の修正を加えています)。 ここで ウィンドウのサイズや右下のペインのサイズを変更するだけで、どのように反応するかを確認することができます。