読者です 読者をやめる 読者になる 読者になる

opamp_sando's blog

クソザコが割りと適当なことを書くためにある備忘録です。あとたまに普通の日記も書きます

JSONデータを取得してhighcharts.jsを使った簡単なグラフ表示

ということでPostgreSQLのテーブルデータを取得してJSONにした後、highcharts.jsを使ってブラウザ上にグラフを書いてみる。
あんまり関係ないかもしれないが、一応書いておくとWebサーバーにはlighttpdを使用し、phpは5.6.14を使用。PostgreSQLは9.4.5。

使うデータについて

以下のようなデータがPostgreSQLに入っている。何のデータかというと、自室の室温データである。
DB設計には疎いのでどうなのかわからないが、主キーはtimeになっている。timeは見ての通りタイムゾーンなしのtimestamp型でvalueはreal型。

> select time,value from temp;
            time            |  value  
----------------------------+---------
 2015-10-22 08:00:01.296074 |  24.385
 2015-10-22 09:00:01.261014 |  24.385
 2015-10-22 10:00:01.242508 |  24.385
 2015-10-22 11:00:01.410739 |  24.385
 2015-10-22 12:00:01.417759 |  24.385
 2015-10-22 13:00:01.439453 |  24.385
 2015-10-22 14:00:01.42983  |  24.385
 2015-10-22 15:00:01.418064 |  24.385
 2015-10-22 16:00:01.289062 |  24.385
 2015-10-22 17:00:01.174973 |  24.385
 2015-10-22 18:00:01.471065 |  24.385
 2015-10-22 19:00:02.50445  | 24.0131
 2015-10-22 20:00:01.269953 | 22.7116
 2015-10-22 21:00:01.169438 | 22.7116
 2015-10-22 22:00:01.165112 | 22.7116
 2015-10-22 23:00:01.165317 | 22.7116
 2015-10-23 00:00:01.170476 | 22.7116
 2015-10-23 01:00:01.171914 | 23.6413
 2015-10-23 02:00:01.16925  |  24.385
 2015-10-23 03:00:01.163014 | 25.8725
 2015-10-23 04:00:01.164198 |   27.36
 2015-10-23 05:00:01.168548 | 26.6162
 2015-10-23 06:00:01.167475 | 25.8725
 2015-10-23 07:00:01.166736 | 25.8725
 2015-10-23 08:00:01.170006 |  24.385
 2015-10-23 09:00:01.165955 | 25.8725
 2015-10-23 10:00:01.166001 | 23.6413
 2015-10-23 11:00:01.170822 |  24.385
 2015-10-23 12:00:01.197592 |  24.385
 2015-10-23 13:00:01.338696 | 24.5709
 2015-10-23 14:00:01.416016 | 25.8725
 2015-10-23 15:00:01.398318 | 25.8725
 2015-10-23 16:00:01.400292 | 25.8725
 2015-10-23 17:00:01.250604 | 25.8725
 2015-10-23 18:00:01.185805 | 24.9428

データの取得とJSONへの変換

まず、これをHTML中のJavaScriptから呼び出せるようにするためにphpを使ってJSONに変換する。
timestampはJavaScriptのDateを使って処理しやすいようにSELECTの時点でUNIX時間に変換しておく。

<?php
$dsn = 'pgsql:dbname=db host=postgres port=5432';
$user = 'username';
$password = 'password';

try{
    $dbh = new PDO($dsn, $user, $password);
    $sql = 'SELECT extract(epoch from time) AS unixtime,value from temp';
    $stt = $dbh->query($sql);
    $tempData = array();
    while($row = $stt->fetch(PDO::FETCH_ASSOC)){
        $tempData[]=array(
            'time'=>$row['unixtime'],
            'temp'=>$row['value'],
        );
    }
    header('Content-type: application/json');
    echo json_encode($tempData);
}catch (PDOException $e){
    print('Error:'.$e->getMessage());
    die();
}

$dbh = null;

これを適当なディレクトリに配置すると、このphpにアクセスすることで先ほどのテーブルの情報がすべてJSONに変換されて取得できる。先ほどのテーブルは1時間毎の室温なので、長期保存すると膨大な量になり重たくなることが考えられるので、必要なら取得量をSQLを発行する時点で抑えればいい気がする。(今回はしないけど)

グラフを書く

highcharts.jsを使ってグラフを書く。htmlはindex.htmlなど適当な名前で先ほど作ったphpと同じディレクトリに入れた。

<!DOCTYPE html>
<html>
  <head>
    <title>室温情報</title>
    <meta charset="utf-8">
    <script type="text/javascript" src="public/js/jquery.min.js"></script>
    <script src="public/js/highcharts/highcharts.js"></script>
    <script src="public/js/highcharts/modules/data.js"></script>
    <script src="public/js/highcharts/modules/exporting.js"></script>
    <script type="text/javascript" src="public/js/index.js"></script>
  </head>
  <body>
    <div id="screen"></div>
  </body>
</html>

次に、htmlから読み込むJavaScriptファイルは以下のように書いて、public/js/index.jsに入れた。なお、highcharts.jsなど必要なJavaScriptファイルも同じようにpublic/js/以下に保存している。

Highcharts.setOptions({
    global : {
        useUTC : false
    }
});

$(document).ready(function(){
    httpObj = new XMLHttpRequest();
    httpObj.open("get", "data.php", true);

    httpObj.onload = function(){
        var rtn = [];
        var tdata = JSON.parse(this.responseText);
        tdata.forEach(function(i){
            rtn.push([(new Date(Number(i.time) * 1000)).getTime(),Number(i.temp)]);
        });

        var chart = new Highcharts.Chart({
            chart :{renderTo: "screen",type: "line"},
            title :{text: "自宅の気温データ"},
            xAxis: {
                type: 'datetime',
                title: {text: "日時"}
            },
            yAxis :{title: {text: "気温[℃]"},min: -10,max: 50},
            series: [{name: "室温", data: rtn}]
        });
    };
    httpObj.send(null);
});

最終的なファイル配置はこんな感じ

.
├── data.php
├── index.html
└── public
    └── js
        └── index.js

終わり

これで表示したらこんな感じ

f:id:opamp_sando:20151024040153p:plain

とりあえず最低限度表示させてみた。もうすこしいろいろ凝りたいところではある。 でもまだデータ自体が少ないので一ヶ月くらいしてデータが集まった頃にまた改良するかな

ちなみに自分が見れればいいと思ってFirefoxくらいでしか動作確認してないのでどの程度他のブラウザでも動くかは不明。

参考資料

http://www.highcharts.com/

http://qiita.com/fantm21/items/891192da1a095e94c9e1

http://www.phpbook.jp/tutorial/pdo/index4.html

http://d.hatena.ne.jp/litt/20070904/p1

http://www.openspc2.org/reibun/javascript2/JSON/parse/0001/

http://blogs.yahoo.co.jp/montabross/67516003.html

http://so-zou.jp/web-app/tech/programming/javascript/grammar/object/date.htm

Firefox ブラウザ無料ダウンロード