LoginSignup
78

More than 3 years have passed since last update.

posted at

updated at

【リアルタイムチャートをChart.js で作ってみた。】

グラフ(折れ線グラフ、棒グラフ、レーダチャートなど)でも同じように設定できちゃう。

参考にしたサイト

リアルタイムチャート作成で参考 : chartjs-plugin-streaming
グラフの初期値設定で参考 : stackoverflow
Mysqlへの接続方法で参考 :PHPでPDOを使ってMySQLに接続

ファイルダウンロード先・公式ドキュメント

ダウンロード先:http://www.chartjs.org
ドキュメント:https://misc.0o0o.org/chartjs-doc-ja/

使い方

test.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<canvas id="myChart"></canvas>

<!-- ライブラリを読み込む -->
<script type="text/javascript" src="../js/moment.js"></script>
<script type="text/javascript" src="../js/Chart.js"></script>
<script type="text/javascript" src="../js/chartjs-plugin-streaming.js"></script>
<script>
var ctx = document.getElementById('myChart').getContext('2d');

var chart = new Chart(ctx, {

  type: 'line',

  data: {

    datasets: [{

      data: []

    }, {

      data: []

    }]

  },

  options: {

    scales: {

      xAxes: [{

        type: 'realtime'     <!-- Barメソッドを実行すれば棒グラフ -->

      }]

    }

  }

});
</script>
</body>
</html>

画面上に以下のようなリアルタイムで動くグラフを確認できるはず。
確認できればあとは自分で反映させたいデータを入れ込んでいくだけ。

スクリーンショット 2018-07-04 11.58.53.png

今回はリアルタイムでデータベースから情報を反映してチャート化するグラフを作ってみます。
グラフの設定はグラフ全体のオプション(option)を渡して canvas で描画するので、
試しにオプション内に以下のように追記して適当な値をグラフで表示。

test.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>

<canvas id="myChart"></canvas>


<script type="text/javascript" src="../js/moment.js"></script>
<script type="text/javascript" src="../js/Chart.js"></script>
<script type="text/javascript" src="../js/chartjs-plugin-streaming.js"></script>
<script>
var ctx = document.getElementById('myChart').getContext('2d');

var chart = new Chart(ctx, {
    type: 'line',               
    data: {
        datasets: [{
            data: []            
        }]
    },
    options: {
        scales: {
            xAxes: [{
                type: 'realtime'    
            }]
        },
        plugins: {
            streaming: {            
                duration: 20000,    
                refresh: 1000,      
                delay: 1000,        
                frameRate: 30,      
                pause: false,       


                onRefresh: function(chart) {
                    chart.data.datasets[0].data.push({
                        x: Date.now(),
                        y: Math.random() * 100
                    });
                }
            }
        }
    }
});
</script>
</body>
</html>

値をランダムに出力して描画し続けるグラフができます。
スクリーンショット 2018-07-04 13.09.34.png

次にデータベースから特定の値のみを取得して表示できるようにします。
ちなみに今回は関数を使ってAjax(非同期通信)でデータを取得します。

get_data()関数を使って sample.php ファイルへデータを取得しにいく。(Ajax通信)

test.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>

<canvas id="myChart"></canvas>


<script type="text/javascript" src="../js/moment.js"></script>
<script type="text/javascript" src="../js/Chart.js"></script>
<script type="text/javascript" src="../js/chartjs-plugin-streaming.js"></script>
<script>
var ctx = document.getElementById('myChart').getContext('2d');

var chart = new Chart(ctx, {
    type: 'line',               
    data: {
        datasets: [{
            data: []            
        }]
    },
    options: {
        scales: {
            xAxes: [{
                type: 'realtime'    
            }]
        },
        plugins: {
            streaming: {            
                duration: 20000,    
                refresh: 1000,      
                delay: 1000,        
                frameRate: 30,      
                pause: false,       


                onRefresh: function(chart) {
                    chart.data.datasets[0].data.push({
                        x: Date.now(),
                        y: get_data()
                    });
                }
            }
        }
    }
});

let a = 0;
function get_data(){
    $.ajax({
        url: "sample.php",
        method: "POST",
    })
    .done(function(data){
        a = data;
        console.log(data);
        $('#len').html(data);
    });
    return a;
}
</script>
</body>
</html>

sample.php からデータベースへアクセスして任意のデータを取得する。

get_students_id.php
<?php

//DB接続関数(PDO)
function db_con(){
  $dbname='sc_project';
  try {$pdo = new PDO('mysql:dbname=sc_project;host=mysql;charset=utf8mb4','ユーザー名','パスワード',
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,]);
      } catch (PDOException $e) {
    exit('DbConnectError:'.$e->getMessage());
  }
  return $pdo;
}



$stmt = $pdo->prepare("SELECT "カラム名" from "テーブル名" where "時刻保持カラム" > current_timestamp + interval -5 SECOND"); //現在時刻から -5秒 のデータのみ取得
$stmt->execute();
$res = $stmt->fetchAll();


echo count ($res);



?>

get_students_id.phpファイルの中で記述されている SELECT文は、現在時刻から -5秒内にあるデータを取得しています。(今回は毎1秒データベースへSELECT通信してます)

今回は仕様上チャートグラフの中にマイナス表示はしたくありませんが、
現状、チャートグラフに何も値が入っていない状態には以下のように出力されてしまいます。

スクリーンショット 2018-07-04 14.58.38.png

これじゃ困る。
っていうか困ったので、基準値を 0 として設定します。

オプション内に y軸 の基準値として"beginAtZero: true"を記述。

test.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>

<canvas id="myChart"></canvas>


<script type="text/javascript" src="../js/moment.js"></script>
<script type="text/javascript" src="../js/Chart.js"></script>
<script type="text/javascript" src="../js/chartjs-plugin-streaming.js"></script>
<script>

var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
    type: 'line',               
    data: {
        datasets: [{
            data: [],            
            label: 'Unknowグラフ',
        }]
    },
    options: {
        scales: {
            xAxes: [{
                type: 'realtime', 
            }],
            yAxes: [
        {
          ticks: {
            beginAtZero: true,
            min: 0,
            max: 100
          }
        }
      ]
        },
        plugins: {
            streaming: {            
                duration: 20000,    
                refresh: 1000,      
                delay: 1000,        
                frameRate: 30,      
                pause: false,       

                onRefresh: function(chart) {
                    chart.data.datasets[0].data.push({
                        x: Date.now(),
                        y: get_data()
                    });
                }
            }
        }
    }
});
//初期値0
let a = 0;
function get_data(){
    //sample.phpの数字を取りに行く
    $.ajax({
        url: "sample.php",
        method: "POST",
    })
    .done(function(data){
        a = data;
    });
    //数字を返す
    return a;
}

</script>
</body>
</html>

はい、できました。
スクリーンショット 2018-07-04 15.15.48.png

あとは、データベースにチャートとして出力させたいデータを入力しちゃえばOKです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
78