SlideShare une entreprise Scribd logo
1  sur  26
ウルシステムズ株式会社
http://www.ulsystems.co.jp
mailto:info@ulsystems.co.jp
Tel: 03-6220-1420 Fax: 03-6220-1402
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
D3によるデータビジュアライゼーション
2013/9/13
講師役:近棟 稔
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
はじめに
1
Webブラウザーの進歩は速く、パソコンやスマートフォンやタブレットや電子書籍リーダーに搭載されている多くのモダンなWebブラウ
ザーは、既にインラインSVGをサポートしています。インラインSVGとは、HTML内にSVGタグを埋め込むことにより、その領域内にベ
クター形式の図形を描画することの出来る仕様です。(SVG: Support Vector Graphics)
このインラインSVGが多くのデバイスで利用可能になったことにより、従来のHTML表現の限界は大きく引き上げられました。
一方、データビジュアライゼーション分野が発展・普及してきました。データによっては、単に数値を羅列しても人間が直感的にそ
のデータの傾向を把握することが難しいことがあります。そのため、従来から棒グラフや円グラフ、散布図といった標準的なデータの
表現方法が要所要所で用いられてきています。データビジュアライゼーションの分野では、既存のデータ表現に加えて、様々な表
現方法が考案され、それが実際に用いられるようになって来ています。
そして現在、データビジュアライゼーションとインラインSVGが融合し、Webページ上でインタラクティブに操作可能なデータビジュアラ
イゼーション方式が登場しました。可視化したいデータをJavaScriptで保持し、そのデータをJavaScriptで加工し、それをJavaScri
ptからインラインSVGを用いて描画します。描画されたものをマウスで操作すると、見たい角度からデータを見たり、加工したりする
事が出来るようになります。
このような、HTML上でインタラクティブなデータビジュアライゼーションを行うライブラリーとして有名になったのが、D3(Data-Driven
Documents)です。
この勉強会ではSVGの基礎からはじめ、D3を用いたデータビジュアライゼーション方法の一部をご紹介します。D3を用いたデモンス
トレーションは以下のURLに沢山掲載されていますので、勉強会に参加されない方も、「今ならWebブラウザー上でこんな事が可
能になっている」という事を知ることが出来ると思います。
(キーの←や→でスライドがめくれます)
http://mbostock.github.io/d3/talk/20111018/#3
http://bost.ocks.org/mike/
https://github.com/mbostock/d3/wiki/Gallery
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
インラインSVG入門:Web画面にSVGで点を描く
 インラインSVGを使えば、HTMLを記述するのと同じ要領で画面に点を描画できます。
2
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">svg {border: dashed 1px blue;}</style>
</head>
<body>
<svg width="100" height="100">
<circle cx="50" cy="50" r="10"></circle>
</svg>
</body>
</html>
ここがインラインSVGの部分
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
D3入門:Web画面にD3で点を描く
 D3を用いて点を描いてみると、以下のようになります。D3はSVGにおけるjQueryのような感触です。
3
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">svg {border: dashed 1px blue;}</style>
</head>
<body>
<svg width="100" height="100">
<circle cx="50" cy="50" r="10"></circle>
</svg>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">svg {border: dashed 1px blue;}</style>
</head>
<body>
<script type="text/javascript" src="js/d3.v3.js"></script>
<script type="text/javascript">
d3.select("body")
.append("svg").attr("width", 100).attr("height", 100)
.append("circle").attr("cx", 50).attr("cy", 50).attr("r", 10);
</script>
</body>
</html>
元の姿
D3での書き方
d3.select("body")で
bodyのDOMをつかむ
<svg width="100" height="100">
と同じ。
<circle cx="50" cy="50" r="10">
と同じ。
描画結果はどちらも同じ
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
D3入門:基本のAPIを使ってsinカーブを描画
4
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">svg {border: dashed 1px blue;}</style>
</head>
<body>
<div id="area"></div>
<script type="text/javascript" src="js/d3.v3.js"></script>
<script type="text/javascript">
var svg = d3.select("#area").append("svg").attr("width", 360).attr("height", 100);
for (var deg = 0; deg < 360; deg++) {
svg.append("circle")
.attr("cx", deg)
.attr("cy", 50 - 40 * Math.sin(deg * Math.PI / 180))
.attr("r", 1);
}
</script>
</body>
</html>
 circleを用いてsinカーブを描画してみる事も簡単にできます。
上記ソースの面倒な点:
SVGで簡単に点を描画できるのは良いけれども、描画の原点が左上にあり、数学でよく使う座標系とは異なっていて、
変換が面倒。また、sinカーブの場合はy軸のオフセットや拡大率の計算も面倒。軸の描画も無いのでさみしい。
SVGの
原点
オフセット 拡大率
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
D3入門:基本のAPIを使ってsinカーブを描画その2:スケールの導入
 座標系の変換処理は、D3の「スケール」を使えば楽になります。座標系の種類は、ここで利用して
いるリニアスケール以外にも、対数軸なども利用可能です。
5
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">svg {border: dashed 1px blue;}</style>
</head>
<body>
<div id="area"></div>
<script type="text/javascript" src="js/d3.v3.js"></script>
<script type="text/javascript">
var svg = d3.select("#area").append("svg").attr("width", 360).attr("height", 100),
x = d3.scale.linear().domain([0,360]).range([0,360]),
y = d3.scale.linear().domain([-1,1]).range([90,10]);
for (var deg = 0; deg < 360; deg++) {
svg.append("circle")
.attr("cx", x(deg))
.attr("cy", y(Math.sin(deg * Math.PI / 180)))
.attr("r", 1);
}
</script>
</body>
</html>
domain:
データの取りうる範囲
range:
描画の範囲
→これをリニアに変換してくれる
xやyの関数は、データ値が与えられたら、
描画時の座標を返却するような関数。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
以後、HTMLからCSSとJSを分離します
6
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="sample.css"></link>
</head>
<body>
<div id="d3area"></div>
<script type="text/javascript" src="js/d3.v3.js"></script>
<script type="text/javascript" src="sample.js"></script>
</body>
</html>
svg {border: dashed 1px blue;}
var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100),
x = d3.scale.linear().domain([0,360]).range([0,360]),
y = d3.scale.linear().domain([-1,1]).range([90,10]);
for (var deg = 0; deg < 360; deg++) {
svg.append("circle")
.attr("cx", x(deg))
.attr("cy", y(Math.sin(deg * Math.PI / 180)))
.attr("r", 1);
}
使用するHTML
sample.html
→以降、これに固定
sample.css
sample.js
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
DOMノードにデータを持たせる
 D3の最も特徴的なアーキテクチャは、HTMLのDOMノードに対して __data__ というキー名でデータを保持する
事にあります。これを徐々に説明していきます。まず、今までのsinカーブの各circleにデータを付けてみます。
7
var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100),
x = d3.scale.linear().domain([0,360]).range([0,360]),
y = d3.scale.linear().domain([-1,1]).range([90,10]);
for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする
svg.append("circle")
.attr("class","dot") // circle一つ一つに「dot」クラスを設定
.attr("cx", x(deg))
.attr("cy", y(Math.sin(deg * Math.PI / 180)))
.attr("r", 1);
}
// 上記circleにデータを付与する
var data = d3.range(360); // [0,1,2, ... ,359] つまり、データ側は359度まで
svg.selectAll(".dot").data(data); // これでDOMノードに __data__ が付与される
デ
ー
タ
を
持
た
せ
る
前
デ
ー
タ
を
持
た
せ
た
後
jQueryのように、 selectAll関数を
用いれば様々なセレクション方法で
DOMノードを掴む事ができます。
その掴んだDOMノードに対してデー
タを割り振ることも出来ます。
ちゃんとデータが付いて
います
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
DOMノードに付けたデータを活用する
 データを持たせたセレクション結果に対して、まとめてDOM操作を行うことが出来ます。ここではDOM操作が可視
