graph.html 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <!DOCTYPE html>
  2. <html lang="en" xml:lang="en">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <title>Data Graph</title>
  6. <script type="text/javascript" src='plotly-basic-2.18.2.min.js?v=$COMMIT_HASH'></script>
  7. <script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
  8. <script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
  9. <script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
  10. <style>
  11. h1 {font-size: 2em;}
  12. h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
  13. h3 {font-size: 1.2em;}
  14. p {font-size: 1em;}
  15. body {
  16. font-family: Arial, Helvetica, sans-serif;
  17. }
  18. select {
  19. padding: 3px 5px;
  20. display: inline-block;
  21. border: 1px solid #ccc;
  22. font-size: 16px;
  23. margin-right: 10px;
  24. min-width: 100px;
  25. vertical-align: middle;
  26. }
  27. .button {
  28. padding: 5px 10px;
  29. width: 160px;
  30. font-size: 16px;
  31. }
  32. </style>
  33. <script>
  34. function run() {
  35. datefile = document.getElementById("datafiles").value;
  36. numbername = document.getElementById("numbers").value;
  37. showRrelativeValues = document.getElementById("showRrelativeValues").checked;
  38. //alert("Auslesen: " + datefile + " " + numbername);
  39. _domainname = getDomainname();
  40. fetch(_domainname + '/fileserver/log/data/' + datefile)
  41. .then(response => {
  42. // handle the response
  43. if (response.status == 404) {
  44. firework.launch("No data available for " + dateString, 'warning', 10000);
  45. }
  46. response.text()
  47. .then( result => {
  48. var lines = result.split("\n");
  49. var traceValue = { x: [], y: [], type: 'scatter', line: {width: 6}, name: 'Value'};
  50. var tracePreValue = { x: [], y: [], type: 'scatter', line: {width: 2}, name: 'Previous Value', visible: 'legendonly'};
  51. var traceChangeRate = { x: [], y: [], type: 'bar', yaxis: 'y2', opacity: 0.2, name: 'Change Rate'};
  52. var traceChangeAbsolute = { x: [], y: [], type: 'bar', yaxis: 'y2', opacity: 0.2, name: 'Change Absolute', visible: 'legendonly'};
  53. var timex = 1;
  54. for (let line of lines) {
  55. {
  56. //console.log(line);
  57. if (line.split(",")[1] == numbername)
  58. {
  59. var value = line.split(",")[3];
  60. var preValue = line.split(",")[4];
  61. var changeRate = line.split(",")[5];
  62. var changeAbsolute = line.split(",")[6];
  63. var time = line.split(",")[0];
  64. //console.log("> "+time+" "+value+"\n");
  65. traceValue.x.push(time);
  66. /* Catch empty fields */
  67. if (value == "" || isNaN(value)) {
  68. value = NaN;
  69. }
  70. if (preValue == "" || isNaN(preValue)) {
  71. preValue = NaN;
  72. }
  73. if (changeRate == "" || isNaN(changeRate)) {
  74. changeRate = NaN;
  75. }
  76. if (changeAbsolute == "" || isNaN(changeAbsolute)) {
  77. changeAbsolute = NaN;
  78. }
  79. traceValue.y.push(value);
  80. tracePreValue.y.push(preValue);
  81. traceChangeRate.y.push(changeRate);
  82. traceChangeAbsolute.y.push(changeAbsolute);
  83. }
  84. }
  85. }
  86. /* If the value trace starts with NaN, replace all those Nans with the first valid value */
  87. var firstNonNaNIndex = 0;
  88. for(var i = 0; i < traceValue.y.length; i++) {
  89. firstNonNaNIndex = i;
  90. if (! isNaN(traceValue.y[i])) {
  91. break;
  92. }
  93. }
  94. if (firstNonNaNIndex == (traceValue.y.length - 1)) {
  95. console.log("No data available for 'value'!");
  96. }
  97. else if (firstNonNaNIndex > 0) { // Replace all leading NaN with the first valid value
  98. console.log("The first leading values have all just NaN, replacing them with the value of",
  99. traceValue.y[firstNonNaNIndex], "at", traceValue.x[firstNonNaNIndex], "(Index:", firstNonNaNIndex, ")");
  100. for(var i = 0; i < firstNonNaNIndex; i++) {
  101. traceValue.y[i] = traceValue.y[firstNonNaNIndex];
  102. }
  103. }
  104. // Copy time to all traces
  105. tracePreValue.x = traceValue.x;
  106. traceChangeRate.x = traceValue.x;
  107. traceChangeAbsolute.x = traceValue.x;
  108. //console.log(traceValue.y);
  109. var offsetValue = traceValue.y[0];
  110. var offsetPreValue = tracePreValue.y[0];
  111. traceValue.connectgaps = true;
  112. if (showRrelativeValues) {
  113. traceValue.y.forEach(function(part, index, arr) {
  114. arr[index] = arr[index] - offsetValue;
  115. });
  116. tracePreValue.y.forEach(function(part, index, arr) {
  117. arr[index] = arr[index] - offsetPreValue;
  118. });
  119. }
  120. // console.log(traceValue.x)
  121. var data = [traceValue, tracePreValue, traceChangeRate, traceChangeAbsolute];
  122. var layout = {
  123. showlegend: true,
  124. colorway: ['green', 'black', 'blue', 'black'],
  125. yaxis: {title: 'Value'},
  126. yaxis2: {
  127. title: 'Change',
  128. overlaying: 'y',
  129. side: 'right'
  130. },
  131. margin: {
  132. l: 70,
  133. r: 70,
  134. b: 50,
  135. t: 40,
  136. pad: 4
  137. },
  138. legend: {
  139. x: 0.02,
  140. y: 0.97,
  141. xanchor: 'left'
  142. }
  143. };
  144. document.getElementById("chart").innerHTML = "";
  145. Plotly.newPlot('chart', data, layout, {displayModeBar: true});
  146. });
  147. }).catch((error) => {
  148. // handle the error
  149. console.log(error);
  150. });
  151. }
  152. </script>
  153. <link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
  154. <script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
  155. <script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
  156. </head>
  157. <body>
  158. <h2>Data Graph</h2>
  159. <div id='chart'><p>Loading...<br></p></div>
  160. Number sequence:
  161. <select id="numbers" onchange="run();"></select>
  162. Day:
  163. <select id="datafiles" onchange="run();"></select>
  164. <input type="checkbox" id="showRrelativeValues" onclick = 'run();' unchecked ><label for="showRrelativeValues">Show relative values</label><br><br>
  165. <button class="button" onclick="run();">Refresh</button>
  166. <button class="button" onClick="window.location.href = 'data.html?v=$COMMIT_HASH'">Show Data Viewer</button>
  167. <button class="button" onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show Data Files</button>
  168. <script>
  169. function WriteModelFiles()
  170. {
  171. list_data = getDATAList();
  172. var _indexDig = document.getElementById("datafiles");
  173. while (_indexDig.length)
  174. _indexDig.remove(0);
  175. for (var i = list_data.length - 1; i >= 0; --i)
  176. {
  177. var optionDig = document.createElement("option");
  178. var text = list_data[i];
  179. optionDig.text = text;
  180. optionDig.value = list_data[i];
  181. _indexDig.add(optionDig);
  182. }
  183. }
  184. function WriteNumbers()
  185. {
  186. list_data = getNUMBERSList();
  187. var _indexDig = document.getElementById("numbers");
  188. while (_indexDig.length)
  189. _indexDig.remove(0);
  190. for (var i = 0; i < list_data.length; ++i)
  191. {
  192. var optionDig = document.createElement("option");
  193. var text = list_data[i];
  194. optionDig.text = text;
  195. optionDig.value = list_data[i];
  196. _indexDig.add(optionDig);
  197. }
  198. }
  199. WriteModelFiles();
  200. WriteNumbers();
  201. function Refresh() {
  202. setTimeout (function() {
  203. run();
  204. Refresh();
  205. }, 300000);
  206. }
  207. run();
  208. Refresh();
  209. </script>
  210. </body>
  211. </html>