diff --git a/meshview/templates/top.html b/meshview/templates/top.html index 20ec91c..5d810af 100644 --- a/meshview/templates/top.html +++ b/meshview/templates/top.html @@ -1,160 +1,150 @@ {% extends "base.html" %} {% block css %} -/* General table styling */ + {% endblock %} {% block body %} -
This chart shows a bell curve (normal distribution) based on the total "Times Seen" values for all nodes. It helps visualize how frequently nodes are heard, relative to the average.
-This "Time Seen" value is the closest that we can get to Mesh utilization by node.
-This "Time Seen" value is the closest that we can get to Mesh utilization by node.
Mean: - Standard Deviation:
-| Long Name | -Short Name | -Channel | -Packets Sent | -Times Seen | -
|---|---|---|---|---|
| {{ node.long_name }} | -{{ node.short_name }} | -{{ node.channel }} | -{{ node.total_packets_sent }} | -{{ node.total_times_seen }} | -
| Long Name | +Short Name | +Channel | +Packets Sent | +Times Seen | +
|---|---|---|---|---|
| {{ node.long_name }} | +{{ node.short_name }} | +{{ node.channel }} | +{{ node.total_packets_sent }} | +{{ node.total_times_seen }} | +
No top traffic nodes available.
- {% endif %} +{% endif %} - - + + + // Recalculate stats & chart + const { mean, stdDev, values } = calculateStats(filtered); + document.getElementById('mean').textContent = mean.toFixed(2); + document.getElementById('stdDev').textContent = stdDev.toFixed(2); + renderChart(values, mean, stdDev); +} + +function populateChannelFilter() { + const select = document.getElementById('channelFilter'); + const channels = [...new Set(nodes.map(n => n.channel))].sort(); + for (const ch of channels) { + const opt = document.createElement('option'); + opt.value = ch; + opt.textContent = ch; + select.appendChild(opt); + } + + select.addEventListener('change', filterByChannel); +} + +function sortTable(n) { + const table = document.getElementById("trafficTable"); + const rows = Array.from(table.rows).slice(1); + const isNumeric = !isNaN(rows[0].cells[n].innerText); + const dir = table.rows[0].cells[n].getAttribute('data-sort-direction') === 'asc' ? 'desc' : 'asc'; + table.rows[0].cells[n].setAttribute('data-sort-direction', dir); + + rows.sort((a, b) => { + const valA = isNumeric ? parseFloat(a.cells[n].innerText) : a.cells[n].innerText.toLowerCase(); + const valB = isNumeric ? parseFloat(b.cells[n].innerText) : b.cells[n].innerText.toLowerCase(); + return (valA > valB ? 1 : -1) * (dir === 'asc' ? 1 : -1); + }); + + rows.forEach(row => table.tBodies[0].appendChild(row)); +} + +function init() { + myChart = echarts.init(document.getElementById('bellCurveChart')); + populateChannelFilter(); + filterByChannel(); + window.addEventListener('resize', () => { + if (myChart) myChart.resize(); + }); +} + +document.addEventListener('DOMContentLoaded', init); + {% endblock %}