目的
Rubyの簡易サーバSinatraを立ち上げて、DBに蓄積されているデータをHighchartsを使ってグラフ化するまでのメモ。センサが定期的にSinatraサーバにデータをPostして、webからアクセスした時に蓄積したデータをグラフ表示で見ることを想定。
フォルダ構成
erbはviewsに、jsはpublicに入れるのがsinatraの決まり事。
highchartsは公式サイトからダウンロードしましょう。
/
│ app.rb
│
├─ views
│ index.erb
│
└─ public
highcharts.js
データベース構成
データベースはこんな感じ。
datatypeとdataのカラムを用意して、センサ種類を定義しながら一括でDB管理できるようにした。datatypeごとにdataを取得してグラフ化していく。
|id | datatype | data |created_at | updated_at |
|:--|----------|------|-------------------------+-----------:|
| 1 | abc | 12 | 2014-05-21 12:17:38 UTC | *** |
| 2 | abc | 123 | 2014-05-20 13:20:16 UTC | *** |
| 3 | abc | 123 | 2014-05-18 12:11:39 UTC | *** |
前提
SinatraでデータをPost/DeleteしてDB操作を行う方法は、以下のHPを参考にして作りました。ここでは割愛。データがあることを前提に、erbにデータを渡して、JavascriptのHighchartsを使ってグラフ化していく。
・Sinatra+ActiveRecord+SQLite3で,軽量なWeb-DB連携例
http://tamosblog.wordpress.com/2012/10/26/sinatra/
Sinatra-ActiverecordでDB情報を取得する
Rubyメインのapp.rb
で、DB情報をソートして、datatype=abc
のレコードのうち、created_at
とdata
の2つを取得する。取得した情報をインスタンス変数に格納する。最後にindex.erb
を呼び出す。そんなに複雑なことはしない。
require 'rubygems'
require 'sinatra'
require 'sinatra/reloader'
require 'active_record'
# ActiverecordのORマッピング
# ENV['DATABASE_URL']はお使いの環境に合わせましょう
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
class Sensor < ActiveRecord::Base
end
# Sinatraメイン
get '/' do
@sensor_abc = Sensor.order("id").where(:datatype => "abc").select("created_at", "data")
erb :index
end
JavascriptでHighchartsのdataを生成する
index.erbの中のJavascriptの中で、インスタンス変数を使ってデータを取得する。
Highchartsのdataは2次元配列を指定する必要があるので、Array関数に代入してく。
Highchartsを時系列表示は、時間をUTC指定にする必要があるので注意。ここでは、getTime()を使ってUTCにしている。あと、時間降順に並べないとバグります。降順はruby側でソートしている。
<script type="text/javascript">
・・・
var val = new Array();
<% @sensor_abc.each do |abc|%>
var ary = new Array();
var time = new Date("<%= abc.created_at %>");
ary.push(time.getTime()); // getTimeでUTCに変換
ary.push(<%= abc.data.to_f %>); // Stringデータを実数にする。
val.push(ary);
<%end%>
・・・
</script>
Highchartsでグラフ化する
Highchartsのソースは以下。seriesのdataに上記で作成したval変数を指定すればOK。
x軸の時間をローカルタイムにしています。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="./highcharts.js"></script>
<script type="text/javascript">
var chart;
// 表示をUTCからローカルタイムにする
Highcharts.setOptions({
global : {
useUTC : false
}
});
function draw() {
// グラフオプションを指定
var options = {
// 出力先を指定
chart : {
renderTo : "container",
type : "line",
backgroundColor : "white"
},
// タイトルを指定
title : {
text : "abcデータ"
},
// x軸のラベルを指定
xAxis : {
type : 'datetime',
title : {
text : "時間"
}
},
// y軸のラベルを指定
yAxis : {
title : {
text : "数値"
}
},
// データ系列を作成
series : [{
name : "data",
data : val
}]
};
// グラフを作成
chart = new Highcharts.Chart(options);
}
// ページがロードされた後に、グラフを出力する
document.body.onload = draw();
</script>
お世話になったサイト
-
Javascriptプログラミング解説Dateオブジェクト
http://www.crystal-creation.com/web-app/tech/programming/javascript/grammar/object/date.htm#no115 -
放射線量可視化(4):Highcharts JSのグラフによる可視化
http://fromto.cc/hosokawa/diary/2011/20111204-home2/ -
highcharts x軸を日付にするノウハウ
http://blogs.yahoo.co.jp/montabross/67516003.html