サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

D3.jsを使う


D3.jsは、データにもとづいて動的にコンテンツを描くJavaScriptライブラリです。HTMLやSVG、CSSなどのWeb標準にのっとって、モダンブラウザにデータを可視化します。本稿はライブラリの基本的な使い方と構文について、かいつまんでご説明します。

01 D3.jsをインストールする

ライブラリはD3.jsサイトからダウンロードできます(図001)。本稿執筆時のバージョンは、4.4.0です。また、GitHubでソースが公開されています。CDNを使う場合には、つぎのコードをコピーしてください。


<script src="https://d3js.org/d3.v4.min.js"></script>

図001■D3.jsサイト

図001

02 要素を選択して設定する

D3ではHTMLのDOM要素を選択して、その操作やCSSなどの定めが加えられます。<body>要素に<p>要素が、つぎのように複数加えられていたとします。


<p>item 1</p>
<p>item 2</p>
<p>item 3</p>
<p>item 4</p>
<p>item 5</p>
<p>item 6</p>

もちろん、組み込み済みのJavaScriptで、つぎのように<p>要素すべてを取り出してスタイル(styleプロパティ)を変えることはできます。


var paragraphs = document.getElementsByTagName('p');
var length = paragraphs.length;
for (var i = 0; i < length ; i++) {
	var paragraph = paragraphs.item(i);
	paragraph.style.color = 'lightskyblue';
}

D3であれば、要素を順にすべて取り出すというコードは書かずに済みます。d3.selectAll()メソッドが、引数のセレクタに合う要素すべてを対象に定められるからです。つぎのようにselection.style()メソッドを用いて、対象の要素(<p>)すべてにスタイルが割り当てられます。


d3.selectAll('p').style('color', 'lightskyblue');

また、つぎのようにd3.select()メソッドを使うと、引数のセレクタに合う最初の要素が選べます。その後の、スタイルなどの定め方は同じです。これらのコード例は、以下のサンプル001でjsdo.itに掲げました。


d3.select('body').style('background-color', 'midnightblue');

サンプル001■D3.js: Selections

D3のセレクタは、W3Cが定めるDocument Object Model (DOM)の仕様にもとづいています。CSSと同じように、属性やクラス、IDなどが扱えます。D3における選択について詳しくは、「D3 4.0 API Reference」をご参照ください。

03 プロパティを動的に定める

セレクタで要素を定めるというのは、jQueryと似ています。D3では、さらにデータに対する関数で、プロパティの値が決められます。selection.style()メソッドの第2引数に関数(function)をつぎのように与えると、選択された要素が順に受け取られて処理されます。つまり、要素のテキストにランダムな色が加えられるのです。


d3.selectAll('p').style('color', function(){
	return 'hsl(' + Math.random() * 360 + ', 100%, 50%)';
})

関数はデータとそのインデックスを、ふたつの引数として受け取ります。JavaScriptコードをつぎのように書き替えれば、奇数番の要素のカラーはグレー(sylver)に定められます。


d3.selectAll('p').style('color', function(d, i){
	return i % 2
		? 'hsl(' + Math.random() * 360 + ', 100%, 50%)'
		: 'sylver';
})

関数の第1引数に渡すデータは、selection.data()メソッドに配列で与えます。すると、つぎのように順に受け取る配列エレメントの値を、プロパティの定めに用いることができるのです。これで、テキストの文字の大きさが、配列データにしたがって変わります。


d3.selectAll('p')
	.data([8, 11, 14, 24, 36, 42])
	.style('font-size', function(d, i) {
		return d + 'px';   
});

selectionオブジェクトのメソッドは、もとの参照を返します。したがって、同じオブジェクトに対してメソッドを呼び出すなら、ドット(.)でつなげて、つぎのようにひとつのステートメントにできます。このコード例は、以下にサンプル002としてjsdo.itに掲げました。


