90
D3.jsを 使ってみよう 2014/08/28 @muddydixon GTUG Girls Meetup #18

Gtug girls-20140828

Embed Size (px)

DESCRIPTION

d3

Citation preview

Page 1: Gtug girls-20140828

D3.jsを 使ってみよう

2014/08/28 @muddydixon

GTUG Girls Meetup #18

Page 2: Gtug girls-20140828

! muddydixon " muddy.dixon # muddydixon !

Node.js Perl Visualization TimeSeries NeuralNetwork

私 is

Page 3: Gtug girls-20140828

アジェンダD3.jsとは D3.jsの流れ D3.jsのサンプル紹介 D3.js ハンズオン 散布図 棒グラフ 折線グラフ グラフの可視化

Page 4: Gtug girls-20140828

データ可視化とはThe main goal of data visualization is its ability to visualize data, communicating information clearly and effectivelty.

Vitaly Friedman

$

データ可視化の目的は、データを可視化し、情報を明確かつ効率的に伝えることである

$

Page 5: Gtug girls-20140828

今日の資料ですhttps://github.com/muddydixon/GTUGGIRLSTOKYO20140828

Page 6: Gtug girls-20140828

D3.jsとは

Page 7: Gtug girls-20140828

D3.jsとは

Page 8: Gtug girls-20140828
Page 9: Gtug girls-20140828

キラキラ 乙

Page 10: Gtug girls-20140828

D3.jsとはData Driven Documents inline SVG https://developer.mozilla.org/ja/docs/SVG_In_HTML_Introduction 複合ライブラリ SVG 操作 数値処理 可視化ユーティリティ

Page 11: Gtug girls-20140828

D3.jsとは~D-D-D~

[ 53434, 28397, 41334 ]

図形化

Page 12: Gtug girls-20140828

D3.jsとは~D-D-D~

[ 53434, 28397, 41334 ]

[ 1, 0.53, 0.77 ]

正規化

Page 13: Gtug girls-20140828

D3.jsとは~D-D-D~

[ 53434, 28397, 41334 ]

[ 1, 0.53, 0.77 ]

正規化 図形化

Page 14: Gtug girls-20140828

D3.jsとは~D-D-D~

[ 53434, 28397, 41334 ]

[ 1, 0.53, 0.77 ]

正規化 図形化Data Driv

en

Documen

ts

Page 15: Gtug girls-20140828

D3.jsとは~D-D-D~# Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1 5.1 3.5 1.4 0.2 setosa

2 4.9 3.0 1.4 0.2 setosa

3 4.7 3.2 1.3 0.2 setosa

4 4.6 3.1 1.5 0.2 setosa

5 5.0 3.6 1.4 0.2 setosa

51 7.0 3.2 4.7 1.4 versicolor

52 6.4 3.2 4.5 1.5 versicolor

53 6.9 3.1 4.9 1.5 versicolor

54 5.5 2.3 4.0 1.3 versicolor

55 6.5 2.8 4.6 1.5 versicolor

101 6.3 3.3 6.0 2.5 virginica

102 5.8 2.7 5.1 1.9 virginica

103 7.1 3.0 5.9 2.1 virginica

104 6.3 2.9 5.6 1.8 virginica

105 6.5 3.0 5.8 2.2 virginica

Page 16: Gtug girls-20140828

D3.jsとは~D-D-D~# Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1 5.1 3.5 1.4 0.2 setosa

2 4.9 3.0 1.4 0.2 setosa

3 4.7 3.2 1.3 0.2 setosa

4 4.6 3.1 1.5 0.2 setosa

5 5.0 3.6 1.4 0.2 setosa

51 7.0 3.2 4.7 1.4 versicolor

52 6.4 3.2 4.5 1.5 versicolor

53 6.9 3.1 4.9 1.5 versicolor

54 5.5 2.3 4.0 1.3 versicolor

55 6.5 2.8 4.6 1.5 versicolor

