D3.js入門:BarChartのスクリプトを読み解く
2014/12/28
保田
D3.jsとは?
データ視覚化に特化したjavascriptライブラリ
DOM要素を最大限に利用
WEB系の人は習得しやすい(たぶん)
ブラウザの開発ツールでデバッグできる
HTML/CSSのアップデートに対応しやす
い
「チェイニング」で記述
必要な属性のみ指定すればいい
(基本的に)指定の順番は関係ない
jQueryに似てる
実例を見てみる! : script
Ref. http://bl.ocks.org/mbostock/3885304
実例を見てみる! : html/css部分
Ref. http://bl.ocks.org/mbostock/3885304
【html/css部分】
!
<!DOCTYPE html>
<meta charset="utf-8">
<style>
!
.bar {
fill: steelblue;
}
!
.bar:hover {
fill: brown;
}
!
.axis {
font: 10px sans-serif;
}
!
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
!
.x.axis path {
display: none;
}
!
</style>
!
…次頁へ続く
実例を見てみる! : script部分
Ref. http://bl.ocks.org/mbostock/3885304
【スクリプト部分】
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
!
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
!
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
!
var y = d3.scale.linear()
.range([height, 0]);
!
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
!
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10, "%");
!
var svg = d3.select("body").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 +
")");
!
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
!
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
!
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
!
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); });
!
});
!
function type(d) {
d.frequency = +d.frequency;
return d;
}
</script>
D3.jsの基本構造は、DOM要素とDataを対応づけすること
DOM Data
対応
3つの基本API
select
data
scale
どのDOM要素で
どんなデータを
どんな大きさで
描くか。
select と append
!
!
!
!
!
!
var svg = d3.select("body").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 + ")");
!
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return
d.frequency; })]);
!
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
!
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
!
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height -
y(d.frequency); });
!
});セレクション(svg下にあ
るすべての.barクラス)
に、dataを対応づける
select:(最初の)DOM要素を選択
selectAll: すべてのDOM要素を選択
append: DOM要素を追加
※引数にはCSSと同等の表記が使える
d3.select()、d3.selectAll()について
d3.select() d3.selectAll()は、DOM要素を参照するメソッド。戻り値は指定した要素(のセット)。
参照(引数)の種類としては、
・タグ( div など)
・ID( #foo など)
・アトリビュート( [color=red] など)
・関係( parent child など)
がある。
また、複数の組み合わせ、
・AND( .this.that = thisクラスの中のthatクラス)
・OR( .this, .that thisクラスまたはthatクラス)
も可能。
d3.select()は条件にマッチした最初の要素のみが入った配列が返る。HTMLノードを取り出したいとき
は、d3.select(セレクションの記述).node()とする。
条件にマッチしたすべての要素(の配列)を得るには、d3.selectAll()を使う。
dataのバインド
!
d3.tsv("data.tsv", type, function(error, data) {
!
<途中省略>
!
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height -
y(d.frequency); });
});
!
function type(d) {
d.frequency = +d.frequency;
return d;
}
セレクション(svg下にあ
るすべての.barクラス)
に、dataを対応づける
(バインド)
d3.csv(url [,accessor], callback関数)
d3.tsv(urll [,accessor], callback関数)
※urlからcsv/tsvファイルを読み終わったら、
callback関数を実行する
callback関数の第2引数が読み込んだデータ
enter()
セレクションのうち、ま
だdataが対応していない
ものすべて
enter と exit
DOM Data
対応
exit
データが対応づけられていないDOM要素のサブセット
enter
DOM要素が対応づけられていないデータのサブセット
scaleとaxis
!
!
!
!
!
!
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
!
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
!
var y = d3.scale.linear()
.range([height, 0]);
!
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
!
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10, %");
!
var svg = d3.select("body").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 + ")");
!
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) {
return d.letter;
}));
y.domain([0, d3.max(data,
  function(d) {
return d.frequency;
})]);
!
Xスケール定義
ordinal 順序尺度
domainの設定
Yスケール定義
linear 線形
X軸
先に定義したXスケールを設定
Y軸
先に定義したYスケールを設定
.orient() 目盛りの方向と位置
.ticks():目盛りの数と単位
scale: 元データから画面表示への「変換関数」
.domain() データ範囲
.range() 描画範囲(ピクセル座標)
axis: 軸の「描画関数」 scaleが入力
scaleの種類
ordinal 順序尺度(非数)
linear 線形
sqrt	 平方根
pow 指数
log 対数
map(function(d)….
!
データのletter列の各
データを要素とする配列
を返す
scaleとaxis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
!
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
!
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return
y(d.frequency); })
.attr("height", function(d) { return height -
y(d.frequency); });
!
!
X軸を描画
rectの幅を rangeBand():バ
ンド幅、に設定
x(d.letter)で、d.letterに対応す
るX座標を得る
X軸
先に定義したXスケールを設定
rectの高さを height-y(d.frequency)
に設定
Y軸を描画
y(d.frequency)で、d.frequencyに対す
るY座標を得る
rangePointsとrangeBands/rangeRoundBandsの違い
var test = d3.scale.ordinal()
.domain(["一郎", "次郎", "三郎", "四朗", "五郎", "六郎"])
.rangePoints([min, max], outerPadding);
!
test("三郎") // 200を返す
!
!
!
!
var test = d3.scale.ordinal()
.domain(["一郎", "次郎", "三郎", "四朗", "五郎", "六郎"])
.rangeBands([min, max], padding, outerPadding);
!
さらに、rangeRoundBandsは、
レンジ幅、バンド幅、オフセット値が整数になるよう調整する
!
!
!
rangeBandsとrangeRoundBandsの違い:
https://gist.github.com/aubergene/5214125
.rangePointsは、両端からouterPaddingを除いて、n-1個の領域に分
割。
両端に pointが来る。
.rangeBandsは、outerPaddingを除いて、n個の領域に分割。
さらに個々の領域からpaddingを除いたものが、rangeBand
D3.jsの参考用リソース
D3.js 3つの小円
http://ja.d3js.node.ws/document/tutorial/
circle.html
!
D3.js Example
https://github.com/mbostock/d3/wiki/Gallery
!
D3.js入門 スコット・マレイ
http://ja.d3js.info/alignedleft/tutorials/d3/
!
Over 2000 D3.js example
http://techslides.com/over-2000-d3-js-
examples-and-demos
!
Over 1000 D3.js example
http://techslides.com/over-1000-d3-js-
examples-and-demos
d3.jsのライブラリ
2014.12.28
保田
crossfilter.js
http://square.github.io/crossfilter/
多次元フィルタリング用ライブラリ。高速性が売り。
dc.js
http://nickqizhu.github.io/dc.js/
多次元解析のライブラリ。 crossfilter オブジェクトを通じてメソッドを使う。
参考: http://toshiha.blogspot.jp/2013/12/dcjs.html
c3.js
http://c3js.org/
チャート・ライブラリ。Line, Timeseries, Spline, Bar, Scatter, Pie, Area, Donutなど基本的なものはひと通り
ある。D3.jsをラップすることで、より簡単にグラフを作成できる。
Vega
http://trifacta.github.io/vega/
データを特定のルールにしたがったJSONで定義することで、グラフが描画できる
Rickshaw
http://code.shutterstock.com/rickshaw/
時系列データのグラフ化ライブラリ。エリア、折れ線、バー、散布などが簡単に作成できる。
Cubism.js
http://square.github.io/cubism/
同じく、時系列データのグラフ化ライブラリ。
NVD3
http://nvd3.org/
チャートおよびチャート要素のライブラリ。カスタマイズも可能。

D3js入門 - Code for Kobe 可視化勉強会資料