化出来るようにするためにアニメーション処理を入れ、cosカーブに変更してみます。
8
var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100),
x = d3.scale.linear().domain([0,360]).range([0,360]),
y = d3.scale.linear().domain([-1,1]).range([90,10]);
for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする
svg.append("circle")
.attr("class","dot") // circle一つ一つに「dot」クラスを設定
.attr("cx", x(deg))
.attr("cy", y(Math.sin(deg * Math.PI / 180)))
.attr("r", 1);
}
// 上記circleにデータを付与する
var data = d3.range(360); // [0,1,2, ... ,359] つまり、データ側は359度まで
svg.selectAll(".dot").data(data) // これでDOMノードに __data__ が付与される
.transition() // DOMの書き換えをアニメーションさせる指定。この指定がなければ一瞬で変化する
.delay(function(d){return 10 * d;}) // DOMの書き換えをX座標に依存して遅らせる指定
.duration(function(d){return 500 + 10 * d;}) // アニメーション速度の指定
.style("fill","green").attr("r",2) // CSSスタイルを変更
.attr("cy",function(d){return y(Math.cos(d * Math.PI / 180));}); // cosカーブに変更
attr関数やstyle関数やdelay関数やd
uration関数など、多くのDOM操作を
伴う関数は、引数として実際の値の他
に、関数を渡すことが可能です。
関数の第一引数には __data__ が渡
され、第二引数にはインデックス番号が
渡されます。
このような仕組みとなっているため、D3
ではDOMノードに持たせたデータを
様々な局面で有効活用できます。
ここがD3の強みです。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
既存のDOMノードの数がデータより少ない状況で、新規DOMノードを追加する
(D3のenter関数を理解する)
 DOMのセレクション結果とデータを関連付けた後、データ側が余った場合に、DOMに関連付け出来なかったデー
タを元に新規のDOMノードを追加する操作が可能です。
9
var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100),
x = d3.scale.linear().domain([0,360]).range([0,360]),
y = d3.scale.linear().domain([-1,1]).range([90,10]);
for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする
svg.append("circle").attr("class","dot") // circle一つ一つに「dot」クラスを設定
.attr("cx", x(deg))
.attr("cy", y(Math.sin(deg * Math.PI / 180)))
.attr("r", 1);
}
// 上記circleにデータを付与する
var data = d3.range(360); // [0,1,2, ... ,359] つまり、データ側は359度まで
svg.selectAll(".dot").data(data) // これでDOMノードに __data__ が付与される
.enter() // DOMのセレクション結果よりdata側が多かった場合、そのはみ出した部分の処理に入る
.append("circle").attr("class","dot")
.attr("cx",function(d){return x(d);})
.attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));})
.attr("r",2).style("fill","red");
実はこの部分もenterで処理可能です。
ここがenterによって
追加されました。
svg.selectAll(".dot").data(d3.range(180))
.enter()
.append("circle").attr("class","dot")
.attr("cx",function(d){return x(d);})
.attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));})
.attr("r",1);
書き換えてみると
こうなります。
この方式ではセレクション結果が空っぽの状態から開始します。データをDOMに紐付ける
dataメソッドの処理も、「すべてのデータがDOMとは紐付かない」という結果になります。
enter関数で新規DOMを作成すると、全データに対するDOMノードが作成されます。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
enterの理解を深める その1
 D3でのenterの仕組みは、なかなか理解できないことで有名です。ステップに分けて説明します。
10
svg.selectAll(".dot").data(d3.range(180))
.enter()
.append("circle")
svg.selectAll(".dot").data(d3.range(180))
.enter()
svg.selectAll(".dot").data(d3.range(180))
svg.selectAll(".dot") クラス「dot」が付いているDOMノードをDOMツリーから検索します。
クラス「dot」が付いているDOMノードの一覧と、リスト構造のデータを結合します。
DOMノード一覧 = ◯ ◯ ◯ ◯
データのリスト = ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ←これらを先頭から組にする
DOMに関連づいていないデータの一覧に絞ったデータの配列+D3ロジックが返ります。
DOMノード一覧 = ◯ ◯ ◯ ◯
データのリスト = ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ←DOMに関連づいていないデータ
svg.selectAll(".dot").data(d3.range(180))
.enter()
.append("circle").attr("class","dot")
DOMに関連づいていなかったデータに対してcircleのDOMが生成され、
その配列が返ります。
DOMノード一覧 = ◯ ◯ ◯ ◯ ◯ ◯ ◯ ◯
データのリスト = ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇
この処理の中で、生成したDOMノードに __data__ プロパティを付与してデータを
関連付ける処理も行われます。
circleのDOM配列に対してclassを指定します。典型的にはselectAllのセレクションで
指定したクラスを指定しますが、そうでなくても構いません。
つまり、プログラムの都合で違うものを付与しても構いません。
attr関数の戻り値は、thisです。よって、引続きattr関数やstyle関数やtext関数などを
使ってDOMの属性をセットアップしていくことが出来ます。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
enterの理解を深める その2
 以下の書き方はD3ではよくあるけれども、どうもしっくりこない・・・
 疑問1:何もセレクションされないことが分かっている時にselectAllを真面目に書く必要があるか?
→その必要はないです。
 疑問2:ノードにクラス指定する事が多いけど、D3ではクラス指定は必須なの?
→その必要はないです。単に後々セレクションなどで使えて便利だからやっているだけです
11
svg.selectAll(".dot").data(d3.range(180))
.enter()
.append("circle").attr("class","dot")
.attr("cx",function(d){return x(d);})
.attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));})
.attr("r",1);
svg.selectAll().data(d3.range(180))
.enter()
.append("circle").attr("class","dot")
.attr("cx",function(d){return x(d);})
.attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));})
.attr("r",1);
svg.selectAll().data(d3.range(180))
.enter()
.append("circle")
.attr("cx",function(d){return x(d);})
.attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));})
.attr("r",1);
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
既存のDOMノードの数がデータより多い状況で、既存DOMノードを削除する
(D3のexit関数を理解する)
 既存のDOMのセレクション結果とデータを関連付けた後、既存DOMノード側の数が多く、余った場合に、その余っ
たDOMノードを対象に処理をする事が可能です。
12
var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100),
x = d3.scale.linear().domain([0,360]).range([0,360]),
y = d3.scale.linear().domain([-1,1]).range([90,10]);
for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする
svg.append("circle").attr("class","dot") // circle一つ一つに「dot」クラスを設定
.attr("cx", x(deg)).attr("cy", y(Math.sin(deg * Math.PI / 180))).attr("r", 1);
}
// 上記circleにデータを付与する。DOMノードは余る。
var data = d3.range(90); // [0,1, ... ,89]
svg.selectAll(".dot").data(data).exit()
.transition() // DOMの書き換えをアニメーションさせる指定。この指定がなければ一瞬で変化する
.duration(function(_,i){return 10*i;}) // アニメーション速度の指定
.style("opacity",0)
.remove();
データがアサインされ
なかったDOMノード
が徐々に消えます
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
軸の導入
13
svg {border: dashed 1px blue; font-size: 12px;}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
var data = d3.range(360).map(function(deg){return {x:deg,y:Math.sin(deg * Math.PI / 180)};});
var margin = {top: 15, right: 10, bottom: 25, left: 40},
width = 500 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom,
x = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.x;}))).range([0,width]),
y = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.y;}))).range([height,0]),
g = d3.select("#d3area").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
g.append("g").attr("class", "y axis")
.call(d3.svg.axis().scale(y).orient("left"));
g.selectAll(".dot").data(data).enter()
.append("circle").attr("class","dot")
.attr("cx", function(d){return x(d.x);})
.attr("cy", function(d){return y(d.y);}).attr("r", 1);
SVGのtransformの指定をすると、
座標系をずらす事が可能です
軸の描画に関しては、D3がそのような図形描画処
理を提供してくれています
d3.extentを利用すると、データの最小値と最大
値が算出可能です。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
おまけ:sinカーブをcosカーブに「にゅーっ」と変形
14
var data = d3.range(360).map(function(deg){return {x:deg,y:Math.sin(deg * Math.PI / 180)};});
var margin = {top: 15, right: 10, bottom: 25, left: 40},
width = 500 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom,
x = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.x;}))).range([0,width]),
y = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.y;}))).range([height,0]),
g = d3.select("#d3area").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
g.append("g").attr("class", "y axis")
.call(d3.svg.axis().scale(y).orient("left"));
g.selectAll(".dot").data(data).enter()
.append("circle").attr("class","dot")
.attr("cx", function(d){return x(d.x);})
.attr("cy", function(d){return y(d.y);}).attr("r", 1);
var newData = d3.range(360).map(function(deg){return {x:deg,y:Math.cos(deg * Math.PI / 180)};});
g.selectAll(".dot").data(newData)
.transition()
.duration(function(d){return 500+x(d.x);})
.delay(function(d){return 10*x(d.x);})
.attr("cy", function(d){return y(d.y);});
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
イベント処理
 D3はjQueryと同じようにon関数によって各種イベントを扱うことが出来るようになっています。
