Help us understand the problem. What is going on with this article?

DBに保存されているデータをHighchartsを使っていい感じのグラフを表示する

More than 5 years have passed since last update.

目的

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_atdataの2つを取得する。取得した情報をインスタンス変数に格納する。最後にindex.erbを呼び出す。そんなに複雑なことはしない。

app.rb
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側でソートしている。

index.erb(抜粋)
<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軸の時間をローカルタイムにしています。

index.erb(抜粋)
<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>

こんな感じになります。
Highchartsグラフ.png

お世話になったサイト

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away