101 6.3 3.3 6.0 2.5 virginica

102 5.8 2.7 5.1 1.9 virginica

103 7.1 3.0 5.9 2.1 virginica

104 6.3 2.9 5.6 1.8 virginica

105 6.5 3.0 5.8 2.2 virginica

Page 17: Gtug girls-20140828

D3.jsとは~D-D-D~# Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1 5.1 3.5 1.4 0.2 setosa

2 4.9 3.0 1.4 0.2 setosa

3 4.7 3.2 1.3 0.2 setosa

4 4.6 3.1 1.5 0.2 setosa

5 5.0 3.6 1.4 0.2 setosa

51 7.0 3.2 4.7 1.4 versicolor

52 6.4 3.2 4.5 1.5 versicolor

53 6.9 3.1 4.9 1.5 versicolor

54 5.5 2.3 4.0 1.3 versicolor

55 6.5 2.8 4.6 1.5 versicolor

101 6.3 3.3 6.0 2.5 virginica

102 5.8 2.7 5.1 1.9 virginica

103 7.1 3.0 5.9 2.1 virginica

104 6.3 2.9 5.6 1.8 virginica

105 6.5 3.0 5.8 2.2 virginica

Data Driv

en

Documen

ts

Page 18: Gtug girls-20140828

D3.jsとは~SVG~SVG: Scalable Vector Graphics !

!

!

!

!

HTML5で「inline SVG」が利用可能に! htmlにsvg(xml)を埋め込んで利用可能!

http://www.slideshare.net/kadoppe/inline-svg

Page 19: Gtug girls-20140828

D3.jsとは~SVG~<html> <head>略</head> <body> <svg width=200 height=200> <circle cx=100 cy=100 r=50 fill=red /> </svg> </body> </html>

Page 20: Gtug girls-20140828

D3.jsとは~SVG~<html> <head>略</head> <body> <svg width=200 height=200> <circle cx=100 cy=100 r=50 fill=red /> </svg> </body> </html>

Page 21: Gtug girls-20140828

D3.jsとは~SVG~<html> <head>略</head> <body> <svg width=200 height=200> <circle cx=100 cy=100 r=50 fill=red /> </svg> </body> </html>

inline SV

G

(突然の丸)

Page 22: Gtug girls-20140828

D3.jsとは~SVG~XMLでかける! アニメーションに強い! Inspectorで見られる! 拡大縮小に強い! 反対に WebGL で 3D に! 平面の描画を高速に行える! 面積が決まっていれば一定のパフォーマンス 画像フォーマットで保存できる!

http://dev.opera.com/articles/svg-or-canvas-choose/

Page 23: Gtug girls-20140828

D3.jsの流れ

Page 24: Gtug girls-20140828

D3.jsの流れデータ作る SVGの準備をする DOMとデータを比較する 足りない部分をデータからDOMを生成 attrをいじる

Page 25: Gtug girls-20140828

サンプルで説明

Page 26: Gtug girls-20140828

D3.jsの流れ 0. HTML基本はこれでずっといきます

<!doctype html> <html> <head> <meta charset="utf-8"> <title>D3.js on GTUG Girls Tokyo</title> <style> .axis path, .axis line { fill: none; stroke: grey; } </style> </head> <body> <script type="text/javascript" src="//code.jquery.com/jquery-2.1.1.min.js"></script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script type="text/javascript" src="./src/main.js"></script> </body> </html>

Page 27: Gtug girls-20140828

D3.jsの流れ 0. WebWeb上げておくとAjaxとかも使えて便利です

python -m http.server 5000 python -m SimpleHTTPServer 5000 plackup -MPlack::App::Directory -e 'Plack::App::Directory->new(root => ".")->to_app' ruby -run -e httpd -- --port=5000 . ruby -rwebrick -e 'WEBrick::HTTPServer.new(:Port => 5000, :DocumentRoot => ".").start'

http://blog.kamipo.net/entry/2013/02/20/122225

