D3 メモ [基礎編]

D3

データを元にHTMLを操作するためのライブラリ。データを元にしたヴィジュアライズもできるし、jQueryの様な使い方で、動的なページを作ることもできる。

http://mbostock.github.com/d3/ex/

基本的な使い方(DOM操作)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>d3 demo</title>
  <!--[if lt IE 9]>
  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
  <script src="js/libs/d3.v2.js" type="text/javascript"></script>
  <script src="js/app.js" type="text/javascript"></script>
</head>
<body onload="draw();">
  <div id="container"></div>
</body>
</html>
// app.js
function draw() {
  d3.select('#container')
    .append('p')
    .text('Hello world');
}

jQueryみたいにセレクタで要素を選択(select)し、メソッドのチェイニング(append, text)もできる。(セレクタに使えるのは、デフォルトだとSelectors API LV.1に準拠した文字列)


selectは、要素が複数見つかった場合には先頭の要素しか返さないので

  <div class="multiple"></div>
  <div class="multiple"></div>
  <div class="multiple"></div>
  <div class="multiple"></div>

の様な、複数の要素を選択したい場合にはselectAll()を使う。

  d3.selectAll('.multiple')
    .append('p')
    .text('Hello world');

データとDOMのバインド

上の例の様なjQuery的な使い方だけではなく、d3ではデータとDOM要素をバインドすることができる。

  // ダミーデータ
  var dummy = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  d3.select('#container')
    .selectAll('li')     // 後で作る要素を選択しておく
    .data(dummy)         // バインドするデータを指定する
    .enter()                   // データと関連付けした要素を生成する(プレースホルダになる)
    .append('li')        // プレースホルダに要素を追加
    .text(function(d, idx) {
      // 各<li>にバインドされたデータをテキストノードとして挿入
      return 'index: ' + idx + ', data: ' + d;
    });

配列の要素数文のli要素が生成される。
データと要素が関連付けされているかどうかは、ブラウザのデベロッパーツール等で生成されたli要素をみると、"__data__"というキーに配列の要素が値としてバインドされている事が確認できる。

SVGを使う

データを使ってSVGでグラフィックを描く

var dummy = [4, 2, 6, 1, 8, 3, 5, 9, 5, 10];

  // SVG要素を作る
  var svg = d3.select('#container')
                     .append('svg')
                     .attr('width', 500)
                     .attr('height', 310);

  console.log(svg);

以下のようなHTMLができる

<div id="container">
  <svg width="500" height="310"></svg>
</div>

変数svgには生成したsvg要素(の配列)が入ってるので、selectやappendを使って更に要素を追加できる。

// データに応じた半径の円を描く
function draw() {
  var dummy = [4, 2, 6, 1, 8, 3, 5, 9, 5, 10],
      svg,
      w = 500,
      h = 310;

  // SVG要素を作る
  svg = d3.select('#container')
                .append('svg')
                .attr('width', w)
                .attr('height', h);

  svg.selectAll('circle')
       .data(dummy)
       .enter()
       .append('circle')
       .attr('cx', function(d, idx) {
          return idx * 20 + 5
       })
       .attr('cy', h / 2)
       .attr('r', function(d) {
         return d;
       })
       .attr('fill', function(d) {
         var color = '#0000ff';
         if(d > 5) {
           color = '#ff0000';
         }

         return color;
       });

  svg.selectAll('text')
       .data(dummy)
       .enter()
       .append('text')
       .text(function(d) {
         return d;
       })
       .attr('x', function(d, idx) {
         return idx * 20;
       })
     .attr('y', function(d, idx) {
       return h / 3 * 2;
     })
     .attr('font-size', '12px')
     .attr('fill', '#333');
  }