Webっちゃ Vol.21 「D3.jsを始めよう」

  • このエントリーをはてなブックマークに追加
  • 2017/10/11 開催 [Webっちゃ] 用記事です。
  • 本記事では D3.js ver4系 での記述になります。

データビジュアライゼーションとは?

今巷で流行りのデータビジュアライゼーションとは一体何か?

データビジュアライゼーション(データの可視化)とは、膨大なデータをグラフや図で数字だけでは理解しづらかったデータ間の特徴・関係性・傾向などを視覚的にわかりやすくする手法のことを指します。

現在ではいくつかのグラフ描画用ライブラリが様々なところから配布されており、グラフを動的に生成する事が比較的容易になっており、画像などではなく、動的にグラフを出力し、ユーザーが見たい情報を抽出→描画することで様々な分野で導入されています。

Chart.js

本題とは少し外れますが、まずは代表的な例として Chart.js を簡単にご紹介。

Chart.js

特徴

  • グラフ描画用のオープンソースjavascriptライブラリ
  • 8種類のグラフフォーマットが用意されている
  • javascriptが書けない人でも導入が容易である
  • 動作の指定はオプションを指定するだけ
  • アニメーションやレスポンシブ機能も標準搭載

上記の特徴から見て取れるようにデータビジュアライゼーションの入門としてはとても簡単です。
デザインもはじめからある程度綺麗に作られており、特に指定することもほとんどありません。

しかし、実案件でディレクション時からChart.jsを想定した仕様になっていなければ、Chart.jsで対応できないこともしばしば・・・

そこで世界中のデータビジュアライザーから指示を集めているのが D3.js です!

D3.js

D3.js とは、 Data-Driven Documents (データ駆動型ドキュメント) の略称であり、2011年から開発が始まったデータビジュアライゼーション用のJavascriptライブラリになります。
一般的にチャートライブラリではなく、データビジュアライゼーション・エンジンと呼ばれる事が多い。

D3.js

特徴

  • グラフ描画用のオープンソースjavascriptライブラリ
  • フォーマットは用意されていない
  • データを元に座標系に変換する計算などはある
  • 完全玄人志向
  • 全ての動き・指定は制作者が付ける
  • アニメーションやレスポンシブ機能は全て自分で実装

 

 

……は?

 

 

 

は?

 

 

 

は????

 

 

 

ちょっと不親切すぎやしませんかね?
ハードル高すぎじゃね????
だれがこんなもの使うの???

 

 

 

。。。と思ってる時期が自分にもありました。

使ってみると、他のライブラリのように
「指定の動きを再現したいのにオプションがみつからない」
「したいことが機能的に再現できない」
などがないと気づけます。
というか、「なかったら作れば良い」がD3.jsの特徴というか本質です。

ネガキャンばかりしてもしょうがないので良い点を幾つか

  • 指定の面倒なデータの整形等がし易い
  • 多種多様な描画が可能(サンプル多数)
  • デザインに沿ったグラフ描画ができる
  • できないものはないんじゃないか?

良い点というかほぼ感想ですが。。。苦笑
実際にサンプルを見てみましょう。

このように様々なグラフや情報の可視化を行えるのがD3.jsの特徴です。

 

 

 

グラフを作る手順

さあ、やっとD3.jsを使用したグラフの制作手順に入っていきます。

D3.jsを使用したグラフの制作手順としては様々ありますが、主な制作手順としては以下になります。

  1. グラフ化するデータを用意
    • データは様々なものに対応(json,csv,tsv,…etc)
  2. 描画する領域を定義
  3. X軸、Y軸の範囲指定
  4. データを描画するカラーを設定
  5. X軸、Y軸を描画
  6. データを描画

基本的な動きとしては上記の流れで定義・指定を行っていき描画してきます。
次から実際に制作しながら各流れを説明していきます。

棒グラフを作ろう

基礎的なグラフとしてまずは棒グラフの生成方法です。

1. グラフ化するデータを用意

まずはグラフ化するデータを用意します。
今回はjavascript内で全て完結させたいので、オブジェクトで生成。

var _data = [
  {'name': 'A','data': 50},
  {'name': 'B','data': 100},
  {'name': 'C','data': 500},
  {'name': 'D','data': 300},
  {'name': 'E','data': 400}
];

2. 描画する領域を定義

D3.jsでは描画領域の指定を行い、そこに各データを入れていきます。
まずはその描画領域の指定に必要な初期設定を決めていきます。

// 初期設定
var _barTarget = d3.selectAll('#graph'); // 描画するDOMを指定

//描画領域のサイズを取得
var _canvas = {
	width: _barTarget.node().getBoundingClientRect().width,
	height: _barTarget.node().getBoundingClientRect().height
};

// 枠内の余白用マージンを定義
var _margin = {top: 10, right: 20, bottom: 10, left: 20};

