HuJK пре 4 година
родитељ
комит
e60022778c
5 измењених фајлова са 425 додато и 2 уклоњено
  1. 2 2
      backend/config.php
  2. 137 0
      chart.html
  3. 133 0
      chart_linear.html
  4. 6 0
      chartjs/Chart.min.js
  5. 147 0
      chartjs/utils.js

+ 2 - 2
backend/config.php

@@ -3,7 +3,7 @@
 /**
  * 最多保存多少条测试记录
  */
-const MAX_LOG_COUNT = 100;
+const MAX_LOG_COUNT = 100000;
 
 /**
  * IP运营商解析服务:(1) ip.sb | (2) ipinfo.io (如果1解析ip异常,请切换成2)
@@ -13,4 +13,4 @@ const IP_SERVICE = 'ip.sb';
 /**
  * 是否允许同一IP记录多条测速结果
  */
-const SAME_IP_MULTI_LOGS = false;
+const SAME_IP_MULTI_LOGS = true;

+ 137 - 0
chart.html

@@ -0,0 +1,137 @@
+<!doctype html>
+<html>
+
+<head>
+        <title>ISP Speed Chart</title>
+    <script src="chartjs/Chart.min.js"></script>
+        <script src="chartjs/utils.js"></script>
+        <style>
+        canvas {
+                -moz-user-select: none;
+                -webkit-user-select: none;
+                -ms-user-select: none;
+        }
+        </style>
+</head>
+
+<body>
+        <div style="width:75%">
+                <canvas id="canvas"></canvas>
+        </div>
+        <script>
+                var color = Chart.helpers.color;
+
+async function mainfunc() {
+    var color = Chart.helpers.color;
+    console.log(color)
+    var datareq = await fetch('backend/results-api.php');
+    console.log(datareq)
+    var dataraw = await datareq.text();
+    console.log(dataraw)
+    try {
+        dataraw = JSON.parse(dataraw);
+    } catch {
+        alert("Can't get data");
+        return 0;
+    }
+
+    data_sorted = {};
+    for (const data of dataraw["data"]) {
+        let data_isp = data["isp"].split(" ").length > 1 ? data["isp"].split(" ")[0] + " " + data["isp"].split(" ")[1] : data["isp"];
+        if (data_isp in data_sorted) {
+            data_sorted[data_isp] = data_sorted[data_isp].concat([data])
+        } else {
+            data_sorted[data_isp] = [data]
+        }
+    }
+    let datasets = []
+    for (const isp of Object.keys(data_sorted)) {
+        let ispdata_chart = {
+            label: isp,
+            data: []
+        }
+        for (const ispdata of data_sorted[isp]) {
+            let [t_h, t_m, t_s] = ispdata["created"].split(" ")[1].split(":");
+            ispdata_chart["data"] = ispdata_chart["data"].concat([{
+                x: t_h * 1.0 + t_m / 60 + t_s / 3600,
+                y: ispdata["dspeed"],
+				label: ispdata
+            }]);
+        }
+        datasets = datasets.concat([ispdata_chart])
+    }
+    datasets = datasets.sort((a, b) => a["data"].length < b["data"].length ? 1 : -1);
+    for (const [i, data] of datasets.entries()) {
+        let pcolor = "gray"
+        if (i === 0) {
+            pcolor = "red";
+        } else if (i === 1) {
+            pcolor = "green"
+        } else if (i === 2) {
+            pcolor = "blue"
+        }
+        datasets[i]["borderColor"] = window.chartColors[pcolor];
+        datasets[i]["backgroundColor"] = pcolor !== "gray" ? color(window.chartColors[pcolor]).alpha(0.9).rgbString() : color(window.chartColors[pcolor]).alpha(0.1).rgbString()
+    }
+    console.log(datasets);
+    scatterChartData = {
+        datasets: datasets
+    }
+
+    var ctx = document.getElementById('canvas').getContext('2d');
+    window.myScatter = Chart.Scatter(ctx, {
+        data: scatterChartData,
+        options: {
+            title: {
+                display: true,
+                text: 'ISP Speed Chart'
+            },
+			scales: {
+					yAxes: [{
+						type: 'logarithmic',
+						position: 'bottom',
+						ticks: {
+							userCallback: function(tick) {
+								var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick))));
+								if (remain === 1 || remain === 2 || remain === 5) {
+									return tick.toString() + 'Mbps';
+								}
+								return '';
+							},
+						},
+						scaleLabel: {
+							labelString: 'Speed',
+							display: true,
+						}
+					}],
+					xAxes: [{
+						type: 'linear',
+						ticks: {
+							userCallback: function(tick) {
+								return tick.toString() + ':00';
+							}
+						},
+						scaleLabel: {
+							labelString: 'Time',
+							display: true
+						}
+					}]
+				}
+        }
+    });
+
+
+}
+
+
+
+                window.onload = function() {
+                        mainfunc();
+                };
+
+
+        </script>
+</body>
+
+</html>
+