ここではclickイベントを拾って円の形を変える例を示します。
15
var svg = d3.select("#d3area").append("svg").attr("width",100).attr("height",100);
svg.append("circle").attr("cx",50).attr("cy",50).attr("r",10)
.on("click",function(){
svg.selectAll("circle")
.transition().duration(300).attr("r",50)
.transition().duration(300).attr("r",10)
.transition().duration(300).attr("cx",80)
.transition().duration(300).attr("cx",20)
.transition().duration(900).attr("cx",50);
});
書き方はjQueryと同じ
ちなみに・・・
D3はDOMノードの処理やイベント処理を記述可能
ですので、jQueryの代替として使う人も増えてきてい
ます。jQueryと役割が重なる部分が多いのです。
ちなみにD3はSVGに特化したものではなく、実はHT
MLのDOMノードやイベント全般が扱えます。
クリック
色々動く
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
イベント処理 その2
 イベントの処理例として、もう一つ、mousemoveイベントを拾って輪を描画するサンプルを紹介します。
16
var color = d3.scale.category20c(),
i = 0;
var svg = d3.select("#d3area")
.append("svg").attr("width",640).attr("height",480)
.style("pointer-events", "all")
.on("mousemove", function(){
svg.append("circle")
.attr("cx", d3.event.x).attr("cy", d3.event.y).attr("r", 1e-6)
.style("fill","none").style("stroke", color(i++)).style("stroke-opacity", 1)
.transition()
.duration(5000)
.ease(Math.sqrt)
.attr("r", 100)
.style("stroke-opacity", 1e-6)
.remove();
});
書き方はjQueryと同じ
[処理内容]
マウスポインタが動く際に発生するイベントに反応して動きます。
circleを作って、色はd3.scale.category20cという色生成関数で
生成した色を指定しています。
transition指定をして徐々に半径が広がるように、また、不透明
度(opacity)が下がるように、つまり透明になっていくように指定し 、
最後に透明になった後、DOMノードも消えるように指定しています。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
散布図
 散布図の実現は簡単です。単純に軸を描画し、circleで点を描くだけです。
17
var data = [[3,5],
[7,2],
[1,10],
[9,12],
[5,13]];
var margin = {top: 15, right: 10, bottom: 25, left: 40},
width = 500 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom,
x = d3.scale.linear().domain(d3.extent(data,function(d){return d[0];})).range([0,width]),
y = d3.scale.linear().domain(d3.extent(data,function(d){return d[1];})).range([height,0]),
g = d3.select("#d3area").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
g.append("g").attr("class", "y axis").call(d3.svg.axis().scale(y).orient("left"));
g.selectAll().data(data).enter()
.append("circle")
.attr("cx",function(d){return x(d[0]);})
.attr("cy",function(d){return y(d[1]);}).attr("r",5);
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
散布図で見るD3(およびJavaScript)のパフォーマンス
 100,000個(10万個)のデータを散布図でプロットしました。HTMLの描画部分も含めて、全体で約2秒でプロット
可能でした。なお、現在関わっているプロジェクトでは約10万件のデータをJavaScriptのメモリー上に保持し、さま
ざまな処理をしていますが、やはり問題にはなっていません。なお、100万件程度になると、インタラクティブな操
作が出来なくなるほど遅くなると思われます。
18
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
円グラフ
 以下に円グラフの例を示します。
19
var data = [["A",4],
["B",3],
["C",2],
["D",1]];
var width = 400,height = 400,radius = 200,
arc = d3.svg.arc().innerRadius(0.3*radius).outerRadius(0.9*radius);
var c = d3.scale.category20c();
var g = d3.select("#d3area").append("svg").attr("width",width).attr("height",height)
.append("g").attr("transform","translate(" + width / 2 + "," + height / 2 + ")")
.selectAll().data(d3.layout.pie().sort(null).value(function(d){return d[1];})(data))
.enter().append("g").attr("class","arc");
g.append("path").style("fill",function(_,i){return c(i);}).style("stroke","black").attr("d",arc);
g.append("text")
.attr("transform",function(d){return "translate(" + arc.centroid(d) + ")"; })
.attr("dy","0.35em").style("text-anchor","middle").style("font-size","30px")
.text(function(d){return d.data[0];});
ここが円グラフの弧の部分の形を生
成するコア部分
ここは円グラフ用のデータを作るため
に必要な部分。ここも重要。
<sunburst>
円グラフのプリミティブである円弧を組合せていくと、
sunburstというモダンな表現も可能になります。
プリミティブの円弧
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
Chord diagram に挑戦
 以降のスライドでChord diagramを扱ってみます。通常目にする散布図、折れ線グラフ、棒グラフ、
円グラフなどとは違うものです。見た目は以下の様なものです。
20
このような円弧は円グラフ(パイチャート)で使った
円弧の表現を応用します。ラベル部分も円グラフと
同じです。オフセットが異なるだけです。
Chord diagram 特有のこの円弧は、D3が提供す
る d3.svg.chord() で描画可能なものになります。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
Chord diagram: bigramをChord diagramで表現してみます
 Chord diagramは、相互に数値的な関係のあるノード間の強さを表現します。なかなか具体例がな
いと説明出来ないため、ここではbigramを例に用いて説明します。
 bigram(バイグラム)とは
 英単語の「the」を用いて説明します。theはtの後にhが来て、hの後にeが来ます。こうなる確率は以下の通
りです。このような、英文字間の遷移確率データをbigramと呼びます。
 英語でtの後にhの来る確率=33%
 英語でhの後にeの来る確率=52%
 bigramのデータを表形式で表現することも出来ます。たとえば以下のようなものになります。
 bigramを3次元グラフで描画することも可能です。(下記はExcelで描画したもの)
21
t h e
33% 52%
aが来る bが来る cが来る dが来る eが来る ・・・
aのあとに 20 3279 4961 5105 65
bのあとに 1754 164 112 13 6150
cのあとに 8507 8 865 50 5204
dのあとに 3254 133 129 1304 13219
・・・
← 数字は、ある英文テキストにおける
出現回数
← 横軸は「aのあとに」などの最初の文字
奥行き方向の軸は「bが来る」などの次の文字
棒の高さは、そのようなパターンの出現回数
この中で飛び抜けて高い棒は「th」のパターン。
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
Chord diagram: bigramはネットワーク構造をしたデータ
 bigramは、「エッジに数値の付いた有向サイクリックグラフ」です。ここで言うグラフは、ネットワーク
構造の事です。bigramを素直にノードとエッジを用いたグラフ構造として表現すると以下のようにな
ります。なお、すべてのノードについて記述するとクモの巣状になってしまうので、4文字のみ取り上
げました。
22
t h e
51626 34984
21256
3004 312
13969
i
186341
1233
6159
00
数字は、あるドキュメントでそのような遷移が出現した回数。
本当にaからzまでのすべての単語について記述するとなると、
1つのノードからaからzまでの26ノードへの関連が発生する。
本当に描画してしまうとグチャグチャに・・・ → そこでChord diagram!
3177
2
71
3893
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
Chord diagram: D3を用いてbigramをChord diagramで表現する
 以下はD3を用いてbigramをChord diagramで表現してみたものです。