// svgの描画初期設定
var _svgInit = {
	width: _canvas.width - _margin.left - _margin.right, //グラフの横幅
	height: _canvas.height - _margin.top - _margin.bottom, //グラフの高さ
	fontSize: 8, // 文字サイズ
	barWidth: 12 // 棒グラフの横幅
};

// svgの定義
var _svg = d3.select(_barTarget)
	.insert('svg')
	.attr('width', _canvas.width)
	.attr('height', _canvas.height)
	.append('g')
	.attr('class', 'chart');

冒頭でDOMを指定する箇所で d3.~ と指定しています。
これは、d3ライブラリの関数を使用する際に使用する宣言だと覚えてください。
jQueryでいう $() みたいな感じです。

また、基本的にD3での記述になるため、7-8行目にある横幅・高さの取得のように各指定・取得方法が若干異なります。
DOMの操作系に関して分かりやすかった記事がありますのでそちらを参考にしてください。

3. X軸、Y軸の範囲指定

データを描画する領域に目盛りとしてX軸・Y軸を生成しますが、
各軸のデータを目盛りに反映させるために描画するデータの範囲を指定します。

// x軸の範囲を指定
var _x = d3.scaleBand()
	.rangeRound([0, _svgInit.width]);
var _y = d3.scaleLinear()
	.rangeRound([_svgInit.height, 0]);

// 各軸のデータ最小値・最大値を指定
_x.domain(_data.map(function (d) {
	return d.name;
}));
_y.domain([0, d3.max(_data, function (d) {
	return d.data;
})]).nice();

4. データを描画するカラーを設定

各グラフに色付けを行う際に対応する色を設定します。
一般的に配列で各カラーコード(16進数)を指定する場合もありますが、
D3.jsではカラー指定用の関数がはじめから用意されていますのでそれを利用します。

// カラーを定義
var _colorScale = d3.schemeCategory10;

5. X軸、Y軸を描画

X軸とY軸を描画します。
ここで気を付ける点としては、
X軸の目盛りは初期状態ではグラフの上に配置されるので、 transform でグラフの下に配置するように指定します、

// X軸
_svg.append('g')
	.attr('class', 'axis x')
	.attr('transform', 'translate(0,' + _svgInit.height + ')')
	.call(d3.axisBottom(_x));

// Y軸
_svg.append('g')
	.attr("class", "y axis")
	.call(
		d3.axisLeft(_y)	.ticks(10) //目盛りの数を指定
	);

6. データを描画

最後にデータを実際に棒グラフへ描画します。

// 棒グラフ描画
_svg.selectAll('.chart')
	.data(_data)
	.enter().append('rect')
	.attr('class', 'bar')
    .attr('fill', function(d,i) {
		return _colorScale[i];
    })
	.attr("x", function(d) { return _x(d.name) + _x.bandwidth() / 2 - _svgInit.barWidth / 2; })
	.attr("y", function(d) { return _y(d.data); })
	.attr("height", function(d) { return _svgInit.height - _y(d.data); })
	.attr('width', _svgInit.barWidth);

実行結果

See the Pen GMGNEa by 3a works (@3aworks) on CodePen.

 

 

 

アニメーション描画

ただグラフを描画するだけだと表示時に寂しいなどの意見が出てきます。
そこで、データを表示する際には動きをつけてユーザーにデータへの関心を高めるようにします。

元々D3.jsにはアニメーション用の関数も用意されているためそれを利用します。

1. データ設定時初期位置に指定

まずはアニメーションする前の状態で描画します。

// 棒グラフ描画
_svg.selectAll('.chart')
	.data(_data)
	.enter().append('rect')
	.attr('class', 'bar')
    .attr('fill', function(d,i) {
		return _colorScale[i];
    })
	.attr("x", function(d) { return _x(d.name) + _x.bandwidth() / 2 - _svgInit.barWidth / 2; })
	.attr("y", function(d) { return _y(0); }) // y座標を値0の位置へ
	.attr("height", function(d) { return 0; }) // グラフの高さを0にします。
	.attr('width', _svgInit.barWidth);

2. アニメーション後の状態を指定

// 次に描画しているグラフ要素(この場合は .bar ) に対してアニメーションの指定をして、実際のデータを指定します。

function animation(){
	// アニメーション表示
	_svg.selectAll('.bar')
		.transition()
		.delay(200) // 発火タイミング
		.duration(500) // アニメーションの時間
		.attr("y", function(d) { return _y(d.data); }) // 実際のデータ
		.attr("height", function(d) { return _svgInit.height - _y(d.data); }) // 実際のデータ
}

animation(); // アニメーション実行

実行結果

See the Pen wrXJXR by 3a works (@3aworks) on CodePen.

 

 

 

実例紹介

実例紹介では実際に制作した案件でのグラフをご覧いただきます。

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。