D3.js データバインディングの方法 - data(), enter()

データバインディングと使い方。data(), enter(), attr(), style()

データバインディングの方法

D3はさまざまなデータ形式に対応しており、CSVやJSONなどを読み込むメソッドが用意されている。

ここでは、簡単なサンプルデータセットを次のように用意する。

var dataset = [ 1, 2, 3, 4, 5 ];

次のコードでデータと要素を結び付けてみる。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>D3 Test</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <script>
      // ここにコードを記述する。
      var dataset = [ 1, 2, 3, 4, 5 ];
    </script>
  </body>
</html>

まず、どの要素に結び付けるかを決める。

d3.select("body").selectAll("p")

<body>タグの中から<p>要素を選択している。

ただし、選択しようとしている<p>タグはまだ存在しない。ここでD3特有の方法を使う。まだ存在しない要素を選択し、そこへ追加するためにenter()を使用する。最終的な方法は次のようになる。

d3.select("body").selectAll("p")
  .data(dataset)
  .enter()
  .append("p")
  .text("Hello!");

この方法で何をしているかを見ると、まずページ内の<body>タグを検索している。

d3.select("body")

そして次のメソッドへ参照を渡す。

.selectAll("p")

参照として渡された<body>内の<p>要素を検索し、次へ渡す。まだ存在しないため、空の選択を次のメソッドへ渡す。

.data(dataset)

データ数を数えて解析する。ここでは5つの値が設定される。

.enter()

データがバインドされた新しい要素を作成するには、enter()を使用する必要がある。このメソッドはページ上の対象要素を調べ、次に渡されるデータを調べる。
対象要素より多くのデータ値がある場合、一時的な参照場所を作成し、その参照を次のメソッドへ渡す。

.append("p")

enter()によって作成された一時的な参照先を受け取り、<p>要素をページへ挿入する。その後、作成した要素への参照を次のメソッドへ渡す。

.text("Hello!")

新しく作成した<p>要素への参照を受け取り、テキスト値を挿入する。

最終的なコードは次のとおりである。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>D3 Test</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <script>
      // ここにコードを記述する。
      var dataset = [ 1, 2, 3, 4, 5 ];
      d3.select("body").selectAll("p")
        .data(dataset)
        .enter()
        .append("p")
        .text("Hello!");
    </script>
  </body>
</html>

実行すると、次のようにHello!が5つ表示される。

Google Chromeの開発者ツールでページの構文を確認すると、次のように5つのpタグが追加されていることがわかる。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>D3 Test</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <script>
      // ここにコードを記述する。
      var dataset = [ 1, 2, 3, 4, 5 ];
      d3.select("body").selectAll("p")
        .data(dataset)
        .enter()
        .append("p")
        .text("Hello!");
    </script>
    <p>Hello!</p>
    <p>Hello!</p>
    <p>Hello!</p>
    <p>Hello!</p>
    <p>Hello!</p>  
</body>
</html>

データの使い方

バインドしたデータの使い方を説明する。

まず、バインドするデータを用意する。

var dataset = [ 1, 2, 3, 4, 5 ];

次のメソッド内の引数を関数にする。

たとえば、次のようなコードがある場合、

d3.select("body").selectAll("p")
  .data(dataset)
  .enter()
  .append("p")
  .text("Hello!");

最後の行のtext()関数を次のように変更する。

  .text(function(d) { return d; });

すると、次のように表示される。

data()を呼び出した後は、連続したメソッド内で入力値として受け取る関数をいつでも作成できる。

JavaScriptの関数は次のような形式で設定する。

function (入力値) {
    // ここに処理コードを入れる。
    return 出力値;
}

D3でデータを使用する場合、入力値には必ずdを宣言する。入力値にdを宣言しないと、バインドされたデータを参照できない。

引数を関数にすると、次のような処理も可能である。

.text(function(d) {
    return "この値は " + d + " である";
});

関数内の処理を変更することで、さまざまな処理ができるようになる。

属性の設定

attr()style()など、D3の他のメソッドと組み合わせると、HTMLやCSSの属性を設定できる。

たとえば、次のようにコードへstyle関連の関数を追加すると、設定した内容が要素に反映される。

d3.select("body").selectAll("p")
  .data(dataset)
  .enter()
  .append("p")
  .text(function(d) {
    return "この値は " + d + " である";
  })
  .style("color", "red");

すべてのテキストが赤色に変わった。

ここでも関数を使用し、データに応じて色を変更できる。

.style("color", function(d) {
  if (d % 2 == 0) {
    return "red";
  } else {
    return "black";
  }
});

dを2で割って0になる場合、つまりdが偶数の場合に赤色へ変更された。