const chartInstances = {}; async function loadPieChart(endpoint, canvasId, legendId) { try { const res = await fetch(endpoint); if (!res.ok) throw new Error(`HTTP ${res.status}`); const json = await res.json(); const canvas = document.getElementById(canvasId); const legend = document.getElementById(legendId); if (!json.top || json.top.length === 0) { legend.innerHTML = "
Geen data ontvangen.
"; return; } const totalPercent = json.top.reduce((sum, item) => sum + item.percent, 0); let topData = [...json.top]; if (totalPercent < 100) { topData.push({ name: "Other", percent: 100 - totalPercent }); } const labels = topData.map(item => item.name); const data = topData.map(item => item.percent); const colors = labels.map((label, i) => label === "Other" ? "#888888" : `hsl(${i * 57 % 360}, 70%, 60%)` ); if (!chartInstances[canvasId]) { const ctx = canvas.getContext("2d"); chartInstances[canvasId] = new Chart(ctx, { type: "pie", data: { labels, datasets: [{ data, backgroundColor: colors }] }, options: { responsive: true, plugins: { tooltip: { callbacks: { label: ctx => `${ctx.label}: ${ctx.parsed.toFixed(2)}%` } }, legend: { display: false } } } }); } else { const chart = chartInstances[canvasId]; chart.data.labels = labels; chart.data.datasets[0].data = data; chart.data.datasets[0].backgroundColor = colors; chart.update(); } legend.innerHTML = ""; const ul = document.createElement("ul"); topData.forEach((item, i) => { const label = item.name === "Other" ? "Other" : item.name.split(":")[0].trim(); ul.innerHTML += `Fout bij ophalen van data: ${err.message}
`; } } function loadAllCharts() { loadPieChart("/stats/src-as", "pieChart1", "legend1"); loadPieChart("/stats/src-ports", "pieChart2", "legend2"); loadPieChart("/stats/protocol", "pieChart3", "legend3"); loadPieChart("/stats/src-country", "pieChart4", "legend4"); loadPieChart("/stats/etype", "pieChart5", "legend5"); } window.addEventListener("DOMContentLoaded", () => { loadAllCharts(); setInterval(loadAllCharts, 60000); }); let chart; async function fetchData() { const response = await fetch('/stats/graph'); const jsonData = await response.json(); const labels = jsonData.data.map(item => { const date = new Date(item.t); const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); const year = date.getFullYear(); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); return `${day}/${month}/${year} ${hours}:${minutes}`; }); const rawData = jsonData.data.map(item => item.gbps); const maxVal = Math.max(...rawData); const scaleFactor = maxVal < 1 ? 1000 : 1; const unitLabel = maxVal < 1 ? 'Mbit/s' : 'Gbit/s'; const data = rawData.map(v => v * scaleFactor); return { labels, data, unitLabel }; } async function initChart() { const ctx = document.getElementById('liveChart').getContext('2d'); const { labels, data, unitLabel } = await fetchData(); chart = new Chart(ctx, { type: 'line', data: { labels, datasets: [{ label: `Network traffic (${unitLabel})`, data, borderColor: 'blue', backgroundColor: 'rgba(0,0,255,0.1)', fill: true, pointRadius: 0, pointHoverRadius: 5 }] }, options: { responsive: true, scales: { y: { beginAtZero: true, title: { display: true, text: unitLabel } }, x: { title: { display: true, text: 'Time' } } }, interaction: { mode: 'index', intersect: false }, plugins: { tooltip: { enabled: true }, legend: { display: true } } } }); } async function updateChart() { const { labels, data, unitLabel } = await fetchData(); chart.data.labels = labels; chart.data.datasets[0].data = data; chart.options.scales.y.title.text = unitLabel; chart.data.datasets[0].label = `Network traffic (${unitLabel})`; chart.update(); } window.addEventListener("DOMContentLoaded", () => { loadAllCharts(); initChart(); setInterval(loadAllCharts, 60000); setInterval(updateChart, 60000); });