sensor_chart_DO.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Smart Coffee - Chart</title>
  6. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  7. <!-- 新 Bootstrap4 核心 CSS 文件 -->
  8. <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
  9. <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
  10. <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  11. <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
  12. <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
  13. <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
  14. <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
  15. <!--
  16. <script src="../static/js/sign_in.js"></script>
  17. <link rel="stylesheet" href="../static/css/sign_in.css">
  18. -->
  19. <!--引入 echarts.js -->
  20. <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
  21. <script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js'></script>
  22. <script src='https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js'></script>
  23. <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/0.3.0/Chart.Zoom.min.js"></script>
  24. <script language="JavaScript">
  25. var tank = '{{tank}}';
  26. var sensor_name = '{{sensor_name}}';
  27. var tid = '{{tid}}';
  28. $(document).ready(function(){
  29. $("#coffee_title_pc").text(tank + tid + ' 乾燥出料儲豆槽感測器圖表');
  30. $("#coffee_title_phone").text(tank + tid + ' 感測器');
  31. });
  32. </script>
  33. </head>
  34. <body>
  35. <div id="wrapper">
  36. <div id="coffee_header">
  37. <!-- 匯入共同使用的 header.html 內容 -->
  38. {% include 'header.html' %}
  39. </div>
  40. <!--
  41. <a href="/dry">返回乾燥槽介面</a>
  42. <div style="text-align: center; margin-top:0px; font-size: 24px;">
  43. Smart Coffee
  44. </div>
  45. -->
  46. <!--
  47. <form action="/chart/SHT11_Temp/{{tid}}" method="post">
  48. <div class="form-group" style="margin-top: 30px; text-align: center;">
  49. -->
  50. <table style="margin: auto; border:3px gray solid; width: 80%; text-align: center;" cellpadding="6" rules='ALL'>
  51. <tr>
  52. <td>
  53. {% if tid == '2'%}
  54. <select id="tank_num">
  55. <option value="DI1">乾燥出料儲豆槽_1</option>
  56. <option value="DI2" selected>乾燥出料儲豆槽_2</option>
  57. </select>
  58. {% else %}
  59. <select id="tank_num">
  60. <option value="DI1" selected>乾燥出料儲豆槽_1</option>
  61. <option value="DI2">乾燥出料儲豆槽_2</option>
  62. </select>
  63. {% endif %}
  64. <select id="sensors">
  65. <option value="UltraSonic">乾燥出料儲豆槽咖啡生豆高度</option>
  66. </select>
  67. </td>
  68. </tr>
  69. <tr>
  70. <td>
  71. 時間間隔:
  72. <select name="time-interval" class="text-right">
  73. <option value="month">逐月</option>
  74. <option value="day">逐日</option>
  75. <option value="hour">逐時</option>
  76. </select>
  77. &nbsp;
  78. <!--
  79. 從&nbsp;
  80. <input type="datetime-local" name="sensor_starttime" id="sensor_starttime" value={{starttime}}>
  81. &nbsp;到&nbsp;
  82. <input type="datetime-local" name="sensor_endtime" id="sensor_endtime" value={{endtime}}>
  83. &nbsp;為止
  84. -->
  85. <span>從</span>
  86. <label for="querydate-start"></label><input id="querydate-start" type="date">
  87. <span>到</span>
  88. <label for="querydate-end"></label><input id="querydate-end" type="date">
  89. <span>為止</span>
  90. </td>
  91. </tr>
  92. <tr>
  93. <td>
  94. 資料類型:
  95. <label><input type="checkbox" name="data-type" value="max">最大值</label>
  96. <label><input type="checkbox" name="data-type" value="avg">平均值</label>
  97. <label><input type="checkbox" name="data-type" value="min">最小值</label>
  98. <br>
  99. </td>
  100. </tr>
  101. <tr>
  102. <td>
  103. <!--
  104. <button type="submit" name="charting">繪製圖表</button>
  105. <button type="submit" onclick="" id="btn_save_chart" style="display: none;">儲存圖表</button>
  106. -->
  107. <input type="button" value="查詢" onclick="ShowInfo()">
  108. <input type="button" value="匯出" onclick="downloadFile()">
  109. <input type="button" value="刪除" onclick="">
  110. <script>
  111. function ShowInfo() {
  112. // 取得桶號、感測器名稱
  113. tid = document.getElementById("tank_num").value
  114. console.log('tid: ' + tid)
  115. sensor_name = document.getElementById("sensors").value
  116. console.log('sensor_name: ' + sensor_name)
  117. // 數據整理
  118. Echart(sensor_name, tid)
  119. // 顯示圖表
  120. };
  121. function downloadFile() {
  122. tid = document.getElementById("tank_num").value
  123. sensor_name = document.getElementById("sensors").value
  124. //藉型別陣列建構的 blob 來建立 URL
  125. let fileName = "ChartData_" + tid + "_" + sensor_name + ".csv";
  126. //"\ufeff"解決打開CSV中文亂碼問題
  127. const data = "\ufeff" + getData();
  128. let blob = new Blob([data], {
  129. type: 'text/csv,charset=UTF-8'
  130. });
  131. var href = URL.createObjectURL(blob);
  132. // 從 Blob 取出資料
  133. var link = document.createElement("a");
  134. document.body.appendChild(link);
  135. link.href = href;
  136. link.download = fileName;
  137. link.click();
  138. };
  139. //所有資料函數
  140. function getData() {
  141. var header = "日期," + data_name + "\n";
  142. var data = "";
  143. var length = all_datetime.length;
  144. for (var i = 0; i < length; i++) {
  145. data = data + all_datetime[i] + ',' + all_data[i] + '\n';
  146. };
  147. return header + data;
  148. };
  149. //最大最小平均資料函數
  150. function getData() {
  151. var header = data_name + "\n日期,";
  152. if (max_data) {
  153. console.log(max_data);
  154. header = header + "最大值,";
  155. };
  156. if (avg_data) {
  157. header = header + "平均值,";
  158. };
  159. if (min_data) {
  160. header = header + "最小值,";
  161. };
  162. header = header + "\n";
  163. var data = "";
  164. var length = xAxis_data.length;
  165. for (var i = 0; i < length; i++) {
  166. data = data + xAxis_data[i] + ',';
  167. if (max_data) {
  168. data = data + max_data[i] + ',';
  169. };
  170. if (avg_data) {
  171. data = data + avg_data[i] + ',';
  172. };
  173. if (min_data) {
  174. data = data + min_data[i] + ',';
  175. };
  176. data = data + '\n';
  177. };
  178. return header + data;
  179. };
  180. </script>
  181. </td>
  182. </tr>
  183. <tr>
  184. <td>
  185. <!--
  186. <img src={{ url }}>
  187. -->
  188. <div id="" class="show-info" style="text-align: center;">
  189. <center>
  190. <div class="show-chart" style="height: 420px; width: 100%; text-align: center;">
  191. 圖表
  192. </div>
  193. </center>
  194. </div>
  195. </td>
  196. </tr>
  197. </table>
  198. <!--
  199. </div>
  200. </form>
  201. -->
  202. <div id="coffee_footer">
  203. <!-- 匯入共同使用的 footer.html 內容 -->
  204. {% include 'footer.html' %}
  205. </div>
  206. </div>
  207. </body>
  208. <script>
  209. var all_datetime = 0; // 所有資料時間 ?
  210. var all_data = 0; // 所有感測器數據 ?
  211. var data_name = 0; // 感測器名稱 // "溫溼度"
  212. var xAxis_data = 0; // x 軸資料
  213. var max_data = 0; //
  214. var min_data = 0; //
  215. var avg_data = 0; //
  216. function Echart(sensor_name, tid) {
  217. // Echart(sensor_name, tid)
  218. //將echarts圖形銷毀
  219. $(".show-chart").removeAttr("_echarts_instance_").empty();
  220. // Rita:sensor 與 data_name 重複
  221. // var sensor = evt.substring(2);
  222. if (!$("input[value=avg]").prop('checked') && !$("input[value=min]").prop('checked') && !$("input[value=max]").prop('checked')) {
  223. alert("請至少選擇一種資料類型!");
  224. return false;
  225. };
  226. if ($("#querydate-start").val() == '' || $("#querydate-end").val() == '') {
  227. alert("請選擇日期範圍!");
  228. return false;
  229. };
  230. //基於準備好的dom,初始化echarts例項
  231. var myChart = echarts.init(document.getElementsByClassName('show-chart')[0]); // class="col-10 show-chart"
  232. var date_start = $("#querydate-start").val();
  233. var date_end = $("#querydate-end").val();
  234. var avg = 0;
  235. var max = 0;
  236. var min = 0;
  237. var time_interval = $("select[name=time-interval]").val();
  238. var legend = new Array();
  239. var color = new Array();
  240. var series = new Array();
  241. if ($("input[value=max]").prop('checked')) {
  242. max = 1;
  243. legend.push("最大值");
  244. color.push("#1e88e5"); // 水藍色
  245. };
  246. if ($("input[value=avg]").prop('checked')) {
  247. avg = 1;
  248. legend.push("平均值");
  249. color.push("#43a047"); // 草綠色
  250. };
  251. if ($("input[value=min]").prop('checked')) {
  252. min = 1;
  253. legend.push("最小值");
  254. color.push("#e64a19"); // 橘紅色
  255. };
  256. var json = {
  257. 'tid': tid,
  258. 'sensor_name': sensor_name,
  259. 'avg': avg,
  260. 'max': max,
  261. 'min': min,
  262. 'time-interval': time_interval,
  263. 'date-start': date_start,
  264. 'date-end': date_end
  265. };
  266. console.log('json___' +
  267. 'tid: ' + tid +
  268. 'sensor_name: ' + sensor_name +
  269. 'avg: ' + avg +
  270. 'max: ' + max +
  271. 'min: ' + min +
  272. 'time-interval: ' + time_interval +
  273. 'date-start: ' + date_start +
  274. 'date-end: ' + date_end
  275. )
  276. $.get('/history_data_new', json, function (resText) {
  277. if (resText.max) {
  278. var max_series = {
  279. 'name': '最大值',
  280. 'type': 'scatter',
  281. 'data': resText.max.map(function (item) { return item[1]; }),
  282. 'itemStyle': { 'normal': { 'lineStyle': { 'color': '#1e88e5' } } },
  283. };
  284. series.push(max_series); // 把上面的 dict 加入 series array 內
  285. xAxis_data = resText.max.map(function (item) { return item[0]; });
  286. max_data = resText.max.map(function (item) { return item[1]; });
  287. };
  288. if (resText.avg) {
  289. var avg_series = { 'name': '平均值', 'type': 'scatter', 'data': resText.avg.map(function (item) { return item[1]; }), 'itemStyle': { 'normal': { 'lineStyle': { 'color': '#43a047' } } }, };
  290. series.push(avg_series);
  291. xAxis_data = resText.avg.map(function (item) { return item[0]; });
  292. console.log('xAxis_data: ' + xAxis_data) // 2021-07-09 10:00:00,2021-07-20 09:00:00,2021-07-22 15:00:00,2021-07-26 15:00:00,2021-07-26 16:00:00
  293. avg_data = resText.avg.map(function (item) { return item[1]; });
  294. console.log('avg_data: ' + avg_data) // 91.0,98.0,11.0,15.2,30.5
  295. };
  296. if (resText.min) {
  297. var min_series = { 'name': '最小值', 'type': 'scatter', 'data': resText.min.map(function (item) { return item[1]; }), 'itemStyle': { 'normal': { 'lineStyle': { 'color': '#e64a19' } } }, };
  298. series.push(min_series);
  299. xAxis_data = resText.min.map(function (item) { return item[0]; }); // all
  300. min_data = resText.min.map(function (item) { return item[1]; }); // min
  301. };
  302. //獲取日期內所有數據
  303. all_datetime = resText.all.map(function (item) { return item[0]; }); // all
  304. all_data = resText.all.map(function (item) { return item[1]; });
  305. //指定圖表的配置項和資料
  306. option = {
  307. title: {
  308. text: '', // 'Data History'
  309. left: '1%'
  310. },
  311. tooltip: {
  312. trigger: 'axis'
  313. },
  314. color: color,
  315. legend: {
  316. data: legend,
  317. },
  318. xAxis: {
  319. data: xAxis_data,
  320. },
  321. yAxis: {
  322. splitLine: {
  323. show: true,
  324. lineStyle: {
  325. color: ''
  326. }
  327. }
  328. },
  329. toolbox: {
  330. show: true,
  331. feature: {
  332. dataZoom: {
  333. yAxisIndex: 'none'
  334. },
  335. dataView: { readOnly: false },
  336. magicType: { type: ['line', 'bar'] },
  337. restore: {},
  338. saveAsImage: {}
  339. }
  340. },
  341. dataZoom: [{
  342. startValue: '2021-01-01'
  343. }, {
  344. type: 'inside'
  345. }],
  346. series: series,
  347. /*
  348. series: [
  349. {
  350. name: '最大值',
  351. type: 'line',
  352. data: resText.max.map(function (item) {
  353. return item[1];
  354. }),
  355. itemStyle: {
  356. normal: {
  357. lineStyle: {
  358. color: '#1e88e5'
  359. }
  360. }
  361. },
  362. },
  363. {
  364. name: '平均值',
  365. type: 'line',
  366. data: [20.0, 20.0, 20.0, 20.0, 20.0, 20.0],
  367. itemStyle: {
  368. normal: {
  369. lineStyle: {
  370. color: '#43a047'
  371. }
  372. }
  373. },
  374. },
  375. {
  376. name: '最小值',
  377. type: 'line',
  378. data: [15.0, 15.0, 15.0, 15.0, 15.0, 15.0],
  379. itemStyle: {
  380. normal: {
  381. lineStyle: {
  382. color: '#e64a19'
  383. }
  384. }
  385. }
  386. },
  387. ]
  388. */
  389. };
  390. console.log('SHOW myChart')
  391. //使用剛指定的配置項和資料顯示圖表
  392. myChart.setOption(option);
  393. }, 'json');
  394. } // Echart(sensor_name, tid)
  395. </script>
  396. </html>