d3.selectAll('p')
	.style('color', function(d, i){
		return i % 2
			? 'hsl(' + Math.random() * 360 + ', 100%, 50%)'
			: 'sylver';
	}) /*;
d3.selectAll('p') */
	.data([8, 11, 14, 24, 36, 42])
	.style('font-size', function(d, i) {
		return d + 'px';   
});

サンプル002■D3.js: Dynamic Properties

04 enter()とexit()メソッド

selection.enter()メソッドを用いると、選択にノードが加えられます。そして、selection.exit()メソッドで、ノードの追加を終えます。<body>要素に加える<p>要素の数は、つぎのように少し減らしましょう。


<p>item 1</p>
<p>item 2</p>
<p>item 3</p>
<!--<p>item 4</p>
<p>item 5</p>
<p>item 6</p>-->

つぎのようにメソッドselection.enter()に続けてselection.append()を呼び出すことにより、要素が加えられます。ただし、要素はデータと組みになりますので、以下のようにデータに足りない分の要素が新たに増えることになるのです。要素のテキストは、selection.text()メソッドで与えます。


var p = d3.select('body').selectAll('p');
p.data([1, 2, 3, 4, 5])
	.enter().append('p')
	.text(function(d) {
		return 'added ' + d + '!';
	});

item 1
item 2
item 3
added 4!
added 5!

改めて、つぎのようにメソッドselection.data()でデータを定めてselection.text()を呼び出すと、要素のテキストが書き替えられます。このとき、selection.append()メソッドで加えた要素のテキストは、以下のように変わらないことにご注意ください。


// update...
p.data([1, 2, 3, 4, 5, 6])
	.text(function(d) {
		return 'updated ' + d;
	});

updated 1
updated 2
updated 3
added 4!
added 5!

すると、与えられたデータには、まだ要素と組み合わせられていない残りがあります。さらに、つぎのようにselection.append()メソッドを呼び出せば、新たにその数だけ要素は加わります。


// update...
p.data([1, 2, 3, 4, 5, 6])
	.text(function(d) {
		return 'updated ' + d;
	})  // ;
// enter...
	.enter().append('p')
	.text(function(d) {
		return 'revised ' + d;
	});

updated 1
updated 2
updated 3
added 4!
added 5!
revised 4
revised 5
revised 6

つぎのように、メソッドselection.exit()に続けてselection.remove()を呼び出せば、その後ノードは加わりません。結果が確かめやすいように、以下のサンプル003をjsdo.itに掲げます。



// update...
p.data([1, 2, 3, 4, 5, 6])
	.text(function(d) {
		return 'updated ' + d;
	})
// exit...
p.exit().remove()
// enter...  ノードは加わらない
	.enter().append('p')
	.text(function(d) {
		return 'revised ' + d;
	});

updated 1
updated 2
updated 3
added 4!
added 5!

サンプル003■D3.js: Enter and Exit

05 プロパティの値を滑らかなアニメーションで変える

selection.transition()メソッドを使うと、プロパティの変化にアニメーションが加えられます。つぎのように、続けてselection.style()メソッドを呼び出せば、背景色が滑らかに移り変わります。アニメーションの時間をミリ秒で決めるのが、transition.duration()メソッドです。


d3.select('body')
	.transition()
	.duration(1000)
	.style('background-color', 'midnightblue');

また、transition.delay()メソッドはアニメーションを始める前の待ち時間をミリ秒数で与えます。つぎのように、関数で要素ごとに決めることもできます。さらに、transition.ease()メソッドに、アニメーションの値の変え方がd3-easeメソッドで定められるのです。ここでは、d3.easeElasticOut()を選びました。この項のコード例を、以下にサンプル004としてjsdo.itに掲げます。


d3.selectAll('p')
	.data([8, 11, 14, 24, 36, 42])
	.transition()
	.duration(750)
	.delay(function(d, i) {
		return i * 250;
	})
	.ease(d3.easeElasticOut)
	.style('font-size', function(d) {
		return d + 'px';   
	});

サンプル004■D3.js: Transitions


作成者: 野中文雄
更新日: 2017年1月14日 「D3.js入門」シリーズのリンクを追加。
作成日: 2017年1月6日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.