Post on 20-Jul-2015
D3.js入門:BarChartのスクリプトを読み解く2014/12/28
保田
D3.jsとは?
データ視覚化に特化したjavascriptライブラリ
DOM要素を最大限に利用
WEB系の人は習得しやすい(たぶん)
ブラウザの開発ツールでデバッグできる
HTML/CSSのアップデートに対応しやすい
「チェイニング」で記述
必要な属性のみ指定すればいい
(基本的に)指定の順番は関係ない
jQueryに似てる
実例を見てみる! : 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/
時系列データのグラフ化ライブラリ。エリア、折れ線、バー、散布などが簡単に作成できる。