秋のJavaScript祭りに参加しました。
その中のセッションで紹介されていたD3.jsというJavaScriptライブラリを触ってみたのでちょいとメモ。
セッションスライドはこちらです。
D3.jsでのデータビジュアライゼーション -人口統計データから使い方を学ぶ-
インストール
D3用のプロジェクトディレクトリ(ここではd3_sample
)を作り
その下にD3.jsをインストールします。
コードは公式サイトからzip形式でダウンロードすることもできますが
今回はGitHubから。
git clone git@github.com:mbostock/d3.git
プロジェクトディレクトリの下にd3
というディレクトリが作成されてるはずです。
触ってみる
日本語の丁寧なチュートリアルがあるので、それを一通り読むと大体理解できそうです。
http://ja.d3js.info/alignedleft/tutorials/d3/
ここではd3がどんなものかを確認するために、プロジェクトディレクトリ直下にindex.html
を作成し、以下を記述します。
(コードは散布図の描画のコード)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>D3 Test</title> <script type="text/javascript" src="d3/d3.js"></script> <style> div.bar { display: inline-block; width: 20px; height: 75px; /* この数値は実行時に上書きされます */ background-color: teal; margin-right: 2px; } </style> </head> <body> <script type="text/javascript"> var dataset = [ [ 5, 20 ], [ 480, 90 ], [ 250, 50 ], [ 100, 33 ], [ 330, 95 ], [ 410, 12 ], [ 475, 44 ], [ 25, 67 ], [ 85, 21 ], [ 220, 88 ] ], w = 500, h = 100; // SVG 要素の生成 var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h); // 円の描画 svg.selectAll('circle') .data(dataset) .enter() .append('circle') .attr('cx', function(d) { return d[0]; }) .attr('cy', function(d) { return d[1]; }) .attr('r', function(d) { return Math.sqrt(h - d[1]); }); // ラベルの描画 svg.selectAll('text') .data(dataset) .enter() .append('text') .text(function(d) { return d[0] + ',' + d[1]; }) .attr('x', function(d) { return d[0]; }) .attr('y', function(d) { return d[1]; }) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "red"); </script> </body> </html>
保存したら、結果を確認するためにローカルサーバーを立ち上げます。
ここ にも書いてますが、pythonを使うと簡単に実行できます。
# python 2.X python -m SimpleHTTPServer 8888 & # python 3 python -m http.server 8888 &
実行したら http://localhost:8888/ にアクセス。
すると、こんな形で散布図が表示されます。
ポイントだけメモ
svg.selectAll('circle') .data(dataset) .enter() .append('circle')
一番重要なこととして、data(dataset)
は受け渡されたデータの数を数え、
それ以降のメソッドはデータを1つずつに対してforループのように実行されます。
また、その後の
.attr('cx', function(d) { return d[0]; })
などは要素に属性を指定してますが、ここで呼ばれている無名関数function(d)
のd
にはデータが1件ずつ渡されます。
d
は変数名なのでなんでもいいんですが慣習的にd
が多いそう。
selectAll
はセレクト対象要素(ここではsvg)の中から指定した要素をすべて取得するメソッドですが、
この時点ではcircle要素は1つも存在していません。
ですが、それをあまり気にする必要はないとのこと。
なぜなら、その後のenter()
メソッドは、最初に DOM を調べ、次にdata(dataset)
によって受け渡されたデータを調べます。
もし該当する DOM 要素の数よりデータの値の個数が多い場合は、enter() は新規に要素を追加するからです。
おわりに
というわけで、今回試したチュートリアルのグラフはかなり簡単なものですが
複雑なグラフでのプロットとかも簡単に行えそうで、便利そうだなーと感じました。
メソッドチェインで書けるおかげでコードの見通しも良くなっている気がします。