D3.js入門(Data-Driven Documents)

D3.js入門(Data-DrivenDocuments)
by
HitoshiNakanishi
PoweredbyOpenBook
§1d3.jsチュートリアルまとめ(前半)
1.1d3.jsチュートリアル
スコット・マレイによって書かれたチュートリアルの簡単なまとめ。
http://ja.d3js.info/alignedleft/tutorials/d3/
簡単な用語説明
HTML...ハイパーテキスト・マークアップ・ランゲージのこと。ウェブブラウザのコンテン
ツ作成のために使う。
DOM...ドキュメント・オブジェクト・モデルのこと。HTMLの階層構造を表したものであ
る。かぎカッコに囲まれたそれぞれのタグが要素で、要素間の相対的な関係を、人間の関
係になぞらえて、親(parent)、子(child)、兄弟(sibling)、先祖(ancestor)、子
孫(descendant)などと表す。Ex.
<p></p>
CSS...カスケーディング・スタイル・シートのこと。HTMLページの見た目のスタイルを
設定するのに使う。
Javascript...JavaScriptは動的なスクリプト言語です。ブラウザがページを読み込んだ後に
それを変更することができる。
SVG...スケーラブル・ベクター・グラフィックスのこと。SVGはテキストベースの画像フ
ォーマット。SVG画像がどう表示されるかを、HTMLタグによく似た簡単なマークアップ
コードの記述だけで指定できる。
ダウンロード
ダウンロードはここからできる。http://d3js.org/
要素の追加
D3を使って新しいDOM要素を生成することが必要。データ視覚化レンダリングの場合、
一般的には生成する要素はSVGオブジェクトになるが、ここでは分かりやすさ優先でパ
ラグラフ要素pを生成してみる。
d3.select("body").append("p").text("新しいパラグラフ!");
今ここで起こったことは、
1. D3のselectメソッドを呼び出します。このメソッドは、CSSセレクタ構文を使って
DOMの中から要素を一つ選択します(ここではbodyを選択しました)。
2. 新しくp要素を生成し、現在のセレクション(選択要素)の最後に追加します。今回の
場合、終了タグ
の直前になります。
空のパラグラフ要素のテキストに「新しいパラグラフ!」をセットします。
間に挟まれた意味不明のドット(.)は、D3のチェイン構文です
メソッドの内容
d3:D3オブジェクトへの参照であり、D3のメソッドにアクセスするためのものです。
.select("body"):select()にCSSセレクタを与えると、DOM中でセレクタにマッチする最
初の要素の参照を返します(複数の要素にマッチさせたい場合はselectAll()を使いま
す)。ここではbodyだけが必要ですので、select()を使い、bodyへの参照をチェインの
次のメソッドに引き渡します。
.append("p"):append()は引数に指定した任意の要素を新規に生成し、受け渡された任意の
セレクションの最後に(ただしその内側に)追加します。ここではbodyの内部に新しくp
を生成したいので、引数として"p"を与えます。チェイン上流のselect()メソッドから
body要素への参照を受け取ったことはメソッド自身が理解しています。最後にappend()
は、生成したばかりの新しい要素への参照を次のメソッドに受け渡します。
.text("新しいパラグラフ!"):text()は文字列を受け取り、それを現在のセレクションの開始
タグと終了タグの間に挿入します。ここでは前のメソッドから新しいp要素への参照を受
け取っているので、このコードは新しいテキストを
<p>
と
</p>
の間に挿入します(もし
そこに既存のテキストがあった場合はそれを上書きします)。
;(セミコロン):この行のコードがここで終ることを示しています。
チェインを使わない方法
varbody=d3.select("body");
varp=body.append("p");
p.text("新しいパラグラフ!");
のようにすれば分割することができる。
データのバインディング
データ視覚化とは、データをビジュアルにマッピングする(対応付ける)過程のことで
す。データが入力であり、ビジュアルのプロパティ(属性)が出力となります。例えば数
字が大きくなるほど棒を高くしたり、データがあるカテゴリに属する場合に明るい色を用
いたりすることです。マッピングのルールを決めるのは自分自身です。
データの入力値とDOM中の要素とのバインドにD3を用います。バインドとは、データを
特定の要素に結び付けることです。バインドによって、マッピングルールを適用するとき
に元の値が参照できるようになるのです。このバインド処理が無ければ、空っぽの、マッ
ピングもされてないDOM要素の山が意味もなく出来上がるだけです。
データをDOMにバインドするためには、D3の
selection.data()
メソッドを用います
データ
D3は様々な種類のデータの扱いに長けており、実際上、数値配列、文字配列、オブジェク
ト(それ自体がほかの配列、キーと値のペアを含んだもの)配列等、あらゆる種類の配列
を受け取ることができる。JSON(とGeoJSON)の扱いもスマートで、さらにはCSVフ
ァイルを読み込む組込メソッドも備えています。次のようなサンプルデータセットを作っ
てみる。
vardataset=[5,10,15,20,25];
セレクションの作成
サンプルデータセットの数だけtext入りのpタグを生成するコードは次のようになる。
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("新しいパラグラフ!");
このコードを一行ずつ解析するとこのようになる。
d3.select("body"):DOMの中からbodyを見つけ、その参照をチェインの次のステップに渡
します。
.selectAll("p"):DOM要素のすべてのパラグラフ要素を選択します。ここでは該当する要素
が存在しないため、メソッドは空のセレクションを返します。この空のセレクションは、
すぐ後に作られるパラグラフ要素を表したものだと理解してください。
.data(dataset):データの値の個数を数え、解析します。データセットには5つの値が含ま
れているので、ここを通過するすべてのメソッドは、それぞれ値ごとに、合計5回繰り返
されます。
.enter():データにバインドされた要素を新規に生成するためにはenter()が必要です。この
メソッドは最初にDOMを調べ、次に受け渡されたデータを調べます。もし該当するDOM
要素の数よりデータの値の個数が多い場合は、enter()は新規にプレースホルダ(※)要素
を生成し、そのプレースホルダへの参照をチェインの次のステップに渡します。次のステ
ップでは、その参照に対して作業するわけです。(※プレースホルダ:最終的な値が決まる
までの間、仮に確保しておくその値の置き場所)
.append("p"):enter()が生成したプレースホルダセレクションを受け取り、ここで(!)
DOMにp要素を挿入します。そして生成した要素の参照をチェインの次のステップに渡し
ます。
.text("新しいパラグラフ!"):新しく生成されたp要素の参照を受け取り、テキストを代入
します。
さてそれでは、データはどこに行ったのでしょうか?
console.log(d3.selectAll("p"))
で確認してみます。すると、D3がデータを要素にバインドした時、そのデータはDOM中
に記録されるのではなく、メモリ上でその要素のdata属性として記録されていることがわ
かります。
データの使い方
vardataset=[5,10,15,20,25];
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text(function(d){returnd;});
data()メソッドを呼ぶことで、その後にチェインされたメソッドの中で、dを入力値として
受け取れる無名関数が使えるようになる。引数dに対して、現在与えられた要素に対応す
る元のデータセットの値が正しくセットされるように、陰でdata()が働いているのです。
ここで仮引数をdとしていますが、もちろんaでもbでもcでもdataでも、JavaScript
で変数として使える文字列であれば何でも構いません。しかし慣例としてdを用います。
無名関数の書き方
無名関数(あるいはメソッド)の基本的な書き方は次の通りです。
function(input_value){
//なんらかの計算
returnoutput_value;
}
引数(ひきすう)としてinput_valueを受け取り、(通常その引数を使って)なんらかの
計算を行い、その結果を戻り値output_valueとして返します。
無名関数とD3.jsの他のメソッドを組み合わせてみる
.style("color",function(d){
if(d>15){//15が区切り
return"red";
}else{
return"black";
}
});
DIV要素の描画
データを使った描画に取り掛かります。データセットとして
vardataset=[5,10,15,20,25];
棒グラフを作る単純な方法として次のスタイルをもったdiv要素を作ればよい。
div.bar{
display:inline-block;
width:20px;
height:75px;/*この数値は実行時に上書きされます*/
background-color:teal;
}
属性の設定
attr()は、要素のHTML属性とその値を設定するために用います。HTML属性とは、要素
の<>カッコ内に含めることのできる任意のプロパティと値の組み合わせのことです。次の
例を見てください。
<pclass="caption">
<selectid="country">
<imgsrc="logo.png"width="100px"alt="Logo"/>
このHTMLの3つの要素には合計5つの属性(と対応する値)が使われています。いずれ
の属性もattr()を使って設定することができます。
1. class|caption
2. id|country
3. src|logo.png
4. width|100px
5. alt|Logo
目的のdiv要素にbarクラスを設定するには、
.attr("class","bar")
とします。またclassをつける方法として、
.classed("bar",true)
としても同じ設定となります。
さて出来上がった要素に付け足します。
.style("height",function(d){
varbarHeight=d*5;//高さを5倍にします
returnbarHeight+"px";
});
さてここまでのコードを組み合わせると次のようになります。
vardataset=[5,10,15,20,25];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class","bar");
.style("height",function(d){
varbarHeight=d*5;//高さを5倍にします
returnbarHeight+"px";
data()の役割
サンプルのデータセットの個数を増やすと、それに応じて作った棒グラフも増えることが
確認されます。
vardataset=[25,7,5,26,11,8,25,14,23,19,
14,11,22,29,11,13,12,17,18,10,
24,18,25,9,3];
これはdata()は与えられたデータの数だけ正確にループを繰り返します。ループのたびに
チェインされたメソッドを実行し、メソッドが実行されるたびにその操作対象の値も更新
されるからです。
応用:ランダムなデータを使う
ランダムなデータは次のように取ってくることができる。
vardataset=[];//配列の宣言と初期化
for(vari=0;i<25;i++){//ループを25回繰り返す
varnewNumber=Math.random()*30;//0〜30のランダムな数を生成
dataset.push(newNumber);//生成した数を配列に追加
}
各行のコードの内容を説明すると次のようになる。
1. datasetという名前の空の配列を生成。
2. forループの初期化と実行(25回)。
3. ループごとに0から30の間のランダムな数を新規に生成。
4. 生成した数をdataset配列に追加(push()は引数に指定した数値を配列の最後に追加す
る配列メソッド)
この場合は、得られる数値はすべて14.793717765714973のようなdecimal型(浮動小数
点型)になるので、整数値が欲しい場合は、JavaScriptのMath.round()メソッドが使う。
varnewNumber=Math.round(Math.random()*30);
とすればよい。
->後半に続く。
協賛企業募集