放射線量可視化(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としてつぶやく処理です。 これは来週の日曜プログラミングに続く。