23
たとえば 「t」 のノードにフォーカスすると、アルファベット「t」の
次に来やすいアルファベットに対して線が引かれます。
ノード「t」に接続している側の線の太さは、遷移のしやすさを
意味します。たとえば「t」の次は「h」が来やすいため太い線と
して表現されています。
逆に「h」のノードから「t」のノードに行く事を考えると、「h」の
側は細く描画されていることが分かります。そのため「ht」のような
並びは英語ではレアであることが分かります。
太い
細い
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
Chord diagram のソースコード
24
var width = 500, height = 500,
innerRadius = 0.35 * width,
outerRadius = 1.2 * innerRadius;
var color = d3.scale.category20();
// 座標の原点をSVGのエリアの中心に
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height)
.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// chord用データを生成
var chord = d3.layout.chord().padding(.05).sortSubgroups(d3.descending).matrix(matrix);
// chord特有の弧の部分を描画
svg.selectAll().data(chord.chords).enter()
.append("path").attr('class','chord-path')
.attr("d", d3.svg.chord().radius(innerRadius))
.style("fill",function(d){return color(d.target.index);})
.style('stroke',function(d){return color(d.target.index);})
.style('stroke-width','1').style("opacity", 0.8).style("stroke-opacity",1);
// 周囲の円弧の土台を作成してデータを投入
var g = svg.selectAll().data(chord.groups).enter().append("g").attr('class','chord');
// 周囲の円弧を描画
g.append("path").style("fill", function(d){return color(d.index);})
.style("stroke", function(d){return color(d.index);})
.attr("d", d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius))
.on("mouseover", fade(0.1,0.1))
.on("mouseout", fade(0.8,1));
function fade(opacity,s_opacity) {
return function(g, i) {
svg.selectAll(".chord-path")
.filter(function(d) { return d.source.index != i && d.target.index != i; })
.transition().style("opacity",opacity).style("stroke-opacity",s_opacity);
};
}
// 周囲のテキストを描画
g.append("text")
.attr("dy","0.35em").style("text-anchor","middle").style("font-size","14px")
.text(function(d,i){return String.fromCharCode('a'.charCodeAt()+i);})
.attr("transform",function(d){
return "translate(" + d3.svg.arc().innerRadius(outerRadius)
.outerRadius(1.15*outerRadius).centroid(d) + ")";
});
ULS Copyright © 2013 UL Systems, Inc. All rights reserved.
他にも色々・・・。data visualization の世界は研究分野の1つなので本当に沢山のア
イディアがあるようです。 D3を使えば、その新しいアイディアをより楽に実装できます。
25
http://bl.ocks.org/mbostock/4063269 http://bl.ocks.org/mbostock/raw/1044242/ http://bl.ocks.org/mbostock/4063570
http://bl.ocks.org/mbostock/1062288 http://bl.ocks.org/mbostock/950642 http://bl.ocks.org/mbostock/4063582 http://bl.ocks.org/mbostock/4060366
http://bl.ocks.org/mbostock/4063530
[データビジュアライゼーションのセオリー:人は可視化されたデータをどう見るか]
 人は、オブジェクトの面積に敏感です。データのスカラー値を面積に比例させると、人はデータ間の相対的な比較を感覚的に行えます。古典
的にはこのような人の性質を用いて円グラフや棒グラフを作っていました。
 人は、色をある程度認識できます。しかし、色の認識は面積ほどではありません。人に傾向を読み取らせるために有向に使える場合がありま
す。たとえばヒートマップは色の使い方の有名な例です。
 人は連続的な変化を好みます。そのため、似たデータは近くに配置するなどの工夫が有効な場合があります。また、アニメーションも連続的
な変化の一種なので、アニメーションもデータを理解させるツールとして使うと効果的なことがあります。

Contenu connexe

En vedette

省メモリーに関するデザインパターン 2011.04.18
省メモリーに関するデザインパターン 2011.04.18省メモリーに関するデザインパターン 2011.04.18
省メモリーに関するデザインパターン 2011.04.18Minoru Chikamune
 
AspectJによるJava言語拡張 2012.09.07
AspectJによるJava言語拡張 2012.09.07AspectJによるJava言語拡張 2012.09.07
AspectJによるJava言語拡張 2012.09.07Minoru Chikamune
 
「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23Minoru Chikamune
 
「グーグルの自動運転Carの技術要素」勉強会 2014.08.29
「グーグルの自動運転Carの技術要素」勉強会 2014.08.29「グーグルの自動運転Carの技術要素」勉強会 2014.08.29
「グーグルの自動運転Carの技術要素」勉強会 2014.08.29Minoru Chikamune
 
Stormとその周辺 2013.03.15
Stormとその周辺 2013.03.15Stormとその周辺 2013.03.15
Stormとその周辺 2013.03.15Minoru Chikamune
 
有名論文から学ぶディープラーニング 2016.03.25
有名論文から学ぶディープラーニング 2016.03.25有名論文から学ぶディープラーニング 2016.03.25
有名論文から学ぶディープラーニング 2016.03.25Minoru Chikamune
 
「機械学習 By スタンフォード大学」勉強会 2015.09.11
「機械学習 By スタンフォード大学」勉強会 2015.09.11「機械学習 By スタンフォード大学」勉強会 2015.09.11
「機械学習 By スタンフォード大学」勉強会 2015.09.11Minoru Chikamune
 
「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04Minoru Chikamune
 
D3.js と SVG によるデータビジュアライゼーション
D3.js と SVG によるデータビジュアライゼーションD3.js と SVG によるデータビジュアライゼーション
D3.js と SVG によるデータビジュアライゼーションKohei Kadowaki
 
D3.jsを使った情報可視化
D3.jsを使った情報可視化D3.jsを使った情報可視化
D3.jsを使った情報可視化KatsuyaENDOH
 
AWSクラウドデザインパターン(CDP) - 概要編 -
AWSクラウドデザインパターン(CDP) - 概要編 - AWSクラウドデザインパターン(CDP) - 概要編 -
AWSクラウドデザインパターン(CDP) - 概要編 - SORACOM, INC
 
Awsのインフラをデザインパターン駆使して設計構築
Awsのインフラをデザインパターン駆使して設計構築Awsのインフラをデザインパターン駆使して設計構築
Awsのインフラをデザインパターン駆使して設計構築Monstar Lab Inc.
 
データをどうやって見せるか?
データをどうやって見せるか?データをどうやって見せるか?
データをどうやって見せるか?E2D3.org
 
Nettet som en del av mediemiksen - Google Think 2014 - Espen Grimmert
Nettet som en del av mediemiksen - Google Think 2014  - Espen GrimmertNettet som en del av mediemiksen - Google Think 2014  - Espen Grimmert
Nettet som en del av mediemiksen - Google Think 2014 - Espen GrimmertEspen Grimmert
 
Η αγαπημένη μου πόλη
Η αγαπημένη μου πόληΗ αγαπημένη μου πόλη
Η αγαπημένη μου πόληdroula_
 

En vedette (20)

省メモリーに関するデザインパターン 2011.04.18
省メモリーに関するデザインパターン 2011.04.18省メモリーに関するデザインパターン 2011.04.18
省メモリーに関するデザインパターン 2011.04.18
 
AspectJによるJava言語拡張 2012.09.07
AspectJによるJava言語拡張 2012.09.07AspectJによるJava言語拡張 2012.09.07
AspectJによるJava言語拡張 2012.09.07
 
「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23「Googleを支える技術」の解説 2010.08.23
「Googleを支える技術」の解説 2010.08.23
 
「グーグルの自動運転Carの技術要素」勉強会 2014.08.29
「グーグルの自動運転Carの技術要素」勉強会 2014.08.29「グーグルの自動運転Carの技術要素」勉強会 2014.08.29
「グーグルの自動運転Carの技術要素」勉強会 2014.08.29
 
Stormとその周辺 2013.03.15
Stormとその周辺 2013.03.15Stormとその周辺 2013.03.15
Stormとその周辺 2013.03.15
 
有名論文から学ぶディープラーニング 2016.03.25
有名論文から学ぶディープラーニング 2016.03.25有名論文から学ぶディープラーニング 2016.03.25
有名論文から学ぶディープラーニング 2016.03.25
 
「機械学習 By スタンフォード大学」勉強会 2015.09.11
「機械学習 By スタンフォード大学」勉強会 2015.09.11「機械学習 By スタンフォード大学」勉強会 2015.09.11
「機械学習 By スタンフォード大学」勉強会 2015.09.11
 
「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04
 
D3.js と SVG によるデータビジュアライゼーション
D3.js と SVG によるデータビジュアライゼーションD3.js と SVG によるデータビジュアライゼーション
D3.js と SVG によるデータビジュアライゼーション
 
AWS IoT アップデート 2016.02.16
AWS IoT アップデート 2016.02.16AWS IoT アップデート 2016.02.16
AWS IoT アップデート 2016.02.16
 
D3.jsを使った情報可視化
D3.jsを使った情報可視化D3.jsを使った情報可視化
D3.jsを使った情報可視化
 
AWSクラウドデザインパターン(CDP) - 概要編 -
AWSクラウドデザインパターン(CDP) - 概要編 - AWSクラウドデザインパターン(CDP) - 概要編 -
AWSクラウドデザインパターン(CDP) - 概要編 -
 
AWS IoTアーキテクチャパターン
AWS IoTアーキテクチャパターンAWS IoTアーキテクチャパターン
AWS IoTアーキテクチャパターン
 
Awsのインフラをデザインパターン駆使して設計構築
Awsのインフラをデザインパターン駆使して設計構築Awsのインフラをデザインパターン駆使して設計構築
Awsのインフラをデザインパターン駆使して設計構築
 
データをどうやって見せるか?
データをどうやって見せるか?データをどうやって見せるか?
データをどうやって見せるか?
 
