前回までの記事ラズパイでIoT 温度データを取得してMySQLに保存しよう。でラズパイにつながった温度センサーHDC1000のデータがMySQLに保存されるようになりました。
今回はそのMySQLのデータをグラフに表示してみたいと思います。家のパソコンやスマホから見ることができますよー(*´艸`*)
どんな感じで表示されるの?
温度データって今の温度じゃなくて変化が重要ですよね。
そのとき調べたい日中の変化だったり、1週間の変化だったり、月の変化だったり。。
ということで、Day(1日前からの変化)、Week(1週間の変化)、1ヶ月の変化(28日分の変化)のグラフを切り替えて表示できるようにしました。プルダウンメニューから変化させます。
1週間と1ヶ月の変化は、1日単位で表示させるのでmin/ave/maxを表示できるようにしました。
※サンプル画像は古いデータがないので1週間分のデータは表示されていません。
こんな感じのグラフがパソコンやスマホから取得できるのって便利ですよね。
ラズパイはLinuxなのでPHPサーバーとして動かすことができるのでこんなこともできちゃうんです。
実装方法をご紹介していきますね(ง°̀ロ°́)ง
ラズパイを使ったグラフ表示のサンプルプログラム
JavaScriptからMySQLのデータを取得するようにPHPに要求し、PHPはJavaSciptの要求に従いデータを返します。JavaScript側ではGoogle Chartsのグラフ描画機能を使うので、そのデータフォーマットでPHPがデータを返すようにするようにしています。
順に見ていきましょう。
Google Chartsでグラフを表示する
グラフの表示にはGoogle Chartsを使用しました。JavaScriptはクライアントサイドなのでインタラクティブにデータの表示ができるからです。
Google Chartsでグラフを表示させる前にCreateJsonFromMySql.phpでラズパイにMySQLからデータを取得しJSONフォーマットでグラフデータを返すように要求しています。
CreateJsonFromMySql.phpについては後ほどサンプルプログラムをご紹介します。
JavaScript側はPHPから受け取ったグラフデータをGoogle Chartsのインスタンスに渡すことで実際にグラフが描画されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<html> <head> <!--Load the AJAX API--> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script type="text/javascript"> // Load the Visualization API and the piechart package. google.charts.load('current', {'packages':['corechart']}); // Set a callback to run when the Google Visualization API is loaded. google.charts.setOnLoadCallback(drawChart); function drawChart(showspan = 'Day') { var urlWithGetData = "CreateJsonFromMySql.php?range=" + showspan + "&target=temperature"; var jsonData = $.ajax({ url: urlWithGetData, dataType: "json", async: false }).responseText; // Create our data table out of JSON data loaded from server. var data = new google.visualization.DataTable(jsonData); // Instantiate and draw our chart, passing in some options. var chart = new google.visualization.LineChart(document.getElementById('chart_div')); var options = { title: 'Temperature report from HDC1000 deployed in RP', curveType: 'function', height: 500, hAxis: {title: 'Time', showTextEvery: 1, slantedText: true, slantedTextAngle: 90}, vAxis: {title: 'Temperature[degC]'}, legend: { position: 'bottom' } }; chart.draw(data, options); } </script> </head> <body> <!--Div that will hold the Line chart--> <form> <select name="showspan" onchange="drawChart(this.value)"> <option value="Day" selected="">Day</option> <option value="Week">Week</option> <option value="Month">Month</option> </select> </form> <div id="chart_div"></div> </body> </html> |
JavaScriptから呼ばれるPHPのプログラム
JavaScript側からDay/Week/Monthどの状態でデータが欲しいのかを$_GET[‘range’]で取得しています。
また、JavaScript側からは何のMySQLデータが欲しいのかを$_GET[‘target’]で取得しています。将来的には温度以外の他のデータも取得したいので少し汎用的にしました。
データはGoogle Chartsのグラフが要求するJSONデータで返しています。
DbManager.php / Encode.phpはJavaScriptからPHPにクエリ情報を渡す方法は?ラズパイで試しました。でご紹介していますので参考にしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
<?php require_once 'DbManager.php'; require_once 'Encode.php'; // Retrieve from $_GET $range = (isset($_GET['range'])) ? $_GET['range'] : 'Day'; $target = (isset($_GET['target'])) ? $_GET['target'] : 'temperature'; // Day unit will handle data as 'Time' unit from table $unit = ($range == 'Day') ? 'time' : 'date'; // initialization $arryCol = array(); $arryRow = array(); // Prepare for data format. switch ($range){ case 'Month': case 'Week': // Date range for query. Week/Month $dayRange = ($range == 'Week') ? 7 : 28; $qryDate = strtotime("-{$dayRange} day"); // Variables to shorten recoring date $substrStart = 5; $substrLen = 5; // Column definition for GoogleCharts Table array_push($arryCol, MakeColElement('Date', 'string')); array_push($arryCol, MakeColElement('min', 'number')); array_push($arryCol, MakeColElement('ave', 'number')); array_push($arryCol, MakeColElement('max', 'number')); break; case 'Day': $days = date("Y-m-d", strtotime("-1 day")); // Variables to shorten recoring date $substrStart = 0; $substrLen = 5; // Column definition for GoogleCharts Table array_push($arryCol, MakeColElement('Time', 'string')); array_push($arryCol, MakeColElement('Value', 'number')); break; default: break; } try { $db = GetDb(); switch ($range){ case 'Month': case 'Week': for ($day=0; $day <$dayRange ; $day++) { // prepare query string. min/ave/max will be targeted. $days = date("Y-m-d", $qryDate); $qry = "select date, min($target), avg($target), max($target) from tb_hdc1000 where Date like '$days'"; $stt = $db->prepare($qry); // call $stt->execute(); $row = $stt->fetch(PDO::FETCH_ASSOC); $rsltToJson = array(substr($row[$unit],$substrStart,$substrLen), round($row['min('.$target.')'],2), round($row['avg('.$target.')'],2), round($row['max('.$target.')'],2)); array_push($arryRow, MakeRowElements($rsltToJson)); // + 1 day for next day. $qryDate = strtotime("+1 day", $qryDate); } break; case 'Day': $qry = "select time, temperature from tb_hdc1000 where Date >= '$days'"; $stt = $db->prepare($qry); $stt->execute(); // loop till fetch all aquired values and store. while($row = $stt->fetch(PDO::FETCH_ASSOC)) { $rsltToJson = array(substr($row[$unit],$substrStart,$substrLen), $row[$target]); array_push($arryRow, MakeRowElements($rsltToJson)); } break; } // delete $db = NULL; } catch (PDOEXception $e) { die("connection error:{$e->getMessage()}"); } // return created Json format. echo ReturnGoogleChartsTable($arryCol, $arryRow); function MakeColElement ($label, $type) { return '{"id":"","label":"'.$label.'"'.',"pattern":"","type":"'.$type.'"'.'}'; } function MakeRowElements ($arry) { $ret = '{"c":['; for ($i=0; $i < count($arry); $i++) { $element = '{"v":"'.$arry[$i].'","f":null}'; $ret .= ($i != (count($arry)-1)) ? $element.',' : $element ; } $ret = $ret.']}'; return $ret; } function ReturnGoogleChartsTable ($arryCol, $arryRow) { $ret = '{ "cols": [' .ConnectArry($arryCol) .'],' .'"rows": [' .ConnectArry($arryRow) .'] }'; return $ret; } function ConnectArry($arry) { $ret = ''; for ($i=0; $i < count($arry); $i++) { $ret .= ($i != (count($arry)-1)) ? $arry[$i].',' : $arry[$i] ; } return $ret; } ?> |
あとはJavaScript側のコードを呼び出してあげればOKです(*´罒`*)
おわりに
パソコンやスマホからラズパイに保存されているMySQLのデータをPHP経由で表示させる方法をご紹介しました。
Google Chartsはパワフルなのでかなり実用的な感じになったのかなーと思います
(◍•ᴗ•◍)♡ ✧*。
記事を読んでいただいてありがとうございます。この記事がいいなと思ったら下記のSNSボタンのクリックをお願いします。励みになります😁