お知らせ
2018年11月5日
Socket.IOとChart.jsでグラフの非同期更新をしてみた時の話。
どうも皆さんこんにちは。
今回はSocket.ioとChart.jsで簡単に作成したグラフの非同期更新をご紹介しようと思います。
非同期通信といえばAjaxのイメージですが、Ajaxでグラフの非同期更新を行う場合、定期的にサーバに対してリクエストを送り、データが更新されているかチェックする必要があります。ですが、それではグラフの更新にラグが発生してしまいます。
そんな時に見つけたのがこのSocket.io
Socket.ioは簡単に説明するとクライアントとサーバとのコネクションを常につなぎ続け、サーバに更新がかかった際にサーバ側からクライアントにデータを送ることのできるため、Ajaxと違い定期的にリクエストを送り続ける必要がないため、タイムラグが発生しづらくリアルタイム性を上げることのできるnode.jsのライブラリです。
今回は15秒間隔でサーバからクライアントに対してランダムな数値を送り、リアルタイムでグラフの更新を行うものを作成いたしました。
app.js
var app = require("express")(); var http = require("http").Server(app); var io = require("socket.io")(http); app.get("/", function(req, res){ res.sendFile(__dirname + "/index.html"); }); // コネクションの確立 io.on("connection", function(socket){ // 15秒ごとにクライアントにランダムな数値を送る setInterval(() => { let obj ={ num: Math.floor(Math.random() * 101) } // クライアント側に送るためのfunction io.emit("graph update", obj); }, 15000); }); http.listen(3000, function(){ console.log("listening on *:3000"); });
index.html
<!doctype html> <html> <head> <title>グラフテスト</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script> <script src="//code.jquery.com/jquery-3.2.1.min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.min.js"></script> <script src="//cdn.socket.io/socket.io-1.4.5.js"></script> </head> <body> <div class="left" > <canvas id="canvas" height="150" ></canvas> </div> </body> </html>
index.js
const socket = io.connect(); var ctx = document.getElementById("canvas").getContext("2d"); // グラフの作成 var myChart = new Chart(ctx, { type: "bar", data: { labels: [], datasets: [{ label: "of Votes", data: [], backgroundColor: [ "rgba(255, 99, 132, 0.2)", "rgba(54, 162, 235, 0.2)", "rgba(255, 206, 86, 0.2)", "rgba(75, 192, 192, 0.2)";, "rgba(153, 102, 255, 0.2)", "rgba(255, 159, 64, 0.2)"; ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); $(() => { // サーバから値を受け取った時の処理 socket.on("graph update", (datas) => { // 現在時刻の取得 const time = moment(); const outputTime = time.format("HH : mm : ss"); // 追加するデータのラベルに時間を付与 myChart.data.labels.push(outputTime); // グラフにデータを追加 myChart.data.datasets[0].data.push(datas.num); // グラフの表示更新 myChart.update(); }) });
画面イメージ
上記をソースコードだけで画面を切り替えることなく、グラフに新しいデータを追加することができます。
今回はSocket.ioをグラフの更新に使用しましたが、他にも色々な活用方法がありますので皆さまも一度触ってみるのはいかがでしょうか。
ちなみに今回このグラフはcanvasタグで表示されていますが、canvasをcssでサイズ指定する場合、canvasに描画される物が引き伸ばされるためサイズ変更をする際は注意が必要です。