150 lines
4.1 KiB
TypeScript
150 lines
4.1 KiB
TypeScript
import Chart, { ChartOptions } from 'chart.js/auto';
|
|
import zoomPlugin from 'chartjs-plugin-zoom';
|
|
|
|
Chart.register(zoomPlugin);
|
|
|
|
const lastDay = new Date();
|
|
lastDay.setDate(lastDay.getDate() - 1);
|
|
const lastHours = `${lastDay.getFullYear()}-${lastDay.getMonth() + 1}-${String(lastDay.getDate()).padStart(2, '0')}`;
|
|
|
|
const options = {
|
|
plugins: {
|
|
zoom: {
|
|
zoom: {
|
|
drag: { enabled: true },
|
|
mode: 'x',
|
|
},
|
|
},
|
|
},
|
|
} satisfies ChartOptions<'line'>;
|
|
|
|
const speedChart = new Chart(document.querySelector('#speed-chart') as any, {
|
|
type: 'line',
|
|
data: { datasets: [] },
|
|
options,
|
|
});
|
|
|
|
const latencyChart = new Chart(document.querySelector('#latency-chart') as any, {
|
|
type: 'line',
|
|
data: { datasets: [] },
|
|
options,
|
|
});
|
|
|
|
const durationChart = new Chart(document.querySelector('#duration-chart') as any, {
|
|
type: 'line',
|
|
data: { datasets: [] },
|
|
options,
|
|
});
|
|
|
|
document.querySelectorAll('.reset-chart').forEach(el => {
|
|
const chartCanvas = getCanvas(el);
|
|
if (!chartCanvas) return;
|
|
el.addEventListener('click', () => Chart.getChart(chartCanvas)?.resetZoom('none'));
|
|
});
|
|
|
|
document.querySelectorAll('.last-hours').forEach(el => {
|
|
const canvasId = getCanvas(el)?.id;
|
|
if (!canvasId) return;
|
|
el.addEventListener('click', () => {
|
|
switch (canvasId) {
|
|
case 'speed-chart':
|
|
return updateSpeedChart(lastHours);
|
|
case 'latency-chart':
|
|
return updateLatencyChart(lastHours);
|
|
case 'duration-chart':
|
|
return updateDurationChart(lastHours);
|
|
default:
|
|
return console.warn('[WARNING] `canvasId` not recognized', canvasId);
|
|
}
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('.complete-data').forEach(el => {
|
|
const canvasId = getCanvas(el)?.id;
|
|
if (!canvasId) return;
|
|
el.addEventListener('click', () => {
|
|
switch (canvasId) {
|
|
case 'speed-chart':
|
|
return updateSpeedChart();
|
|
case 'latency-chart':
|
|
return updateLatencyChart();
|
|
case 'duration-chart':
|
|
return updateDurationChart();
|
|
default:
|
|
return console.warn('[WARNING] `canvasId` not recognized', canvasId);
|
|
}
|
|
});
|
|
});
|
|
|
|
updateSpeedChart(lastHours);
|
|
updateLatencyChart(lastHours);
|
|
updateDurationChart(lastHours);
|
|
|
|
function updateSpeedChart(from?: string, to?: string): void {
|
|
fetch('/data/speed' + toUrlQuery(from, to))
|
|
.then(res => res.json())
|
|
.then(json => {
|
|
const downloadData = json.map(j => j.DLSpeed / 125000.0); // Mbps
|
|
const uploadData = json.map(j => j.ULSpeed / 125000.0); // Mbps
|
|
const time = json.map(j => j.CreationDate);
|
|
|
|
speedChart.data = {
|
|
labels: time,
|
|
datasets: [
|
|
{ data: downloadData, label: 'Download' },
|
|
{ data: uploadData, label: 'Upload' },
|
|
],
|
|
};
|
|
speedChart.update('none');
|
|
speedChart.resetZoom('none');
|
|
});
|
|
}
|
|
|
|
function updateLatencyChart(from?: string, to?: string): void {
|
|
fetch('/data/latency' + toUrlQuery(from, to))
|
|
.then(res => res.json())
|
|
.then(json => {
|
|
const latencyData = json.map(j => j.Latency / 1000000); // ms
|
|
const maxLatencyData = json.map(j => j.MaxLatency / 1000000); // ms
|
|
const minLatencyData = json.map(j => j.MinLatency / 1000000); // ms
|
|
const jitterData = json.map(j => j.Jitter / 1000000); // ms
|
|
const time = json.map(j => j.CreationDate);
|
|
|
|
latencyChart.data = {
|
|
labels: time,
|
|
datasets: [
|
|
{ data: latencyData, label: 'Latency' },
|
|
{ data: maxLatencyData, label: 'max Latency' },
|
|
{ data: minLatencyData, label: 'min Latency' },
|
|
{ data: jitterData, label: 'Jitter' },
|
|
],
|
|
};
|
|
latencyChart.update('none');
|
|
latencyChart.resetZoom('none');
|
|
});
|
|
}
|
|
|
|
function updateDurationChart(from?: string, to?: string): void {
|
|
fetch('/data/duration' + toUrlQuery(from, to))
|
|
.then(res => res.json())
|
|
.then(json => {
|
|
const durationData = json.map(j => j.TestDuration / 1000000000); // sec
|
|
const time = json.map(j => j.CreationDate);
|
|
|
|
durationChart.data = {
|
|
labels: time,
|
|
datasets: [{ data: durationData, label: 'Duration' }],
|
|
};
|
|
durationChart.update('none');
|
|
durationChart.resetZoom('none');
|
|
});
|
|
}
|
|
|
|
function toUrlQuery(from?: string, to?: string): string {
|
|
return `?from=${from ?? ''}&to=${to ?? ''}`;
|
|
}
|
|
|
|
function getCanvas(element: Element): HTMLCanvasElement | undefined {
|
|
return element.closest('.wrapper')?.querySelector('canvas') ?? undefined;
|
|
}
|