diff --git a/content/sv/status/index.md b/content/sv/status/index.md index f92c221..9f3ab67 100644 --- a/content/sv/status/index.md +++ b/content/sv/status/index.md @@ -22,12 +22,18 @@ Eftersom vi har begränsad bandbredd är det viktigt att hålla nere trafiken. E +## Enhetsroll +Antalet enheter av respektive Enhetsroll som synts i meshet de senaste 30 dagarna. I större mesh så som Stockholm bör i princip all noder vara `Client` eller `Client Mute`. Enbart ett fåtal `Router` eller `Repeater` behövs. Dessa måste vara placerade extremt strategiskt, till exempel högst upp i en skidbacke. `Router Client` är en avvecklad roll som inte finns längre, men i meshen lever det kvar några noder som inte blivit uppdaterade. För med info see vår [dokumentation]({{}}). +
+ +
+ ## Position Precision Grafen visar position precision, eller noggrannhet, på de noder som rapporterat sin position de senaste 7 dagarna. Vi ser gärna att man använder en noggrannhet på ±182m eller noggrannare. Detta är dock inte möjligt att ställa in i iPhone Appen. För mer info se vår [dokumentation]({{}}#position-precision). -
+
@@ -58,4 +64,5 @@ Graferna baseras på data från [map.sthlm-mesh.se](https://map.sthlm-mesh.se), - \ No newline at end of file + + \ No newline at end of file diff --git a/static/js/status/device-roles.js b/static/js/status/device-roles.js new file mode 100644 index 0000000..1e51f2d --- /dev/null +++ b/static/js/status/device-roles.js @@ -0,0 +1,75 @@ +async function deviceRolesChart() { + const canvas = document.getElementById('deviceRoles'); + const ctx = canvas.getContext('2d'); + + // Loading message + ctx.font = '16px Arial'; + ctx.fillStyle = 'gray'; + ctx.textAlign = 'center'; + ctx.fillText('Loading data...', canvas.width / 2, canvas.height / 2); + + try { + const response = await fetch('https://map.sthlm-mesh.se/api/v1/nodes/'); + const data = await response.json(); + + const predefinedLabels = ['CLIENT', 'CLIENT_MUTE', 'CLIENT_HIDDEN', 'ROUTER_LATE', 'ROUTER', 'ROUTER_CLIENT']; + + // Count role occurrences + const roleCounts = {}; + data.nodes.forEach(node => { + const role = node.role_name || "UNKNOWN"; + roleCounts[role] = (roleCounts[role] || 0) + 1; + }); + + // Add extra roles not in predefined list + const extraLabels = Object.keys(roleCounts).filter(role => !predefinedLabels.includes(role)).sort(); + const labels = [...predefinedLabels, ...extraLabels]; + const counts = labels.map(label => roleCounts[label] || 0); + + + // Dynamically size the container based on the number of elements + const chartContainer = document.getElementById('deviceRolesContainer'); + chartContainer.style.height = `${labels.length *35}px`; + + const backgroundColors = labels.map(label => { + if (label == "ROUTER_CLIENT") return 'rgb(196, 36, 18)'; + if (label == "ROUTER") return 'rgb(242, 161, 67)'; + if (label == "ROUTER_LATE") return 'rgb(229, 189, 82)'; + return 'rgb(41, 156, 70)'; + }); + + new Chart(ctx, { + type: 'bar', + data: { + labels: labels, + datasets: [{ + label: 'Count', + data: counts, + backgroundColor: backgroundColors, + borderWidth: 1 + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + indexAxis: 'y', + scales: { + y: { + ticks: { autoSkip: false, font: { size: 12 } } + }, + x: { beginAtZero: true }, + }, + plugins: { + legend: { display: false }, + } + } + }); + } catch (error) { + console.error('Error loading portnum data:', error); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = 'red'; + ctx.fillText('Error loading data', canvas.width / 2, canvas.height / 2); + } +} + +deviceRolesChart();