+ 133 - 0
chart_linear.html

@@ -0,0 +1,133 @@
+<!doctype html>
+<html>
+
+<head>
+        <title>ISP Speed Chart</title>
+    <script src="chartjs/Chart.min.js"></script>
+        <script src="chartjs/utils.js"></script>
+        <style>
+        canvas {
+                -moz-user-select: none;
+                -webkit-user-select: none;
+                -ms-user-select: none;
+        }
+        </style>
+</head>
+
+<body>
+        <div style="width:75%">
+                <canvas id="canvas"></canvas>
+        </div>
+        <script>
+                var color = Chart.helpers.color;
+
+async function mainfunc() {
+    var color = Chart.helpers.color;
+    console.log(color)
+    var datareq = await fetch('backend/results-api.php');
+    console.log(datareq)
+    var dataraw = await datareq.text();
+    console.log(dataraw)
+    try {
+        dataraw = JSON.parse(dataraw);
+    } catch {
+        alert("Can't get data");
+        return 0;
+    }
+
+    data_sorted = {};
+    for (const data of dataraw["data"]) {
+        let data_isp = data["isp"].split(" ").length > 1 ? data["isp"].split(" ")[0] + " " + data["isp"].split(" ")[1] : data["isp"];
+        if (data_isp in data_sorted) {
+            data_sorted[data_isp] = data_sorted[data_isp].concat([data])
+        } else {
+            data_sorted[data_isp] = [data]
+        }
+    }
+    let datasets = []
+    for (const isp of Object.keys(data_sorted)) {
+        let ispdata_chart = {
+            label: isp,
+            data: []
+        }
+        for (const ispdata of data_sorted[isp]) {
+            let [t_h, t_m, t_s] = ispdata["created"].split(" ")[1].split(":");
+            ispdata_chart["data"] = ispdata_chart["data"].concat([{
+                x: t_h * 1.0 + t_m / 60 + t_s / 3600,
+                y: ispdata["dspeed"],
+				label: ispdata
+            }]);
+        }
+        datasets = datasets.concat([ispdata_chart])
+    }
+    datasets = datasets.sort((a, b) => a["data"].length < b["data"].length ? 1 : -1);
+    for (const [i, data] of datasets.entries()) {
+        let pcolor = "gray"
+        if (i === 0) {
+            pcolor = "red";
+        } else if (i === 1) {
+            pcolor = "green"
+        } else if (i === 2) {
+            pcolor = "blue"
+        }
+        datasets[i]["borderColor"] = window.chartColors[pcolor];
+        datasets[i]["backgroundColor"] = pcolor !== "gray" ? color(window.chartColors[pcolor]).alpha(0.9).rgbString() : color(window.chartColors[pcolor]).alpha(0.1).rgbString()
+    }
+    console.log(datasets);
+    scatterChartData = {
+        datasets: datasets
+    }
+
+    var ctx = document.getElementById('canvas').getContext('2d');
+    window.myScatter = Chart.Scatter(ctx, {
+        data: scatterChartData,
+        options: {
+            title: {
+                display: true,
+                text: 'ISP Speed Chart'
+            },
+			scales: {
+					yAxes: [{
+						type: 'linear',
+						position: 'bottom',
+						ticks: {
+							userCallback: function(tick) {
+									return tick.toString() + 'Mbps';
+							},
+						},
+						scaleLabel: {
+							labelString: 'Speed',
+							display: true,
+						}
+					}],
+					xAxes: [{
+						type: 'linear',
+						ticks: {
+							userCallback: function(tick) {
+								return tick.toString() + ':00';
+							}
+						},
+						scaleLabel: {
+							labelString: 'Time',
+							display: true
+						}
+					}]
+				}
+        }
+    });
+
+
+}
+
+
+
+                window.onload = function() {
+                        mainfunc();
+                };
+
+
+        </script>
+</body>
+
+</html>
+

Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
chartjs/Chart.min.js