Page 28: Gtug girls-20140828

D3.jsの流れ 1. データデータを作ります こういうの作っておくと便利

// データ生成ユーティリティ var dataGenerator = function(len, gen){ var array = [], i = 0; for(i = 0; i < len; i++){ array.push(gen ? gen(i) : i); } return array; };

// データ生成 var data = dataGenerator(100, function(i){ return { id: i, name: "name "+ i, x: 0|Math.random() * width, y: 0|Math.random() * height }; });

Page 29: Gtug girls-20140828

D3.jsの流れ 2. SVG土台(svg)作り

// var svg = d3.select("body").append("svg") .attr({width: WIDTH, height: HEIGHT}); var main = svg.append("g") .attr({ width: width, height: height, transform: “translate("+margin+","+margin+")" });

初出 * (selection) d3.select * (selection) selection.append * (selection) selection.attr

Page 30: Gtug girls-20140828

D3.jsの流れ 3. データとDOMの紐付けデータの紐付け

var circle = // 現状の取得 main.selectAll("g.circle") // データのヒモ付 .data(data) // データ > 現状(DOM)の部分を取得 .enter() // "g"要素を追加し、classをセット .append("g").attr({"class": "circle"});

初出 * (selection) selection.selectAll * (selection) selection.data * (selection) selection.enter

Page 31: Gtug girls-20140828

D3.jsの流れ 4. データからドキュメントデータからの要素属性

circle.append("circle").attr({ r: 10, cx: function(d){ return d.x; }, cy: function(d){ return d.y; }, fill: "red" });

Page 32: Gtug girls-20140828
Page 33: Gtug girls-20140828

D3.jsの流れ 5. color色を取得してみよう

var color = d3.scale.category20(); circle.append("circle").attr({ r: 10, cx: function(d){ return d.x; }, cy: function(d){ return d.y; }, fill: function(d, i){ return color(i); } });

初出 * (scale) d3.scale.category20

Page 34: Gtug girls-20140828
Page 35: Gtug girls-20140828

D3.jsの流れデータ作る SVGの準備をする DOMとデータを比較する 足りない部分をデータからDOMを生成 attrをいじる

Page 36: Gtug girls-20140828

Selection

紐付けたデータ既存のDOM

.exit()selection

.enter()

Page 37: Gtug girls-20140828

Selection (例えば)

紐付けたデータ既存のDOM

.exit()selection

.enter()

属性・スタイル・テキストの変更などを行う

新規にDOMを追加し、同時に属性・スタイル・テキストをセットする

既存のDOMを削除したり、透明度を上げたりを行う

Page 38: Gtug girls-20140828

D3.jsで棒グラフ

Page 39: Gtug girls-20140828

棒グラフ新しい話 d3.scale.ordinal scale.rangeBands scale.domain d3.scale.linear scale.range d3.extent / d3.min / d3.max d3.svg.axis selection.call

Page 40: Gtug girls-20140828

棒グラフデータ作成

// データ生成 var data = dataGenerator(10, function(i){ return { id: i, name: "name "+ i, // height よりも大きい! y: 0|Math.random() * 1000 }; });

Page 41: Gtug girls-20140828

棒グラフデータ整理 アクセサを指定することで、配列から柔軟に最大・最小・範囲を取り出せる 他にも平均とか中央値なども可能

// データの調査 var min = d3.min(data, function(d){ return d.y;}), max = d3.max(data, function(d){ return d.y;}), extent = d3.extent(data, function(d){ return d.y;});

アクセサ

初出 * (number) d3.min / d3.max * ([number, number]) d3.extent

Page 42: Gtug girls-20140828

棒グラフスケール作成: 超重要!scaleを制すこと必須

var x = d3.scale.ordinal() .domain(data.map(function(d){ return d.id; })) .rangeBands([0, width], 0.2), y = d3.scale.linear() .domain([0, max]) .range([height, 0]); // [0, height]じゃない!

