HTML5テクニカルノート
D3.jsを使う
- ID: FN1701003
- Technique: HTML5 / JavaScript
- Library: D3.js 4.4.0
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サイト
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
- D3.js入門 01: 棒グラフを描く
- D3.js入門 02: 外部ファイルのデータからSVGで棒グラフを描く
- D3.js入門 03: 立て棒グラフに軸の記載を加える
- D3.js入門 04: グラフにアニメーションを加える
- D3.js入門 05: グラフの棒にラベルを加える
作成者: 野中文雄
更新日: 2017年1月14日 「D3.js入門」シリーズのリンクを追加。
作成日: 2017年1月6日
Copyright © 2001-2017 Fumio Nonaka. All rights reserved.