chart.html 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <!doctype html>
  2. <html>
  3. <head>
  4. <title>ISP Speed Chart</title>
  5. <link rel="shortcut icon" href="favicon.ico">
  6. <script src="chartjs/Chart.min.js"></script>
  7. <script src="chartjs/utils.js"></script>
  8. <style>
  9. canvas {
  10. -moz-user-select: none;
  11. -webkit-user-select: none;
  12. -ms-user-select: none;
  13. position: relative;
  14. flex-grow: 1;
  15. min-height: 0;
  16. width: 100%;
  17. height:100%;
  18. }
  19. div {
  20. width:100%;
  21. height:100%;
  22. }
  23. body {
  24. background: #ffffff;
  25. color: #000000;
  26. transition: background 0.3s, color 0.3s;
  27. }
  28. /* 深色模式适配 */
  29. @media (prefers-color-scheme: dark) {
  30. body {
  31. background: #121212;
  32. color: #e0e0e0;
  33. }
  34. canvas {
  35. background: #1e1e1e;
  36. }
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <div>
  42. <canvas id="canvas"></canvas>
  43. </div>
  44. <script>
  45. var color = Chart.helpers.color;
  46. async function mainfunc() {
  47. var color = Chart.helpers.color;
  48. //console.log(color)
  49. var datareq = await fetch('backend/results-api.php');
  50. //console.log(datareq)
  51. var dataraw = await datareq.text();
  52. //console.log(dataraw)
  53. try {
  54. dataraw = JSON.parse(dataraw);
  55. } catch {
  56. alert("Can't get data");
  57. return 0;
  58. }
  59. data_sorted = {};
  60. for (const data of dataraw["data"]) {
  61. let data_isp = data["isp"].split(" ").length > 1 ? data["isp"].split(" ")[0] + " " + data["isp"].split(" ")[1] : data["isp"];
  62. if (data_isp in data_sorted) {
  63. data_sorted[data_isp] = data_sorted[data_isp].concat([data])
  64. } else {
  65. data_sorted[data_isp] = [data]
  66. }
  67. }
  68. let datasets = []
  69. for (const isp of Object.keys(data_sorted)) {
  70. let ispdata_chart = {
  71. label: isp,
  72. data: []
  73. }
  74. for (const ispdata of data_sorted[isp]) {
  75. let [t_h, t_m, t_s] = ispdata["created"].split(" ")[1].split(":");
  76. ispdata_chart["data"] = ispdata_chart["data"].concat([{
  77. x: t_h * 1.0 + t_m / 60 + t_s / 3600,
  78. y: ispdata["dspeed"],
  79. label: ispdata
  80. }]);
  81. }
  82. datasets = datasets.concat([ispdata_chart])
  83. }
  84. datasets = datasets.sort((a, b) => a["data"].length < b["data"].length ? 1 : -1);
  85. for (const [i, data] of datasets.entries()) {
  86. if (i === 0) {
  87. datasets[i]["borderColor"] = window.chartColors["red"];
  88. datasets[i]["backgroundColor"] = color(datasets[i]["borderColor"]).alpha(0.9).rgbString()
  89. } else if (i === 1) {
  90. datasets[i]["borderColor"] = "rgb(12, 176, 42)";
  91. datasets[i]["backgroundColor"] = color(datasets[i]["borderColor"]).alpha(0.9).rgbString()
  92. } else if (i === 2) {
  93. datasets[i]["borderColor"] = "rgb(2, 104, 219)";
  94. datasets[i]["backgroundColor"] = color(datasets[i]["borderColor"]).alpha(0.9).rgbString()
  95. }
  96. else{
  97. datasets[i]["borderColor"] = window.chartColors["gray"];;
  98. datasets[i]["backgroundColor"] = color(window.chartColors["gray"]).alpha(0.1).rgbString()
  99. }
  100. }
  101. console.log(datasets);
  102. scatterChartData = {
  103. datasets: datasets
  104. }
  105. var ctx = document.getElementById('canvas').getContext('2d');
  106. window.myScatter = Chart.Scatter(ctx, {
  107. data: scatterChartData,
  108. options: {
  109. title: {
  110. display: true,
  111. text: 'ISP Speed Chart'
  112. },
  113. tooltips: {
  114. mode: 'nearest',
  115. callbacks: {
  116. title: function(TooltipItem, data){
  117. // console.log(TooltipItem);
  118. // console.log(data);
  119. // console.log(data["datasets"][TooltipItem[0]["datasetIndex"]]["label"])
  120. return data["datasets"][TooltipItem[0]["datasetIndex"]]["label"]
  121. },
  122. label:function(TooltipItem, data){
  123. return data["datasets"][TooltipItem["datasetIndex"]]["data"][TooltipItem["index"]]["label"]["isp"];
  124. },
  125. footer: function(TooltipItem, data){
  126. // console.log(TooltipItem);
  127. // console.log(data);
  128. displaydata = data["datasets"][TooltipItem[0]["datasetIndex"]]["data"][TooltipItem[0]["index"]]["label"];
  129. showdict = {
  130. location: displaydata["addr"],
  131. Download: displaydata["dspeed"],
  132. Upload: displaydata["uspeed"],
  133. Ping: displaydata["ping"],
  134. Jitter: displaydata["jitter"],
  135. IP: displaydata["ip"],
  136. Time: displaydata["created"],
  137. // ISP: displaydata["isp"],
  138. };
  139. let showtext = ""
  140. for (const k of Object.keys(showdict)){
  141. showtext += k + ": " + showdict[k] + "\n";
  142. }
  143. return showtext
  144. },
  145. },
  146. footerFontStyle: 'normal'
  147. },
  148. scales: {
  149. yAxes: [{
  150. type: 'linear',
  151. position: 'bottom',
  152. ticks: {
  153. userCallback: function(tick) {
  154. return tick.toString() + 'Mbps';
  155. },
  156. },
  157. scaleLabel: {
  158. labelString: 'Speed',
  159. display: true,
  160. }
  161. }],
  162. xAxes: [{
  163. type: 'linear',
  164. ticks: {
  165. userCallback: function(tick) {
  166. return tick.toString() + ':00';
  167. },
  168. beginAtZero: true,
  169. stepSize: 3,
  170. max: 24
  171. },
  172. scaleLabel: {
  173. labelString: 'Time',
  174. display: true
  175. }
  176. }]
  177. },
  178. responsive: true,
  179. maintainAspectRatio: false
  180. }
  181. });
  182. }
  183. window.onload = function() {
  184. mainfunc();
  185. };
  186. </script>
  187. </body>
  188. </html>