Nettet som en del av mediemiksen - Google Think 2014 - Espen Grimmert
Nettet som en del av mediemiksen - Google Think 2014  - Espen GrimmertNettet som en del av mediemiksen - Google Think 2014  - Espen Grimmert
Nettet som en del av mediemiksen - Google Think 2014 - Espen Grimmert
 
I16092.00_E501-E501
I16092.00_E501-E501I16092.00_E501-E501
I16092.00_E501-E501
 
Η αγαπημένη μου πόλη
Η αγαπημένη μου πόληΗ αγαπημένη μου πόλη
Η αγαπημένη μου πόλη
 
WONDERFUL
WONDERFULWONDERFUL
WONDERFUL
 
portfolio_tmajasaari
portfolio_tmajasaariportfolio_tmajasaari
portfolio_tmajasaari
 

Similaire à D3によるデータビジュアライゼーション 2013.09.13

D3.js で LOD を Visualization
D3.js で LOD を VisualizationD3.js で LOD を Visualization
D3.js で LOD を Visualizationdsuke Takaoka
 
第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要
第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要 第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要
第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要 Daiyu Hatakeyama
 
SVG MANIAX - CSS Nite After dark7
SVG MANIAX - CSS Nite After dark7SVG MANIAX - CSS Nite After dark7
SVG MANIAX - CSS Nite After dark7Naoki Matsuda
 
W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告
W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告
W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告Satoru Takagi
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略takezoe
 
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送Google Cloud Platform - Japan
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013Ryo Sakamoto
 
クラウド・アプリケーション・モデリングへのアプローチ
クラウド・アプリケーション・モデリングへのアプローチクラウド・アプリケーション・モデリングへのアプローチ
クラウド・アプリケーション・モデリングへのアプローチTomoharu ASAMI
 
SVG MANIAX Ver.2 - Mars vanilla
SVG MANIAX Ver.2 -  Mars vanillaSVG MANIAX Ver.2 -  Mars vanilla
SVG MANIAX Ver.2 - Mars vanillaNaoki Matsuda
 
HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)
HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)
HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)Hadoop / Spark Conference Japan
 
D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料充彦 保田
 
Webデザイン 第10回:HTML5実践 Three.jsで3Dプログラミング
Webデザイン 第10回:HTML5実践 Three.jsで3DプログラミングWebデザイン 第10回:HTML5実践 Three.jsで3Dプログラミング
Webデザイン 第10回:HTML5実践 Three.jsで3DプログラミングAtsushi Tadokoro
 
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。Masayuki Ozawa
 
Gpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure ai
Gpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure aiGpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure ai
Gpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure aiShotaro Suzuki
 
【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)
【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)
【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)日本マイクロソフト株式会社
 
「html5 boilerplate」から考える、これからのマークアップ
「html5 boilerplate」から考える、これからのマークアップ「html5 boilerplate」から考える、これからのマークアップ
「html5 boilerplate」から考える、これからのマークアップYasuhito Yabe
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Fixstars Corporation
 

Similaire à D3によるデータビジュアライゼーション 2013.09.13 (20)

D3.js で LOD を Visualization
D3.js で LOD を VisualizationD3.js で LOD を Visualization
D3.js で LOD を Visualization
 
第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要
第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要 第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要
第29回 SQL Server 勉強会 (JSSUG) - Azure Synapse Analytics 概要
 
Aaなゲームをjsで
AaなゲームをjsでAaなゲームをjsで
Aaなゲームをjsで
 
SVG MANIAX - CSS Nite After dark7
SVG MANIAX - CSS Nite After dark7SVG MANIAX - CSS Nite After dark7
SVG MANIAX - CSS Nite After dark7
 
W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告
W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告
W3C日本会員会議 2013 12/17 TPAC2013 SVGWG活動報告
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
Google Cloud Dataflow を理解する - #bq_sushi
Google Cloud Dataflow を理解する - #bq_sushiGoogle Cloud Dataflow を理解する - #bq_sushi
Google Cloud Dataflow を理解する - #bq_sushi
 
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
 
クラウド・アプリケーション・モデリングへのアプローチ
クラウド・アプリケーション・モデリングへのアプローチクラウド・アプリケーション・モデリングへのアプローチ
クラウド・アプリケーション・モデリングへのアプローチ
 
SVG MANIAX Ver.2 - Mars vanilla
SVG MANIAX Ver.2 -  Mars vanillaSVG MANIAX Ver.2 -  Mars vanilla
SVG MANIAX Ver.2 - Mars vanilla
 
HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)
HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)
HadoopとRDBMSをシームレスに連携させるSmart SQL Processing (Hadoop Conference Japan 2014)
 
D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料
 
Webデザイン 第10回:HTML5実践 Three.jsで3Dプログラミング
Webデザイン 第10回:HTML5実践 Three.jsで3DプログラミングWebデザイン 第10回:HTML5実践 Three.jsで3Dプログラミング
Webデザイン 第10回:HTML5実践 Three.jsで3Dプログラミング
 
Tamabi media131118
Tamabi media131118Tamabi media131118
Tamabi media131118
 
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
 
Gpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure ai
Gpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure aiGpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure ai
Gpu accelerates aimodeldevelopmentandanalyticsutilizingelasticsearchandazure ai
 
【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)
【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)
【de:code 2020】 Azure Synapse Analytics 技術編 ~ 最新の統合分析プラットフォームによる新しい価値の創出(後編)
 
「html5 boilerplate」から考える、これからのマークアップ
「html5 boilerplate」から考える、これからのマークアップ「html5 boilerplate」から考える、これからのマークアップ
「html5 boilerplate」から考える、これからのマークアップ
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門
 

