個人的に初めてD3.js(以下、D3と呼びます)を使う機会があったので、その時に得られたD3の大まかな概要やD3(もしくはSVG)の使い所を纏めておきたいと思います。特にD3を使った事がない人向けですが、ここではD3についてハンズオン的な事はしないのでご了承ください。
D3とは
D3 (or D3.js) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data.
上記は、公式サイトからの引用です。
以下はD3のGalleryの一部ですが、D3を使う事でかなり複雑な処理でも比較的容易に実装する事ができます。勿論、モノによっては自分で計算が必要なケースもあるので、全てのサンプルが魔法のように実現できる訳ではありません。
GitHubのStar数から見るD3
2017/5/7時点でD3のGitHub上のStar数は62,821
で、全リポジトリ1,877,429
の中ではfacebook/react
に次いで5番目にStar数が多いリポジトリになっています。
GoogleTrendsから見るD3
D3のv1.0.0がリリースされたのは2011/2/18になりますが、2015/4をピークに安定した人気を保っているようです。
2016年に約4年ぶりのメジャーアップデート
2016/6/29にメジャーバージョンがアップデートされ、v4.0.0がリリースされました。現在(2017/5/7時点)では、v4.8.0が最新バージョンとなっています。
v3→v4のアップデートにより名前空間が大きく変更されたため、それまでの書籍や記事に書かれたコードは使えなくなってしまいました。しかし、アルゴリズムの見直しによる性能の向上や便利な関数が追加されているので、これからD3を学ぶ人はv4の方が恩恵が大きいと思います。
v4の変更点については以下のスライドがとても参考になります。
D3の誤解
D3.jsにあてはまらないことの記事からD3の誤解について幾つか取り上げます。
D3はチャートライブラリではない
D3のGalleryを見ると、あたかもチャートを表示するためのライブラリに見えてしまいますが、D3はチャートを含むデータのビジュアライズを比較的容易にしてくれるためのライブラリであり、Chart.jsのようなチャート専用のライブラリではありません。
因みにD3をベースにしたチャートライブラリとして、C3.jsがあります。
SVGだけでなくHTML Elementも操作できる
D3で描かれるチャートは基本的にSVGで描画されますが、div要素やinput要素などのHTML Elementsも操作する事ができます。v4からCanvasのレンダリングもサポートしたようです。
SVGのポリフィルではない
最近はレガシーブラウザも対応しなくて良い時期にきているので、あまり問題にならないと思いますが、D3はSVGのポリフィルではないので、SVGに対応していない環境(IE8やAndroidバージョン3xなど)では期待しているような使い方は出来ない可能性があります。
以下はCan I useのSVGのサポート状況を示したものです。
IE8のようなレガシーブラウザでベクターグラフィックスを利用可能にしてくれるライブラリとしてRaphael.jsがあります。
D3の旨味
jQueryライクにSVG操作
D3でDOM操作を行う場合は、jQueryの場合と似ているため、jQueryを利用した事がある人は飲み込みやすいかもしれません。例えば、DOM生成処理は以下のようになります。
//D3
var $elements = d3.select('.parent')
.append('div')
.classed('child', true)
.on('click', () => {
console.log('click child.');
});
//jQuery
var $elements = $('.parent')
.append('<div>')
.addClass('child')
.on('click', () => {
console.log('click child.');
});
他の関数に関しては以下の記事が参考になります。
要素にデータをバインドする事で反復処理が簡単に
D3の特徴の1つに要素にデータをバインドする事が挙げられます。要素にデータをバインドする事でfor文を書かずに反復処理が行えるのでコードの記述がよりシンプルになったり、増減があったデータのみに対してアニメーションの処理を加えるといった事が簡単に行えます。
例えば、以下のような縦棒グラフを表示する場合を考えます。
var chartData = [
{ value: 100, color: 'blue' },
{ value: 20, color: 'red' },
{ value: 10, color: 'green' }
];
const SVG_HEIGHT = 150;
const BAR_WIDTH = 100;
const BAR_INTERVAL = 20;
let $bars = d3.select('.svg')
.selectAll('rect')
.data( chartData )
.enter()
.append('rect')
.attr('x', (d, i) => {
return i * BAR_WIDTH + i * BAR_INTERVAL;
})
.attr('y', (d) => {
return SVG_HEIGHT - d.value;
})
.attr('width', BAR_WIDTH)
.attr('height', (d) => {
return d.value;
})
.attr('fill', (d) => {
return d.color;
});
上記の処理は、D3を使った事がない人にとっては一見分かりづらいかもしれませんが、処理の仕組みが分かれば決して難しくありません。
要点だけ説明すると、d3
オブジェクトのdata
関数を使用して.svg
要素に対してデータをセットし、append
関数でrect
要素をビューに追加しています。enter
関数はセットされたデータの一部を取得するものですが、少しややこしいのでここでは割愛します。
特に注目すべき点は、attr
関数の第二引数にコールバックを指定している点です。
このコールバック関数はデータの数だけ繰り返し実行されます。つまり、chartData
配列の長さ=3回実行されるのですが、コールバック関数の戻り値がattr
関数の第一引数で指定した属性に設定されます。
var $bars = d3.select('.svg')
//~割愛~
.attr('y', (d) => {
return SVG_HEIGHT - d.value;
})
さらにコールバック関数の第一引数d
には要素に紐づけられたデータが入るので、データに応じて柔軟に設定する値を変える事が出来ます。上記の場合は、データのvalue
値によってy
属性の値を変更しています。このように要素にデータをバインドする事でfor文を記述せずに反復処理を行う事が出来ます。
上記のような処理を利用する事でデータに応じて要素のサイズを変えたり、スタイルを変えたりする事が可能になり、データの可視化を行いやすくしてくれます。
補足:SVGとCanvasの比較
HTML5を使ってグラフィカルな表現を行う手段としてSVGとCanvasがありますが、2つの技術は根本的に異なる技術を使って描画しています。
SVGはベクターグラフィックスと呼ばれる方式で画像描画を行なっており、元となるデータは描画する要素それぞれの相対的なパス情報や色といったパラメータを扱っているため、パラメータを変更すれば大きさ等も容易に変更する事が出来ます。結果として要素を大きく描画しようが小さく描画しようが元となるデータのサイズにほとんど影響がありませんが、要素の数が多い場合は描画コストが大きくなります。
一方、Canvasはラスターグラフィックスと呼ばれる方式で画像描画を行なっており、元となるデータにはピクセル単位で色情報が格納されています。ピクセル単位で色描画した結果、1枚の絵が出来上がるような形なので、描画する絵がシンプルだろうが複雑だろうが変わりはありませんが、絵が大きい程描画コストが大きくなります。
上図の引用元:SVG と Canvas: どちらを選ぶか
まとめ
- D3はチャート専用のライブラリではない
- D3を使うと比較的簡単にデータの可視化が行える
- 描画領域のサイズと描画要素の数によってSVGとCanvasを使い分ける
v4の情報はまだ多くないかもしれませんが、D3自体の情報は少し調べればたくさん出てくるので、興味がある方は試しに使ってみると良いかもしれません。
余談ですが、以前D3を使ってGitHubのスター数を可視化した時の記事もあるので、良ければご覧ください。