domain(入力) -> range(出力)の変換 quantitative / ordinalの2種類 quantitativeは「範囲->範囲」 ordinalは「ID->範囲」+ 範囲情報の提供

初出 * (scale) d3.scale.linear / d3.scale.ordinal

Page 43: Gtug girls-20140828

棒グラフscaleのrangeが[0,height]ではなく[height,0]だった理由 ブラウザ上では左上が(0,0) 右に行けば(x,0)、下に行けば(0,y) 大きい値ほど「高い」=「小さい値」 高さのほうを調整=「height - 高さ」

Page 44: Gtug girls-20140828

棒グラフ要素の描画の準備

var bar = // 現状の取得 main.selectAll("g.bar") // データのヒモ付 .data(data) // データ > 現状(DOM)の部分を取得 .enter() // "g"要素を追加し、classをセット .append("g") .attr({ "class": "bar", transform: function(d){ // コツ: 位置合わせをやっておく return “translate("+x(d.id)+","+height+")"; } });

Page 45: Gtug girls-20140828

棒グラフ要素の描画の準備

var bar = // 現状の取得 main.selectAll("g.bar") // データのヒモ付 .data(data) // データ > 現状(DOM)の部分を取得 .enter() // "g"要素を追加し、classをセット .append("g") .attr({ "class": "bar", transform: function(d){ // コツ: 位置合わせをやっておく return “translate("+x(d.id)+","+height+")"; } });

描画上の一番下に合わせる

height

Page 46: Gtug girls-20140828

棒グラフ要素の描画

bar.append("rect").attr({ width: x.rangeBand(), height: function(d){ return height - y(d.y); }, y: function(d){ return y(d.y) - height; }, fill: "red" }); // ラベルも付けておきます bar.append("text").text(function(d){ return d.y;});

Page 47: Gtug girls-20140828
Page 48: Gtug girls-20140828

棒グラフ軸の作成

