インタラクションの実装
さて昨日は D3.js 日本語訳の全 16 章の内容を駆け足で一気に書き下ろしてみましたが、この内容だけですと静的なプロッティングしかできずなんとも消化不良です。
そこで今回は前々回にも紹介した NVD3 との組み合わせでいよいよ D3.js の肝心の目玉であるインタラクションを実装していきます。
完成形のデモアプリケーションはこちらから閲覧できます。
(うまく表示されない場合はブラウザをリロードしてみてください)
Heroku を利用する
いままでは画像をペタペタと記事に貼ってきましたがインタラクションを見せるには Qiita に画像を貼るだけでは不十分です。そこでデモアプリケーションとして外部のサイトにデプロイすることを考えます。こんなときに非常に便利なのが Heroku というサイトです。詳細はこの辺りを読めば分かると思いますが要は無料でも使える PaaS サービスです。
Heroku に静的な HTML だけを置くことは通常はできません。そこで D3.js を Sinatra アプリケーションのビューとして組み込むことによって Heroku へのデプロイを可能にします。
今後 D3.js を使うにあたり Ruby などのアプリケーションの一部として開発を進めるようなことがあっても、このように最初から連携しておくと何かと応用が効いて便利ですね。
ビューの実装
index.erb という名前でビューを作成します。とはいっても ERB の部分は何もありませんので中身は単なる HTML ファイルです。今回はこれをデモアプリで表示するのが目的です。一応 ERB という扱いなので views サブディレクトリに配置します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3.js</title>
<!-- D3.js 本体を読み込む (予め公式サイトからダウンロードしておく) -->
<script type="text/javascript" src="/d3/d3.min.js"></script>
<!-- NVD3.js を読み込む (予め公式サイトからダウンロードしておく) -->
<script type="text/javascript" src="/nvd3/nv.d3.min.js"></script>
<!-- NVD3.js 用の CSS を忘れないように -->
<link rel="stylesheet" type="text/css" href="/nvd3/nv.d3.css" />
<!-- 自作の CSS を読み込む -->
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body class='with-3d-shadow with-transitions'>
D3.js
<div>
<!-- チャートを表示するための空の SVG -->
<svg id="chart1"></svg>
</div>
<!-- 自作の JS を読み込む -->
<script type="text/javascript" src="d3js.my.js"></script>
</body>
</html>
データの定義
JSON で次のようにデータを定義します。
[
{
"key" : "キー項目名" ,
"values" : [ [ "UNIX 時刻印 (数値)" , "データの値 (数値)"]]
} ,
{
"key" : "キー項目名" ,
"values" : [ [ "UNIX 時刻印 (数値)" , "データの値 (数値)"]]
}
]
なお元となるデータの整形については以前に書いた Python での整形テクニックを利用すると良いでしょう。
NVD3 を利用したプロッティング
d3.json メソッドで読み込んだ JSON 形式のデータを NVD3 で描画します。なお一応 Sinatra アプリケーションなので JavaScript や CSS 、データとなる JSON のように外に提供するリソースは public サブディレクトリに配置します。 D3.js や NVD3.js も以前に解説した通り筆者は外部サイトから読み込む方法を採用したくないので同様に public に配置します。
d3.json('data.json', function(data) {
// 色の定義
var colors = d3.scale.category20();
keyColor = function(d, i) {return colors(d.key)};
// グラフの描画
// NVD3 を使って Stacked Area Chart な関数を定義する
var chart;
nv.addGraph(function() {
chart = nv.models.stackedAreaChart()
.useInteractiveGuideline(true)
.x(function(d) { return d[0] })
.y(function(d) { return d[1] })
.color(keyColor)
.transitionDuration(300);
// X 軸
chart.xAxis
.tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });
// Y 軸
chart.yAxis
.tickFormat(d3.format(',.2f'));
// D3.js で SVG を選択してデータの配列回数分だけメソッドを実行
d3.select('#chart1')
.datum(data)
.transition().duration(1000)
.call(chart) // NVD3 の関数を .call する
.each('start', function() {
setTimeout(function() {
d3.selectAll('#chart1 *').each(function() {
console.log('start',this.__transition__, this)
if(this.__transition__)
this.__transition__.duration = 1;
})
}, 0)
})
nv.utils.windowResize(chart.update);
return chart;
});
});
CSS の実装
CSS も public サブディレクトリに置きます。
body {
overflow-y:scroll;
}
text {
font: 12px sans-serif;
}
#chart1, #chart2 {
height: 500px;
}
デモアプリケーションの完成
あとは Heroku に git push すれば完成です。
D3.js デモアプリケーション
http://d3js-stacked-chart.herokuapp.com/
Chrome ブラウザで閲覧するのが推奨です。
まとめ
今回は NVD3 のデモ通りのアプリケーションを実装し Heroku にデプロイしてみました。これでようやく手持ちのデータを整形すればインタラクティブなデータ可視化をできそうな手応えが感じられるようになったのではないでしょうか。