D3によるデータビジュアライゼーション 2013.09.13

  • 1. ウルシステムズ株式会社 http://www.ulsystems.co.jp mailto:info@ulsystems.co.jp Tel: 03-6220-1420 Fax: 03-6220-1402 ULS Copyright © 2013 UL Systems, Inc. All rights reserved. D3によるデータビジュアライゼーション 2013/9/13 講師役:近棟 稔
  • 2. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. はじめに 1 Webブラウザーの進歩は速く、パソコンやスマートフォンやタブレットや電子書籍リーダーに搭載されている多くのモダンなWebブラウ ザーは、既にインラインSVGをサポートしています。インラインSVGとは、HTML内にSVGタグを埋め込むことにより、その領域内にベ クター形式の図形を描画することの出来る仕様です。(SVG: Support Vector Graphics) このインラインSVGが多くのデバイスで利用可能になったことにより、従来のHTML表現の限界は大きく引き上げられました。 一方、データビジュアライゼーション分野が発展・普及してきました。データによっては、単に数値を羅列しても人間が直感的にそ のデータの傾向を把握することが難しいことがあります。そのため、従来から棒グラフや円グラフ、散布図といった標準的なデータの 表現方法が要所要所で用いられてきています。データビジュアライゼーションの分野では、既存のデータ表現に加えて、様々な表 現方法が考案され、それが実際に用いられるようになって来ています。 そして現在、データビジュアライゼーションとインラインSVGが融合し、Webページ上でインタラクティブに操作可能なデータビジュアラ イゼーション方式が登場しました。可視化したいデータをJavaScriptで保持し、そのデータをJavaScriptで加工し、それをJavaScri ptからインラインSVGを用いて描画します。描画されたものをマウスで操作すると、見たい角度からデータを見たり、加工したりする 事が出来るようになります。 このような、HTML上でインタラクティブなデータビジュアライゼーションを行うライブラリーとして有名になったのが、D3(Data-Driven Documents)です。 この勉強会ではSVGの基礎からはじめ、D3を用いたデータビジュアライゼーション方法の一部をご紹介します。D3を用いたデモンス トレーションは以下のURLに沢山掲載されていますので、勉強会に参加されない方も、「今ならWebブラウザー上でこんな事が可 能になっている」という事を知ることが出来ると思います。 (キーの←や→でスライドがめくれます) http://mbostock.github.io/d3/talk/20111018/#3 http://bost.ocks.org/mike/ https://github.com/mbostock/d3/wiki/Gallery
  • 3. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. インラインSVG入門:Web画面にSVGで点を描く  インラインSVGを使えば、HTMLを記述するのと同じ要領で画面に点を描画できます。 2 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css">svg {border: dashed 1px blue;}</style> </head> <body> <svg width="100" height="100"> <circle cx="50" cy="50" r="10"></circle> </svg> </body> </html> ここがインラインSVGの部分
  • 4. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. D3入門:Web画面にD3で点を描く  D3を用いて点を描いてみると、以下のようになります。D3はSVGにおけるjQueryのような感触です。 3 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css">svg {border: dashed 1px blue;}</style> </head> <body> <svg width="100" height="100"> <circle cx="50" cy="50" r="10"></circle> </svg> </body> </html> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css">svg {border: dashed 1px blue;}</style> </head> <body> <script type="text/javascript" src="js/d3.v3.js"></script> <script type="text/javascript"> d3.select("body") .append("svg").attr("width", 100).attr("height", 100) .append("circle").attr("cx", 50).attr("cy", 50).attr("r", 10); </script> </body> </html> 元の姿 D3での書き方 d3.select("body")で bodyのDOMをつかむ <svg width="100" height="100"> と同じ。 <circle cx="50" cy="50" r="10"> と同じ。 描画結果はどちらも同じ
  • 5. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. D3入門:基本のAPIを使ってsinカーブを描画 4 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css">svg {border: dashed 1px blue;}</style> </head> <body> <div id="area"></div> <script type="text/javascript" src="js/d3.v3.js"></script> <script type="text/javascript"> var svg = d3.select("#area").append("svg").attr("width", 360).attr("height", 100); for (var deg = 0; deg < 360; deg++) { svg.append("circle") .attr("cx", deg) .attr("cy", 50 - 40 * Math.sin(deg * Math.PI / 180)) .attr("r", 1); } </script> </body> </html>  circleを用いてsinカーブを描画してみる事も簡単にできます。 上記ソースの面倒な点: SVGで簡単に点を描画できるのは良いけれども、描画の原点が左上にあり、数学でよく使う座標系とは異なっていて、 変換が面倒。また、sinカーブの場合はy軸のオフセットや拡大率の計算も面倒。軸の描画も無いのでさみしい。 SVGの 原点 オフセット 拡大率
  • 6. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. D3入門:基本のAPIを使ってsinカーブを描画その2:スケールの導入  座標系の変換処理は、D3の「スケール」を使えば楽になります。座標系の種類は、ここで利用して いるリニアスケール以外にも、対数軸なども利用可能です。 5 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css">svg {border: dashed 1px blue;}</style> </head> <body> <div id="area"></div> <script type="text/javascript" src="js/d3.v3.js"></script> <script type="text/javascript"> var svg = d3.select("#area").append("svg").attr("width", 360).attr("height", 100), x = d3.scale.linear().domain([0,360]).range([0,360]), y = d3.scale.linear().domain([-1,1]).range([90,10]); for (var deg = 0; deg < 360; deg++) { svg.append("circle") .attr("cx", x(deg)) .attr("cy", y(Math.sin(deg * Math.PI / 180))) .attr("r", 1); } </script> </body> </html> domain: データの取りうる範囲 range: 描画の範囲 →これをリニアに変換してくれる xやyの関数は、データ値が与えられたら、 描画時の座標を返却するような関数。
  • 7. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 以後、HTMLからCSSとJSを分離します 6 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="sample.css"></link> </head> <body> <div id="d3area"></div> <script type="text/javascript" src="js/d3.v3.js"></script> <script type="text/javascript" src="sample.js"></script> </body> </html> svg {border: dashed 1px blue;} var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100), x = d3.scale.linear().domain([0,360]).range([0,360]), y = d3.scale.linear().domain([-1,1]).range([90,10]); for (var deg = 0; deg < 360; deg++) { svg.append("circle") .attr("cx", x(deg)) .attr("cy", y(Math.sin(deg * Math.PI / 180))) .attr("r", 1); } 使用するHTML sample.html →以降、これに固定 sample.css sample.js
  • 8. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. DOMノードにデータを持たせる  D3の最も特徴的なアーキテクチャは、HTMLのDOMノードに対して __data__ というキー名でデータを保持する 事にあります。これを徐々に説明していきます。まず、今までのsinカーブの各circleにデータを付けてみます。 7 var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100), x = d3.scale.linear().domain([0,360]).range([0,360]), y = d3.scale.linear().domain([-1,1]).range([90,10]); for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする svg.append("circle") .attr("class","dot") // circle一つ一つに「dot」クラスを設定 .attr("cx", x(deg)) .attr("cy", y(Math.sin(deg * Math.PI / 180))) .attr("r", 1); } // 上記circleにデータを付与する var data = d3.range(360); // [0,1,2, ... ,359] つまり、データ側は359度まで svg.selectAll(".dot").data(data); // これでDOMノードに __data__ が付与される デ ー タ を 持 た せ る 前 デ ー タ を 持 た せ た 後 jQueryのように、 selectAll関数を 用いれば様々なセレクション方法で DOMノードを掴む事ができます。 その掴んだDOMノードに対してデー タを割り振ることも出来ます。 ちゃんとデータが付いて います
  • 9. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. DOMノードに付けたデータを活用する  データを持たせたセレクション結果に対して、まとめてDOM操作を行うことが出来ます。ここではDOM操作が可視 化出来るようにするためにアニメーション処理を入れ、cosカーブに変更してみます。 8 var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100), x = d3.scale.linear().domain([0,360]).range([0,360]), y = d3.scale.linear().domain([-1,1]).range([90,10]); for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする svg.append("circle") .attr("class","dot") // circle一つ一つに「dot」クラスを設定 .attr("cx", x(deg)) .attr("cy", y(Math.sin(deg * Math.PI / 180))) .attr("r", 1); } // 上記circleにデータを付与する var data = d3.range(360); // [0,1,2, ... ,359] つまり、データ側は359度まで svg.selectAll(".dot").data(data) // これでDOMノードに __data__ が付与される .transition() // DOMの書き換えをアニメーションさせる指定。この指定がなければ一瞬で変化する .delay(function(d){return 10 * d;}) // DOMの書き換えをX座標に依存して遅らせる指定 .duration(function(d){return 500 + 10 * d;}) // アニメーション速度の指定 .style("fill","green").attr("r",2) // CSSスタイルを変更 .attr("cy",function(d){return y(Math.cos(d * Math.PI / 180));}); // cosカーブに変更 attr関数やstyle関数やdelay関数やd uration関数など、多くのDOM操作を 伴う関数は、引数として実際の値の他 に、関数を渡すことが可能です。 関数の第一引数には __data__ が渡 され、第二引数にはインデックス番号が 渡されます。 このような仕組みとなっているため、D3 ではDOMノードに持たせたデータを 様々な局面で有効活用できます。 ここがD3の強みです。
  • 10. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 既存のDOMノードの数がデータより少ない状況で、新規DOMノードを追加する (D3のenter関数を理解する)  DOMのセレクション結果とデータを関連付けた後、データ側が余った場合に、DOMに関連付け出来なかったデー タを元に新規のDOMノードを追加する操作が可能です。 9 var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100), x = d3.scale.linear().domain([0,360]).range([0,360]), y = d3.scale.linear().domain([-1,1]).range([90,10]); for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする svg.append("circle").attr("class","dot") // circle一つ一つに「dot」クラスを設定 .attr("cx", x(deg)) .attr("cy", y(Math.sin(deg * Math.PI / 180))) .attr("r", 1); } // 上記circleにデータを付与する var data = d3.range(360); // [0,1,2, ... ,359] つまり、データ側は359度まで svg.selectAll(".dot").data(data) // これでDOMノードに __data__ が付与される .enter() // DOMのセレクション結果よりdata側が多かった場合、そのはみ出した部分の処理に入る .append("circle").attr("class","dot") .attr("cx",function(d){return x(d);}) .attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));}) .attr("r",2).style("fill","red"); 実はこの部分もenterで処理可能です。 ここがenterによって 追加されました。 svg.selectAll(".dot").data(d3.range(180)) .enter() .append("circle").attr("class","dot") .attr("cx",function(d){return x(d);}) .attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));}) .attr("r",1); 書き換えてみると こうなります。 この方式ではセレクション結果が空っぽの状態から開始します。データをDOMに紐付ける dataメソッドの処理も、「すべてのデータがDOMとは紐付かない」という結果になります。 enter関数で新規DOMを作成すると、全データに対するDOMノードが作成されます。
  • 11. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. enterの理解を深める その1  D3でのenterの仕組みは、なかなか理解できないことで有名です。ステップに分けて説明します。 10 svg.selectAll(".dot").data(d3.range(180)) .enter() .append("circle") svg.selectAll(".dot").data(d3.range(180)) .enter() svg.selectAll(".dot").data(d3.range(180)) svg.selectAll(".dot") クラス「dot」が付いているDOMノードをDOMツリーから検索します。 クラス「dot」が付いているDOMノードの一覧と、リスト構造のデータを結合します。 DOMノード一覧 = ◯ ◯ ◯ ◯ データのリスト = ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ←これらを先頭から組にする DOMに関連づいていないデータの一覧に絞ったデータの配列+D3ロジックが返ります。 DOMノード一覧 = ◯ ◯ ◯ ◯ データのリスト = ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ←DOMに関連づいていないデータ svg.selectAll(".dot").data(d3.range(180)) .enter() .append("circle").attr("class","dot") DOMに関連づいていなかったデータに対してcircleのDOMが生成され、 その配列が返ります。 DOMノード一覧 = ◯ ◯ ◯ ◯ ◯ ◯ ◯ ◯ データのリスト = ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ この処理の中で、生成したDOMノードに __data__ プロパティを付与してデータを 関連付ける処理も行われます。 circleのDOM配列に対してclassを指定します。典型的にはselectAllのセレクションで 指定したクラスを指定しますが、そうでなくても構いません。 つまり、プログラムの都合で違うものを付与しても構いません。 attr関数の戻り値は、thisです。よって、引続きattr関数やstyle関数やtext関数などを 使ってDOMの属性をセットアップしていくことが出来ます。
  • 12. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. enterの理解を深める その2  以下の書き方はD3ではよくあるけれども、どうもしっくりこない・・・  疑問1:何もセレクションされないことが分かっている時にselectAllを真面目に書く必要があるか? →その必要はないです。  疑問2:ノードにクラス指定する事が多いけど、D3ではクラス指定は必須なの? →その必要はないです。単に後々セレクションなどで使えて便利だからやっているだけです 11 svg.selectAll(".dot").data(d3.range(180)) .enter() .append("circle").attr("class","dot") .attr("cx",function(d){return x(d);}) .attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));}) .attr("r",1); svg.selectAll().data(d3.range(180)) .enter() .append("circle").attr("class","dot") .attr("cx",function(d){return x(d);}) .attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));}) .attr("r",1); svg.selectAll().data(d3.range(180)) .enter() .append("circle") .attr("cx",function(d){return x(d);}) .attr("cy",function(d){return y(Math.sin(d * Math.PI / 180));}) .attr("r",1);
  • 13. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 既存のDOMノードの数がデータより多い状況で、既存DOMノードを削除する (D3のexit関数を理解する)  既存のDOMのセレクション結果とデータを関連付けた後、既存DOMノード側の数が多く、余った場合に、その余っ たDOMノードを対象に処理をする事が可能です。 12 var svg = d3.select("#d3area").append("svg").attr("width", 360).attr("height", 100), x = d3.scale.linear().domain([0,360]).range([0,360]), y = d3.scale.linear().domain([-1,1]).range([90,10]); for (var deg = 0; deg < 180; deg++) { // 今後の説明のために描画は180度までとする svg.append("circle").attr("class","dot") // circle一つ一つに「dot」クラスを設定 .attr("cx", x(deg)).attr("cy", y(Math.sin(deg * Math.PI / 180))).attr("r", 1); } // 上記circleにデータを付与する。DOMノードは余る。 var data = d3.range(90); // [0,1, ... ,89] svg.selectAll(".dot").data(data).exit() .transition() // DOMの書き換えをアニメーションさせる指定。この指定がなければ一瞬で変化する .duration(function(_,i){return 10*i;}) // アニメーション速度の指定 .style("opacity",0) .remove(); データがアサインされ なかったDOMノード が徐々に消えます
  • 14. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 軸の導入 13 svg {border: dashed 1px blue; font-size: 12px;} .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } var data = d3.range(360).map(function(deg){return {x:deg,y:Math.sin(deg * Math.PI / 180)};}); var margin = {top: 15, right: 10, bottom: 25, left: 40}, width = 500 - margin.left - margin.right, height = 200 - margin.top - margin.bottom, x = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.x;}))).range([0,width]), y = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.y;}))).range([height,0]), g = d3.select("#d3area").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")") .call(d3.svg.axis().scale(x).orient("bottom")); g.append("g").attr("class", "y axis") .call(d3.svg.axis().scale(y).orient("left")); g.selectAll(".dot").data(data).enter() .append("circle").attr("class","dot") .attr("cx", function(d){return x(d.x);}) .attr("cy", function(d){return y(d.y);}).attr("r", 1); SVGのtransformの指定をすると、 座標系をずらす事が可能です 軸の描画に関しては、D3がそのような図形描画処 理を提供してくれています d3.extentを利用すると、データの最小値と最大 値が算出可能です。
  • 15. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. おまけ:sinカーブをcosカーブに「にゅーっ」と変形 14 var data = d3.range(360).map(function(deg){return {x:deg,y:Math.sin(deg * Math.PI / 180)};}); var margin = {top: 15, right: 10, bottom: 25, left: 40}, width = 500 - margin.left - margin.right, height = 200 - margin.top - margin.bottom, x = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.x;}))).range([0,width]), y = d3.scale.linear().domain(d3.extent(data.map(function(d){return d.y;}))).range([height,0]), g = d3.select("#d3area").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")") .call(d3.svg.axis().scale(x).orient("bottom")); g.append("g").attr("class", "y axis") .call(d3.svg.axis().scale(y).orient("left")); g.selectAll(".dot").data(data).enter() .append("circle").attr("class","dot") .attr("cx", function(d){return x(d.x);}) .attr("cy", function(d){return y(d.y);}).attr("r", 1); var newData = d3.range(360).map(function(deg){return {x:deg,y:Math.cos(deg * Math.PI / 180)};}); g.selectAll(".dot").data(newData) .transition() .duration(function(d){return 500+x(d.x);}) .delay(function(d){return 10*x(d.x);}) .attr("cy", function(d){return y(d.y);});
  • 16. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. イベント処理  D3はjQueryと同じようにon関数によって各種イベントを扱うことが出来るようになっています。 ここではclickイベントを拾って円の形を変える例を示します。 15 var svg = d3.select("#d3area").append("svg").attr("width",100).attr("height",100); svg.append("circle").attr("cx",50).attr("cy",50).attr("r",10) .on("click",function(){ svg.selectAll("circle") .transition().duration(300).attr("r",50) .transition().duration(300).attr("r",10) .transition().duration(300).attr("cx",80) .transition().duration(300).attr("cx",20) .transition().duration(900).attr("cx",50); }); 書き方はjQueryと同じ ちなみに・・・ D3はDOMノードの処理やイベント処理を記述可能 ですので、jQueryの代替として使う人も増えてきてい ます。jQueryと役割が重なる部分が多いのです。 ちなみにD3はSVGに特化したものではなく、実はHT MLのDOMノードやイベント全般が扱えます。 クリック 色々動く
  • 17. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. イベント処理 その2  イベントの処理例として、もう一つ、mousemoveイベントを拾って輪を描画するサンプルを紹介します。 16 var color = d3.scale.category20c(), i = 0; var svg = d3.select("#d3area") .append("svg").attr("width",640).attr("height",480) .style("pointer-events", "all") .on("mousemove", function(){ svg.append("circle") .attr("cx", d3.event.x).attr("cy", d3.event.y).attr("r", 1e-6) .style("fill","none").style("stroke", color(i++)).style("stroke-opacity", 1) .transition() .duration(5000) .ease(Math.sqrt) .attr("r", 100) .style("stroke-opacity", 1e-6) .remove(); }); 書き方はjQueryと同じ [処理内容] マウスポインタが動く際に発生するイベントに反応して動きます。 circleを作って、色はd3.scale.category20cという色生成関数で 生成した色を指定しています。 transition指定をして徐々に半径が広がるように、また、不透明 度(opacity)が下がるように、つまり透明になっていくように指定し 、 最後に透明になった後、DOMノードも消えるように指定しています。
  • 18. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 散布図  散布図の実現は簡単です。単純に軸を描画し、circleで点を描くだけです。 17 var data = [[3,5], [7,2], [1,10], [9,12], [5,13]]; var margin = {top: 15, right: 10, bottom: 25, left: 40}, width = 500 - margin.left - margin.right, height = 200 - margin.top - margin.bottom, x = d3.scale.linear().domain(d3.extent(data,function(d){return d[0];})).range([0,width]), y = d3.scale.linear().domain(d3.extent(data,function(d){return d[1];})).range([height,0]), g = d3.select("#d3area").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")") .call(d3.svg.axis().scale(x).orient("bottom")); g.append("g").attr("class", "y axis").call(d3.svg.axis().scale(y).orient("left")); g.selectAll().data(data).enter() .append("circle") .attr("cx",function(d){return x(d[0]);}) .attr("cy",function(d){return y(d[1]);}).attr("r",5);
  • 19. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 散布図で見るD3(およびJavaScript)のパフォーマンス  100,000個(10万個)のデータを散布図でプロットしました。HTMLの描画部分も含めて、全体で約2秒でプロット 可能でした。なお、現在関わっているプロジェクトでは約10万件のデータをJavaScriptのメモリー上に保持し、さま ざまな処理をしていますが、やはり問題にはなっていません。なお、100万件程度になると、インタラクティブな操 作が出来なくなるほど遅くなると思われます。 18
  • 20. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 円グラフ  以下に円グラフの例を示します。 19 var data = [["A",4], ["B",3], ["C",2], ["D",1]]; var width = 400,height = 400,radius = 200, arc = d3.svg.arc().innerRadius(0.3*radius).outerRadius(0.9*radius); var c = d3.scale.category20c(); var g = d3.select("#d3area").append("svg").attr("width",width).attr("height",height) .append("g").attr("transform","translate(" + width / 2 + "," + height / 2 + ")") .selectAll().data(d3.layout.pie().sort(null).value(function(d){return d[1];})(data)) .enter().append("g").attr("class","arc"); g.append("path").style("fill",function(_,i){return c(i);}).style("stroke","black").attr("d",arc); g.append("text") .attr("transform",function(d){return "translate(" + arc.centroid(d) + ")"; }) .attr("dy","0.35em").style("text-anchor","middle").style("font-size","30px") .text(function(d){return d.data[0];}); ここが円グラフの弧の部分の形を生 成するコア部分 ここは円グラフ用のデータを作るため に必要な部分。ここも重要。 <sunburst> 円グラフのプリミティブである円弧を組合せていくと、 sunburstというモダンな表現も可能になります。 プリミティブの円弧
  • 21. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. Chord diagram に挑戦  以降のスライドでChord diagramを扱ってみます。通常目にする散布図、折れ線グラフ、棒グラフ、 円グラフなどとは違うものです。見た目は以下の様なものです。 20 このような円弧は円グラフ(パイチャート)で使った 円弧の表現を応用します。ラベル部分も円グラフと 同じです。オフセットが異なるだけです。 Chord diagram 特有のこの円弧は、D3が提供す る d3.svg.chord() で描画可能なものになります。
  • 22. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. Chord diagram: bigramをChord diagramで表現してみます  Chord diagramは、相互に数値的な関係のあるノード間の強さを表現します。なかなか具体例がな いと説明出来ないため、ここではbigramを例に用いて説明します。  bigram(バイグラム)とは  英単語の「the」を用いて説明します。theはtの後にhが来て、hの後にeが来ます。こうなる確率は以下の通 りです。このような、英文字間の遷移確率データをbigramと呼びます。  英語でtの後にhの来る確率=33%  英語でhの後にeの来る確率=52%  bigramのデータを表形式で表現することも出来ます。たとえば以下のようなものになります。  bigramを3次元グラフで描画することも可能です。(下記はExcelで描画したもの) 21 t h e 33% 52% aが来る bが来る cが来る dが来る eが来る ・・・ aのあとに 20 3279 4961 5105 65 bのあとに 1754 164 112 13 6150 cのあとに 8507 8 865 50 5204 dのあとに 3254 133 129 1304 13219 ・・・ ← 数字は、ある英文テキストにおける 出現回数 ← 横軸は「aのあとに」などの最初の文字 奥行き方向の軸は「bが来る」などの次の文字 棒の高さは、そのようなパターンの出現回数 この中で飛び抜けて高い棒は「th」のパターン。
  • 23. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. Chord diagram: bigramはネットワーク構造をしたデータ  bigramは、「エッジに数値の付いた有向サイクリックグラフ」です。ここで言うグラフは、ネットワーク 構造の事です。bigramを素直にノードとエッジを用いたグラフ構造として表現すると以下のようにな ります。なお、すべてのノードについて記述するとクモの巣状になってしまうので、4文字のみ取り上 げました。 22 t h e 51626 34984 21256 3004 312 13969 i 186341 1233 6159 00 数字は、あるドキュメントでそのような遷移が出現した回数。 本当にaからzまでのすべての単語について記述するとなると、 1つのノードからaからzまでの26ノードへの関連が発生する。 本当に描画してしまうとグチャグチャに・・・ → そこでChord diagram! 3177 2 71 3893
  • 24. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. Chord diagram: D3を用いてbigramをChord diagramで表現する  以下はD3を用いてbigramをChord diagramで表現してみたものです。 23 たとえば 「t」 のノードにフォーカスすると、アルファベット「t」の 次に来やすいアルファベットに対して線が引かれます。 ノード「t」に接続している側の線の太さは、遷移のしやすさを 意味します。たとえば「t」の次は「h」が来やすいため太い線と して表現されています。 逆に「h」のノードから「t」のノードに行く事を考えると、「h」の 側は細く描画されていることが分かります。そのため「ht」のような 並びは英語ではレアであることが分かります。 太い 細い
  • 25. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. Chord diagram のソースコード 24 var width = 500, height = 500, innerRadius = 0.35 * width, outerRadius = 1.2 * innerRadius; var color = d3.scale.category20(); // 座標の原点をSVGのエリアの中心に var svg = d3.select("body").append("svg").attr("width", width).attr("height", height) .append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // chord用データを生成 var chord = d3.layout.chord().padding(.05).sortSubgroups(d3.descending).matrix(matrix); // chord特有の弧の部分を描画 svg.selectAll().data(chord.chords).enter() .append("path").attr('class','chord-path') .attr("d", d3.svg.chord().radius(innerRadius)) .style("fill",function(d){return color(d.target.index);}) .style('stroke',function(d){return color(d.target.index);}) .style('stroke-width','1').style("opacity", 0.8).style("stroke-opacity",1); // 周囲の円弧の土台を作成してデータを投入 var g = svg.selectAll().data(chord.groups).enter().append("g").attr('class','chord'); // 周囲の円弧を描画 g.append("path").style("fill", function(d){return color(d.index);}) .style("stroke", function(d){return color(d.index);}) .attr("d", d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius)) .on("mouseover", fade(0.1,0.1)) .on("mouseout", fade(0.8,1)); function fade(opacity,s_opacity) { return function(g, i) { svg.selectAll(".chord-path") .filter(function(d) { return d.source.index != i && d.target.index != i; }) .transition().style("opacity",opacity).style("stroke-opacity",s_opacity); }; } // 周囲のテキストを描画 g.append("text") .attr("dy","0.35em").style("text-anchor","middle").style("font-size","14px") .text(function(d,i){return String.fromCharCode('a'.charCodeAt()+i);}) .attr("transform",function(d){ return "translate(" + d3.svg.arc().innerRadius(outerRadius) .outerRadius(1.15*outerRadius).centroid(d) + ")"; });
  • 26. ULS Copyright © 2013 UL Systems, Inc. All rights reserved. 他にも色々・・・。data visualization の世界は研究分野の1つなので本当に沢山のア イディアがあるようです。 D3を使えば、その新しいアイディアをより楽に実装できます。 25 http://bl.ocks.org/mbostock/4063269 http://bl.ocks.org/mbostock/raw/1044242/ http://bl.ocks.org/mbostock/4063570 http://bl.ocks.org/mbostock/1062288 http://bl.ocks.org/mbostock/950642 http://bl.ocks.org/mbostock/4063582 http://bl.ocks.org/mbostock/4060366 http://bl.ocks.org/mbostock/4063530 [データビジュアライゼーションのセオリー:人は可視化されたデータをどう見るか]  人は、オブジェクトの面積に敏感です。データのスカラー値を面積に比例させると、人はデータ間の相対的な比較を感覚的に行えます。古典 的にはこのような人の性質を用いて円グラフや棒グラフを作っていました。  人は、色をある程度認識できます。しかし、色の認識は面積ほどではありません。人に傾向を読み取らせるために有向に使える場合がありま す。たとえばヒートマップは色の使い方の有名な例です。  人は連続的な変化を好みます。そのため、似たデータは近くに配置するなどの工夫が有効な場合があります。また、アニメーションも連続的 な変化の一種なので、アニメーションもデータを理解させるツールとして使うと効果的なことがあります。