D3とは、 Data-Driven Documents(データ・ドリブン・ドキュメント)のことです。 データからドキュメントを生成するためのライブラリです。 ここで言うデータというのは、グラフなどのもとになる数値のことで、それをグラフィカルな表示にします。 HTMLの表を作成したり、インタラクティブなSVGのグラフを作成し、ユーザーの操作でスムーズに変化させることができます。
グラフには色々な種類があるけれど
D3.jsは頑張れば、複雑なグラフを描けます。 D3公式サイト 「頑張れば」というのが曲者で、グラフを描ける他のライブラリとは違い、グラフを簡単に表示する機能はありません。 D3の機能を利用して、自分でグラフの見た目を作らなくてはいけません。 その分、自由度が高いのですが、それなりに頑張りが必要なわけです。
とにかく手を動かして、円グラフを作ってみた
特に理由はありませんが、円グラフを作ってみました。 ボタンを2つ置いて、データを入れ替えると、円グラフをアニメーションさせようと思います。 デモはここから
D3のライブラリを読み込み
まずは、D3.jsを読み込まないと始まりません。 公式サイトからダウンロードしても良いですし、公式サイトからリンクしても良いでしょう。 今回は、headタグ内に、リンクさせました。
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
円グラフを表示させるdivと、切り替えるボタンを置く
body内はこんな感じにします。 script.jsというファイルにガリガリとD3を書いていこうと思います。 </body>の前ならhtmlの読み込みを気にしなくて良いので、ここに書きます。 その他、円グラフを配置するdivと、ボタンを置いておきます。
<body> <div id="chart"></div> <div> <input type="button" value="データ1" id="btn1" /> <input type="button" value="データ2" id="btn2" /> </div> <script src="script.js"></script> </body>
script.jsを書く
それでは、ここからは、D3.jsでコーディングをしていきます。 補足として、ソースに書いたコメントも載せていきます。
データの用意
まずは、適当にデータを用意します。 入れ替えようのデータも準備します。
// なにかしらのデータを用意 var dataset1 = [53245, 28479, 19697, 24037, 40245]; // アニメーション用にもうひとつ用意 var dataset2 = [500, 500, 200, 500, 10];
大きさを決める
SVGで円グラフを描画するので、大きさなどを決めます。 自分で色を決めるのだ面倒だったので、d3.scale.category10で、色を用意します。
// SVGの横幅 var width = 640; // SVGの縦幅 var height = 480; // 円の大きさ var radius = Math.min(width, height) / 2 - 10; // 外側の円の大きさ var outerRadius = radius - 10; // 内側の円の大きさ。 // 穴をあけるときは数値を設定。0にすると穴はあかない。 var innerRadius = radius - 50; // 色を10色用意する関数。色は下記の通り。 // #1f77b4 #ff7f0e #2ca02c #d62728 #9467bd // #8c564b #e377c2 #7f7f7f #bcbd22 #17becf var color = d3.scale.category10();
円を生成
円グラフを作成する場合、こう書くのが決まりごとのようです。
// 円を生成します。 // sortにnullを与えると、データの順番通りに円グラフを作成します。 // 指定しない場合は、値の大きい順になります。 // D3.jsでは関数のが引数にデータが入ります。 var pie = d3.layout.pie().value(function(d) { return d; }).sort(null); // 円の大きさの設定を適用します。 var arc = d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius);
SVGの作成
上記の設定をもとにSVGを描画していきます。 D3.jsは、jQueryのようなチェーンメソッドを採用しています。
// SVG作成 // selectでhtmlのタグ/class/idなどで選択します。 var svg = d3.select("#chart") // appnedでsvgタグを追加します。 .append("svg") // attrでタグの属性を設定します。 .attr("width", width).attr("height", height) // appendでsvgのgタグ(グループ要素)を追加します。 // svg内で描画すると、いくつもタグができるので、まとめて動かすときに便利です。 .append("g") // 描画場所をsvgの中央にします。 .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // 使いまわしたいので、ここで切ります。 // 描画するだけなら続けて描いても同じです。
グループの作成とデータの読み込み
dataで円としてデータを読み込みます。 そうすると、データがsvgのタグと関連付けされ、enterとappendでデータ分だけタグが増えます。 dataset1の中には5つデータがあるので、gタグは5つ追加されます。
var g = svg // 円はpathというタグで描画されるので、selectAllでまとめてタグを選択します。 .selectAll("path") // dataでデータを設定します // 円グラフの場合は、事前に準備したpieを利用しないといけません。 .data(pie(dataset1)) // 要素を自動で増やす時は、enterを使用します。 .enter() //文字と一緒に円を扱いたいので、gを追加します。 // dataとenterがあるので、データの分だけ自動で増えます。 .append("g"); // 円と文字を個別に設定するので、切ります。
円の描画
増やしたgタグ内に、円を描くときに使用するpathタグを追加します。
//円を描画します。 g // 円を描くpathを追加します。 .append("path") // fillはsvgの塗りの属性です。 // 関数で設定するとdataとindexを使えるので、事前に用意したcolorから // indexで色を取り出して設定します。 .attr("fill", function(d, i) { return color(i); }) // d属性でpathをどう描くか決めます。 // 事前に用意したarcで円を設定できるので、それを入れます。 .attr("d", arc) // 今の数値を保存します。 .each(function(d) { this._current = d; });
文字の描画
円と同じようにデータの数値を文字としても表示してみます。 SVGにはtextというタグで文字が書けます。
//文字を描画します。 g // 文字をを描くtextを追加します。 .append("text") // 文字の位置を円の要素の中心にします。 .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; }) // 文字の大きさを設定します。 .attr("font-size", "30") // 文字の開始位置をセンターにします。 .style("text-anchor", "middle") //文字の内容を入れます。 .text(function(d) { return d.data; }) //eachで今の数値を保存します。 .each(function(d) { this._current = d; });
イベントの追加
二つのボタンに、クリックでデータが変更するように、イベントを入れます。
//#btnにclickイベントを追加します。 d3.select("#btn1").on("click",function (){arcAnime(dataset1);} , false); d3.select("#btn2").on("click",function (){arcAnime(dataset2);} , false);
イベントの内容
arcAnimeでは、データを入れ替えて、円と文字にアニメーションを加えています。
//clickイベントの関数を記述します。 function arcAnime(newdata) { svg .selectAll("path") // 新しいデータを設定します。 .data(pie(newdata)) // トランジションを設定するとアニメーションさせることができます。 .transition() // アニメーションの秒数を設定します。 .duration(800) // アニメーションの間の数値を補完します。 .attrTween("d", function(d) { var interpolate = d3.interpolate(this._current, d); this._current = interpolate(0); return function(t) { return arc(interpolate(t)); }; }); svg .selectAll("text") // 新しいデータを設定します。 .data(pie(newdata)) //文字を更新します。 .text(function(d) { return d.data; }) // トランジションを設定。 .transition() // アニメーションの秒数を設定。 .duration(800) // アニメーションの間の数値を補完。 .attrTween("transform", function(d) { var interpolate = d3.interpolate(arc.centroid(this._current), arc.centroid(d)); this._current = d; return function(t) { return "translate(" + interpolate(t) + ")"; }; }); }
まとめ
D3.jsは、難しそうなリッチなデータ表示を、比較的簡単に作ることができるのが魅力です。 少し学習コストは高いですが、オリジナルにこだわりたい方は、勉強するのも良いのではないでしょうか。
コメント