canvasにグラフ描画

2022/08/10


データとグラフ

Ni-MH電池の放電特性を測定した。
定時測定をしたいが測定時間が長くなる。測定はADコンバータつきマイクロコントローラ(ESP32-WROOM-32E)にまかせて、結果はデータロガー的に逐次データベースに保存した。(ただ、ADコンバータがかなり怪しくて電圧値がズレているらしい。)
データベースに格納されているデータをもとにつぎのことをしたい。 サーバサイドプログラミングで解決すべきものだが、準備段階としてローカルで処理する。
表形式出力はPostgreSQLの機能(-Hオプション)として用意されている。PostgreSQLはtableタグ部分(<table>から</table>まで)をつくるので、その前後(<!DOCTYPE>,<head><body>)はこちらで用意する。(なくてもどうかなるので省略可能)
$DBUSERNAMEはデータベースユーザ名、$PGHOSTNAMEはPostgreSQLを動かしているマシン名(またはIPアドレス)を環境変数として用意するのがよいだろう。 コマンドラインからPostgreSQLに指示してbattery20220810.htmlに出力した。
#htmlファイル(battery20220810.html)に保存
cat <<EOF> battery20220810.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>TABLE (PostgreSQL)</title>
</head>
<body>
EOF
 psql -d xxxx -U $DBUSERNAME -h $PGHOSTNAME -H -c "SELECT to_char(dt, 'YYYY/MM/DD HH24:MI:SS') AS dt, to_char(v2, '0.000') AS \"CH3\",  to_char(v1, '0.000') AS \"CH2\" FROM battery WHERE dt BETWEEN '2022-08-10 08:35:00' AND '2022-08-10 15:00:00' ORDER BY dt"  >> battery20220810.html
cat <<EOF>> battery20220810.html
</body>
</html>
EOF

測定したデータは{dt:時刻, CH3:電圧値, CH2:電圧値}のようなセット(連想記憶)として20220810.jsに保存する。
#js用に加工して20220810.jsに保存
echo "table=[" > 20220810.js
 psql -d xxxx -U $DBUSERNAME -h $PGHOSTNAME -c "SELECT '{dt:''' || to_char(dt, 'YYYY/MM/DD HH24:MI:SS') || ''', CH3:' || v2 || ', CH2:' || v1 ||'},' FROM battery WHERE dt BETWEEN '2022-08-10 08:35:00' AND '2022-08-10 17:00:00' ORDER BY dt"  >> 20220810.js
echo "];" >> 20220810.js
この20220810.jsはエラーになるので修正する。
table=[
                     ?column?                      	//この行を削除
---------------------------------------------------	//この行を削除
 {dt:'2022/08/10 08:35:10', CH3:1.304, CH2:2.641},

=== 途中省略 ===

 {dt:'2022/08/10 14:27:23', CH3:0.128, CH2:1.017},
 {dt:'2022/08/10 14:28:24', CH3:2.772, CH2:2.567},
 {dt:'2022/08/10 14:33:23', CH3:0, CH2:0},		//行末の,を削除
(287 行)						//この行を削除
							//(空白行 削除してもよい)
];
ECMAScriptでグラフを描画するため、描画ページ(graph.html)に<canvas>要素を用意する。
graph.htmlgraph.js20220810.js
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>ECMAScript canvas Graph</title>
<script src="./20220810.js"></script>
<script src="./graph.js"></script>
</head>

<body>
<canvas name="graph" id="mycanvas" width="840" height="700" style="background-color:#FFEEC0;">
</canvas>
<script>
var canvas = document.getElementById('mycanvas');
var Xmin=0, Xmax=Math.floor(canvas.width/100)*100;
var Ymin=canvas.height, Ymax=50;
var X0=100, Y0=Ymin-Ymax;
 graph();
</script>
</body>
</html>
/*-- 20220810.jsはこのような感じで --*/
table=[
 {dt:'2022/08/10 08:35:10', CH3:1.304, CH2:2.641},
  ...
 {dt:'2022/08/10 15:33:23', CH3:0.000, CH2:0.000}
];

グラフ領域レイアウト

数学座標系は原点が左下だが、canvas座標系の原点は左上になるで注意が必要。
100ピクセル間隔で目盛線を入れる。

graph

描画

描画したグラフが途中で切れているが、間違いではない。
9:56から10:39、12:32から12:43はマイクロコントローラとデータベースとの接続が切れていたため、データが欠落している。

HTMLクイックリファレンス (http://www.htmq.com/js/)

とほほのJavaScriptリファレンス (https://www.tohoho-web.com/js/index.htm)

TCD WordPress Theme 【JavaScriptの基本】配列メソッド -繰り返し( https://tcd-theme.com/2021/07/javascript-array-foreach.html)

IT求人ナビ JavaScriptでforEachメソッドを使用する方法( https://it-kyujin.jp/article/detail/1539/)