D3.js 折れ線チャート(line chart)の作成

D3で基本チャートである折れ線チャートを作成する方法を説明する。

サンプルプログラム

コードを確認

サンプルコード

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>D3 Line Chart</title>
  <script src="https://d3js.org/d3.v7.min.js"></script>
</head>

<body>
  <script>
    // 1. データ準備
    var dataset = [
      [5, 20],
      [25, 67],
      [85, 21],
      [100, 33],
      [220, 88],
      [250, 50],
      [330, 95],
      [410, 12],
      [475, 44],
      [480, 90]
    ];

    var width = 400; // グラフ幅
    var height = 300; // グラフ高さ
    var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };

    // 2. SVG領域設定
    var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);

    // 3. 軸スケール(目盛り)設定
    var xScale = d3.scaleLinear()
      .domain([0, d3.max(dataset, function (d) { return d[0]; })])
      .range([margin.left, width - margin.right]);

    var yScale = d3.scaleLinear()
      .domain([0, d3.max(dataset, function (d) { return d[1]; })])
      .range([height - margin.bottom, margin.top]);

    // 4. 軸表示
    var axisx = d3.axisBottom(xScale).ticks(5);
    var axisy = d3.axisLeft(yScale).ticks(5);

    svg.append("g")
      .attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
      .call(axisx)
      .append("text")
      .attr("fill", "black")
      .attr("x", (width - margin.left - margin.right) / 2 + margin.left)
      .attr("y", 35)
      .attr("text-anchor", "middle")
      .attr("font-size", "10pt")
      .attr("font-weight", "bold")
      .text("X Label");

    svg.append("g")
      .attr("transform", "translate(" + margin.left + "," + 0 + ")")
      .call(axisy)
      .append("text")
      .attr("fill", "black")
      .attr("text-anchor", "middle")
      .attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
      .attr("y", -35)
      .attr("transform", "rotate(-90)")
      .attr("font-weight", "bold")
      .attr("font-size", "10pt")
      .text("Y Label");

    // 5. ライン表示
    svg.append("path")
      .datum(dataset)
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-width", 1.5)
      .attr("d", d3.line()
        .x(function (d) { return xScale(d[0]); })
        .y(function (d) { return yScale(d[1]); }));
  </script>
</body>

</html>

サンプルコード説明

散布図グラフを段階的に描画して説明ページでは、散布図を作成する方法を詳しく紹介している。折れ線チャートはPlotの部分を少し変更すれば描画できる。

1. データ準備

余白を設定するためにオブジェクトを宣言した。

var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };

軸を表示するため、下端と左側のマージンを大きく設定する。

2. SVG領域設定

SVGの表示領域を設定する。

3. 軸スケール設定

軸スケールを設定する。

d3.scaleLinear()

上のコードで、domain(..)で設定した範囲をrange(..)で設定した範囲へ変換する関数を設定する。線グラフの座標を画面のピクセル値へ変換する関数を作成する。

4. 軸表示

D3の関数d3.axisBottom()d3.axisLeft()を使用して軸要素を設定する。引数を軸スケールの設定で作成した関数にし、callで呼び出すことでSVG要素が自動的に追加される。

  var axisx = d3.axisBottom(xScale).ticks(5);
  var axisy = d3.axisLeft(yScale).ticks(5);

  svg.append("g")
    .attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
    .call(axisx)

  svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + 0 + ")")
    .call(axisy)

.ticks()は軸目盛りの数を制御するメソッドである。整数で設定する。

軸を呼び出し、text要素で軸ラベルを追加する。

    .append("text")
    .attr("fill", "black")
    .attr("x", (width - margin.left - margin.right) / 2 + margin.left)
    .attr("y", 35)
    .attr("text-anchor", "middle")
    .attr("font-size", "10pt")
    .attr("font-weight", "bold")
    .text("X Label");

    .append("text")
    .attr("fill", "black")
    .attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
    .attr("y", -35)
    .attr("transform", "rotate(-90)")
    .attr("text-anchor", "middle")
    .attr("font-weight", "bold")
    .attr("font-size", "10pt")
    .text("Y Label");

"text-anchor"はテキストの位置合わせ用の属性で、"middle"で中央揃えを設定している。それぞれ軸に重ならないように35pxずつ移動している。

5. ライン表示

折れ線チャートのラインを"path"要素で表示する。データバインディングは次のようにしている。

.datum(dataset)

1つずつデータをバインドするdataとは異なり、1つのpathにデータセットを追加するためにdatumを使用する。

次のコードは、SVG要素の経路の"d"属性を作成するメソッドである。

  d3.line()
    .x(function(d) { return xScale(d[0]); })
    .y(function(d) { return yScale(d[1]); })

まとめ

折れ線チャートは棒グラフおよび散布図と同じアルゴリズムで作成できる。1つ作成すれば、他のグラフにも簡単に応用できる。