actuator_chart_P.html 17 KB

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