+ 147 - 0
chartjs/utils.js

@@ -0,0 +1,147 @@
+'use strict';
+
+window.chartColors = {
+	red: 'rgb(255, 99, 132)',
+	orange: 'rgb(255, 159, 64)',
+	yellow: 'rgb(255, 205, 86)',
+	green: 'rgb(75, 192, 192)',
+	blue: 'rgb(54, 162, 235)',
+	purple: 'rgb(153, 102, 255)',
+	grey: 'rgb(201, 203, 207)'
+};
+
+(function(global) {
+	var MONTHS = [
+		'January',
+		'February',
+		'March',
+		'April',
+		'May',
+		'June',
+		'July',
+		'August',
+		'September',
+		'October',
+		'November',
+		'December'
+	];
+
+	var COLORS = [
+		'#4dc9f6',
+		'#f67019',
+		'#f53794',
+		'#537bc4',
+		'#acc236',
+		'#166a8f',
+		'#00a950',
+		'#58595b',
+		'#8549ba'
+	];
+
+	var Samples = global.Samples || (global.Samples = {});
+	var Color = global.Color;
+
+	Samples.utils = {
+		// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
+		srand: function(seed) {
+			this._seed = seed;
+		},
+
+		rand: function(min, max) {
+			var seed = this._seed;
+			min = min === undefined ? 0 : min;
+			max = max === undefined ? 1 : max;
+			this._seed = (seed * 9301 + 49297) % 233280;
+			return min + (this._seed / 233280) * (max - min);
+		},
+
+		numbers: function(config) {
+			var cfg = config || {};
+			var min = cfg.min || 0;
+			var max = cfg.max || 1;
+			var from = cfg.from || [];
+			var count = cfg.count || 8;
+			var decimals = cfg.decimals || 8;
+			var continuity = cfg.continuity || 1;
+			var dfactor = Math.pow(10, decimals) || 0;
+			var data = [];
+			var i, value;
+
+			for (i = 0; i < count; ++i) {
+				value = (from[i] || 0) + this.rand(min, max);
+				if (this.rand() <= continuity) {
+					data.push(Math.round(dfactor * value) / dfactor);
+				} else {
+					data.push(null);
+				}
+			}
+
+			return data;
+		},
+
+		labels: function(config) {
+			var cfg = config || {};
+			var min = cfg.min || 0;
+			var max = cfg.max || 100;
+			var count = cfg.count || 8;
+			var step = (max - min) / count;
+			var decimals = cfg.decimals || 8;
+			var dfactor = Math.pow(10, decimals) || 0;
+			var prefix = cfg.prefix || '';
+			var values = [];
+			var i;
+
+			for (i = min; i < max; i += step) {
+				values.push(prefix + Math.round(dfactor * i) / dfactor);
+			}
+
+			return values;
+		},
+
+		months: function(config) {
+			var cfg = config || {};
+			var count = cfg.count || 12;
+			var section = cfg.section;
+			var values = [];
+			var i, value;
+
+			for (i = 0; i < count; ++i) {
+				value = MONTHS[Math.ceil(i) % 12];
+				values.push(value.substring(0, section));
+			}
+
+			return values;
+		},
+
+		color: function(index) {
+			return COLORS[index % COLORS.length];
+		},
+
+		transparentize: function(color, opacity) {
+			var alpha = opacity === undefined ? 0.5 : 1 - opacity;
+			return Color(color).alpha(alpha).rgbString();
+		}
+	};
+
+	// DEPRECATED
+	window.randomScalingFactor = function() {
+		return Math.round(Samples.utils.rand(-100, 100));
+	};
+
+	// INITIALIZATION
+
+	Samples.utils.srand(Date.now());
+
+	// Google Analytics
+	/* eslint-disable */
+	if (document.location.hostname.match(/^(www\.)?chartjs\.org$/)) {
+		(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+		(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+		m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+		})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+		ga('create', 'UA-28909194-3', 'auto');
+		ga('send', 'pageview');
+	}
+	/* eslint-enable */
+
+}(this));

Неке датотеке нису приказане због велике количине промена