var xaxis = main.append("g").call(d3.svg.axis().scale(x)).attr({ "class": "axis", transform: "translate(0,"+height+")" }); var yaxis = main.append(“g").call(d3.svg.axis().scale(y).orient("left")) .attr({ "class": "axis" });

初出 * (svg) d3.svg.axis * (selection) selection.call

Page 49: Gtug girls-20140828
Page 50: Gtug girls-20140828

閑話休題 SVG 要素

Page 51: Gtug girls-20140828

SVGで使えるタグsvg g defs, symbol, use path, line, rect, circle ellipse, polyline, polygon !

あとはフィルター周りがたくさんありますがほとんど使う機会はありません

Page 52: Gtug girls-20140828

SVG, GSVG このタグは無いと始まりません!必ず作ります G 子要素をグループ化することができます。 例えば「棒とラベル」の位置を同時に変えるにはG要素の位置を制御すれば一度で行えますし、アニメーションの時も手間が減ります ともにwidth/height/transform属性を取ります

Page 53: Gtug girls-20140828

PATHすべての描画要素(graphics element)はこれのaliasだと考えることができます d属性でデータパス文字列を渡すことで描画させます e.g. M 100 100 L 300 100 L 200 300 z (100,100)から開始(M)し、(300,100)に移動(L)、(200,300)に移動して、閉路を作る(z) fill属性: 閉路の中を指定した色で塗りつぶす stroke属性: パスを指定した色で描く stroke-width属性: パスの線の太さを指定する

Page 54: Gtug girls-20140828

CIRCLE, RECT, LINE, ELLIPSEcircle要素 r属性: 半径を指定 cx/cy属性: 中心のx/y座標を指定

rect要素 width/height属性: 矩形の幅/高さを指定 x/y属性: 矩形の左上の位置を指定 rx/ry属性: 角丸の楕円半径を指定

line要素 x1/x2/y1/y2属性: 短点の座標を指定

ellipse要素 cx/cy属性: 楕円の中心位置の座標を指定 rx/ry属性: 楕円の半径を指定

Page 55: Gtug girls-20140828

Transform属性transform属性には文字列で下記を指定することができます matrix: 変形行列(5要素)を指定 translate: 並行移動 e.g. transform(X,Y) rotate: 回転 e.g. rotate(-90) skewX/skewY: 傾斜(平行四辺形みたいに潰す) e.g. skewX(45) scale: 拡大縮小 e.g. scale(1.5), scale(2,3)

Page 56: Gtug girls-20140828

D3.jsで折線グラフ

Page 57: Gtug girls-20140828

折線グラフ新しい話 d3.time.scale selection.datum d3.svg.line

Page 58: Gtug girls-20140828

データ作成 // データ生成 var data = dataGenerator(10, function(i){ var now = Date.now(); return { id: i, name: "name "+ i, x: new Date(now + 60000 * i), // 一分おき y: 0|Math.random() * 1000 }; });

折線グラフ

Page 59: Gtug girls-20140828

スケール作成 // スケールの生成 var x = d3.time.scale() .domain(d3.extent(data, function(d){ return d.x; })) .range([0, width]), y = d3.scale.linear().domain([0, max]).range([height, 0]);

時間に特化したスケール 自動で時間の区間を調整してくれるため、axisに利用した時に便利(年、四半期、月、日、時、分、など柔軟!)

初出 * (scale) d3.time.scale

折線グラフ

Page 60: Gtug girls-20140828

要素描画ユーティリティ var line = d3.svg.line() .x(function(d){ return x(d.x); }) .y(function(d){ return y(d.y); }); // PATHDATA=line([{x: X, y:Y},{}]) 配列を受けて、PathDataの文字列を返す

類似のsvgとしてarea, arc, diagonalなどがある

初出 * (function) d3.svg.line

折線グラフ

Page 61: Gtug girls-20140828

描画 var serie = // 現状の取得 main.append("path") // データのヒモ付 .datum(data) .attr({ d: line, fill: "none", stroke: color(0) });

初出 * (selection) selection.datum

path要素に対して、配列を紐付ける

折線グラフ

Page 62: Gtug girls-20140828
Page 63: Gtug girls-20140828

データの準備(オブジェクトの配列の配列) // データ生成 var series = dataGenerator(3, function(i){ return { name: "series " + i, data: dataGenerator(10, function(j){ var now = Date.now(); return { id: j, name: "name "+ j, x: new Date(now + 60000 * j), // 一分おき y: 0|Math.random() * 1000 }; }) }; });

複数の折線グラフ

Page 64: Gtug girls-20140828

データの範囲を取得(2回 min/maxを使う) var maxY = d3.max(series, function(serie){ return d3.max(serie.data, function(d){ return d.y;}); }); var minX = d3.min(series, function(serie){ return d3.min(serie.data, function(d){ return d.x;}); }), maxX = d3.max(series, function(serie){ return d3.max(serie.data, function(d){ return d.x;}); });

複数の折線グラフ

Page 65: Gtug girls-20140828

紐付けて描画 var serie = // 現状の取得 main.selectAll("g.serie") // データのヒモ付 .data(series) .enter() .append("g").attr({"class": "serie"}); ! serie.append("path").attr({ d: function(d){ return line(d.data); }, fill: "none", stroke: function(d){ return color(d.name); } });

複数の折線グラフ

Page 66: Gtug girls-20140828
Page 67: Gtug girls-20140828

One more thing各ポイントにドットと数値を

var serie = // 現状の取得 main.selectAll("g.serie") // データのヒモ付 .data(series) .enter() .append("g").attr({ "class": "serie", fill: function(d){ return color(d.name); } });

子要素すべてのfillを指定

Page 68: Gtug girls-20140828

紐付けて描画 var point = serie.selectAll("g.point") .data(function(d){ return d.data;}).enter() .append("g").attr({ "class": "point", transform: function(d){ return "translate("+x(d.x)+","+y(d.y)+")"; } }); point.append("circle").attr({r: 5}); point.append("text").text(function(d){ return d.y; }).attr({dy: -8});

One more thing

Page 69: Gtug girls-20140828
Page 70: Gtug girls-20140828

Animation

Page 71: Gtug girls-20140828

selection.transition()につづいて.attrを指定することで現在->指定したattrへのアニメーションが行われます e.g. d3.select(“circle”).transition().attr({fill: “green”})

Page 72: Gtug girls-20140828

Animation更新処理関数(前半)

var updateLine = function(){ // スケールのドメイン更新 x.domain(d3.extent(data, function(d){ return d.x; })); var max = d3.max(data, function(d){ return d.y;}); y.domain([0, max]); ! // 折線の変形アニメーション serie.transition() .attr({ d: line }); !

これでアニメーションを利用できる!

Page 73: Gtug girls-20140828

Animation更新処理関数(中盤)

// 新たにデータが増えたのでselection撮り直し var point = main.selectAll("g.point").data(data); // データ追加分の処理 var newpoint = point.enter().append(“g") .attr({"class": "point", fill: color(0), transform: function(d){ return "translate("+x(d.x)+","+y(d.y)+")"; } }); newpoint.append("circle").attr({ r: 5 }); newpoint.append("text").text(function(d){return d.y;}).attr({dy:-8}); // 既存データのアニメーション point.transition().attr({ transform: function(d){ return "translate("+x(d.x)+","+y(d.y)+")"; } });

Page 74: Gtug girls-20140828

Animation更新処理関数(後半)

// 軸の更新 xaxis.call(d3.svg.axis().scale(x)); yaxis.call(d3.svg.axis().scale(y).orient("left")); };

Page 75: Gtug girls-20140828
Page 76: Gtug girls-20140828

Layout

Page 77: Gtug girls-20140828

Layoutとは再利用可能なアルゴリズムの塊 基本的には「元データ」から「ある可視化表現に必要なデータ」への変換プログラム +αでアニメーションやイベントなどがついてくる

Page 78: Gtug girls-20140828
Page 79: Gtug girls-20140828

キラキラ 乙

Page 80: Gtug girls-20140828

Layoutシャレオツな可視化を作るには、たくさんの変数が必要です 例えば、関係グラフを作成するには、「どの点とどの点をつなぐか」「点の並びはどうするか」「点の位置座標は」「点を結ぶ弧の曲がり具合はどうするか」など これらの計算を一から実装しないで済むようにするためにLayoutが存在します

Page 81: Gtug girls-20140828

Layout今日は余力がある人(実装に自信がある人はサポートします)

Page 82: Gtug girls-20140828

Hands On

Page 83: Gtug girls-20140828

時間までハンズオンアニメーションまで一度手元で動かしてみてください 試したいことがある人は実装<-アシストします 試したいことない人は相談してください<-アシストします

Page 84: Gtug girls-20140828

気になるデータ

Page 85: Gtug girls-20140828

東京メトロ オープンデータ 活用コンテスト

http://tokyometro10th.jp/future/opendata/

Page 86: Gtug girls-20140828

福井県オープンデータライブラリ

http://www.pref.fukui.lg.jp/doc/toukei-jouhou/opendata/

Page 87: Gtug girls-20140828

その他の資料

Page 88: Gtug girls-20140828

SVGについてはこちらを

http://www.slideshare.net/kadoppe/inline-svghttp://www.slideshare.net/ssuser99dc16/svg-maniaxcss-nite-after-dark7-svgmatsuda

https://github.com/muddydixon/html5conference

Page 89: Gtug girls-20140828

可視化についてはこちらを

Page 90: Gtug girls-20140828

データ可視化のマントラOverview First, Zoom and Filter, Then Details-on-Demand Overview First, Zoom and Filter, Then Details-on-Demand Overview First, Zoom and Filter, Then Details-on-Demand

Ben Shneiderman

$