放射線量可視化(4):Highcharts JSのグラフによる可視化
注: この作業によって作成した可視化グラフはhttp://FromTo.Cc/rad/で、結果の定期ツイートは@xckbradで公開されています。
HTMLでの準備
Highcharts JSの利用法は、公式サイトに詳細なマニュアルとサンプルが用意されていますが、 今回のページで使った手法を簡単に解説します。
まずはHighcharts JSのライブラリと、 リアルタイムデータの取り込みのためのjQueryを読み込みます。
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"> </script> <script src="/js/highcharts.js" type="text/javascript"></script>
そして、今回のサイトでHighcharts JSを使うためのJavaScriptファイルchart.js(後述)を読み込みます。
<script src="chart.js" type="text/javascript"></script>
<body>内では、グラフを描く<div>を用意します。
そして複数のグラフを縦に並べるために、間に空の<div class="spacer">を入れています。
<div id="graph5m" class="graph"></div> <div class="spacer"></div>
これらの<div>はスタイルシートで次のようにスタイルが定義されています。
.graph {
background-color: white;
width: 95%;
height: 400px;
margin: auto;
}
.spacer {
height: 30px;
}
この<div class="graph">に、chart.js内のJavaScriptで、Highchrts JSのグラフを描画します。
JavaScriptでの準備
ということで、グラフ生成のためのJavaScriptのchart.jsについて簡単に解説します。
まずは、Highcharts JSの時間軸サポートは標準でUTCとなってしまうので、ローカルタイムを使用するために次の設定を入れます。
Highcharts.setOptions({
global: {
useUTC: false
}
});
で、変数を宣言。
var firsttime5m; var chart5m;
jQueryでページ表示時に初期化してもらいます。適当にコメントを入れてみました。 表示するグラフのデータは後述するreqeustData5m()という関数でAjaxを使って初期化します。 とりあえずは空でデータの入れ場所を用意しておきます。
$(document).ready(function() {
firsttime5m = true;
// グラフの生成
chart5m = new Highcharts.Chart({
chart: {
// 描画対象の<div>のIDはgraph5m
renderTo: 'graph5m',
// 折れ線グラフを指定
type: 'line',
// requestData5m()で表示データを初期化する
events: {
load: requestData5m
}
},
title: {
text: '空間線量測定値 (1日分・5分間隔)'
},
subtitle: {
text: '[神奈川県川崎市多摩区]'
},
xAxis: {
// X軸に関しては時間軸サポートで詳細なフォーマットを指定可能
type: 'datetime',
dateTimeLabelFormats: {
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%m/%e %H:%M',
day: '%y/%m/%e',
week: '%y/%m/%e',
month: '%Y/%m',
year: '(%Y)'
}
},
yAxis: {
title: {
text: '5分間平均線量(μSv/h)'
},
min: 0
},
tooltip: {
// グラフ上にマウスカーソルを持っていった場合の表示
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%m月%e日%H時%M分 ', this.x) +
': ' + this.y +'μSv/h';
}
},
series: [{
name: '5分間平均線量(μSv/h)',
// データはとりあえず空で初期化、Ajaxで読み込む
data: []
}]
});
特に、Highcharts JSは時間軸のフォーマットに関して、
表示する時系列データの幅に基づいて、
指定したdateTimeLabelFormats:に従って自動的に調整してくれます。
この機能はなかなか素晴らしい。
そして、データ初期化のrequestData5m()関数はこのような処理です。 こちらも適宜コメントを追加してみました。 jQueryのおかげで非常に簡単にAjaxでJSONのデータを読むことができます。 ありがたい。
function requestData5m() {
// jQueryによるAjaxの処理
$.ajax({
// JSONデータを読み込む相対URL
url: 'このファイルからの相対パス/doserae2-1day.json',
// 成功した場合、Highcharts JSのAPIを用いてデータを設定
// (データの参照はseries.dataで可能だが更新はAPIが必要)
success: function(points) {
var series = chart5m.series[0];
// JSON形式で転送されてきた配列のデータは、
// pointsという変数に入っているので、
// 最新のものをlastpoint変数に取得
var lastpoint = points.pop();
if (firsttime5m) {
// 完全初期化の場合
// JSONデータの全てをグラフに追加する
for (var i in points) {
series.addPoint(points[i], false, false);
}
// 最後に、最新のデータを入れるタイミングでグラフを再描画する
// (addPoint()の第2引数はredraw)
series.addPoint(lastpoint, true, false);
firsttime5m = false;
}
else {
// 差分更新の場合
// JSONデータについて、最新以外のすべてのデータが
// 既にグラフ上に存在しているかをそれぞれチェック
for (var i in points) {
var seen = false;
for (var j in series.data) {
if (series.data[j].x == points[i][0]) {
seen = true;
break;
}
}
// 存在していなければAPIで該当データを追加
// 再描画や古いデータの削除は行わない
if (!seen) {
series.addPoint(points[i], false, false);
}
}
// JSONデータの最新のものが、
// 既にグラフ上に存在しているかどうかをチェック
var seen = false;
for (var i in series.data) {
if (series.data[i].x == lastpoint[0]) {
seen = true;
break;
}
}
// 存在していなければ最新データを追加する
// 追加時に、最古のデータは削除される
// (addPoint()の第2引数はredraw, 第3引数はshift)
if (!seen) {
series.addPoint(lastpoint, true, true);
}
}
// 150秒ごとにこの関数は呼び出される
setTimeout(requestData5m, 150*1000);
},
// Ajaxデータの読み込み時にキャッシュしないようにする
cache: false
});
}
これで、グラフが表示できるようになりました。 同様の処理を2時間平均、1日平均のグラフについても行なっています。 これはhttp://FromTo.Cc/rad/でソースを表示することでも確認できます。
さて、最後はこの集計結果をTwitter Botとしてつぶやく処理です。 これは来週の日曜プログラミングに続く。
