mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-08-06 17:02:48 +02:00
Adding new Top Users visualization
This commit is contained in:
+24
-27
@@ -63,9 +63,9 @@ h1 {
|
||||
}
|
||||
|
||||
#stats {
|
||||
text-align: center; /* Centers the content inside the #stats container */
|
||||
margin-top: 20px; /* Adds a 20px margin at the top */
|
||||
color: #fff
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
@@ -73,15 +73,18 @@ h1 {
|
||||
{% block body %}
|
||||
<h1>Top Traffic Nodes</h1>
|
||||
|
||||
<!-- Chart Description -->
|
||||
<div id="stats">
|
||||
<p>This chart shows a bell curve (normal distribution) based on the total <strong>"Times Seen"</strong> values for all nodes. It helps visualize how frequently nodes are heard, relative to the average.</p>
|
||||
<p> This "Time Seen" value is the closest that we can get to Mesh utilization by node.</p>
|
||||
</div>
|
||||
<div id="stats">
|
||||
<p><strong>Mean: </strong><span id="mean"></span> - <strong>Standard Deviation: </strong><span id="stdDev"></span></p>
|
||||
</div>
|
||||
|
||||
<!-- Bell Curve Chart -->
|
||||
<div id="bellCurveChart"></div>
|
||||
|
||||
<!-- Mean and Standard Deviation Display -->
|
||||
<div id="stats">
|
||||
<p><strong>Mean: </strong><span id="mean"></span></p>
|
||||
<p><strong>Standard Deviation: </strong><span id="stdDev"></span></p>
|
||||
</div>
|
||||
|
||||
{% if nodes %}
|
||||
<div class="container">
|
||||
<table id="trafficTable">
|
||||
@@ -97,7 +100,7 @@ h1 {
|
||||
<tbody>
|
||||
{% for node in nodes %}
|
||||
<tr>
|
||||
<td>{{ node.long_name }}</td>
|
||||
<td><a href="/top?node_id={{ node.node_id }}">{{ node.long_name }}</a></td>
|
||||
<td>{{ node.short_name }}</td>
|
||||
<td>{{ node.channel }}</td>
|
||||
<td>{{ node.total_packets_sent }}</td>
|
||||
@@ -114,7 +117,7 @@ h1 {
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"></script>
|
||||
<script>
|
||||
// Get the nodes data from the backend
|
||||
const nodes = {{ nodes | tojson }}; // Converts the nodes to a JSON object in JavaScript
|
||||
const nodes = {{ nodes | tojson }};
|
||||
|
||||
// Extract total_times_seen values
|
||||
const timesSeenValues = nodes.map(node => node.total_times_seen);
|
||||
@@ -127,17 +130,17 @@ h1 {
|
||||
document.getElementById('mean').textContent = mean.toFixed(2);
|
||||
document.getElementById('stdDev').textContent = stdDev.toFixed(2);
|
||||
|
||||
// Function to calculate the normal distribution value (bell curve)
|
||||
// Function to calculate the normal distribution value
|
||||
function normalDistribution(x, mean, stdDev) {
|
||||
return (1 / (stdDev * Math.sqrt(2 * Math.PI))) * Math.exp(-0.5 * Math.pow((x - mean) / stdDev, 2));
|
||||
}
|
||||
|
||||
// Generate x-values (range) and corresponding y-values for the bell curve
|
||||
// Generate x and y values for the bell curve
|
||||
const xData = [];
|
||||
const yData = [];
|
||||
const min = Math.min(...timesSeenValues);
|
||||
const max = Math.max(...timesSeenValues);
|
||||
const step = (max - min) / 100; // Number of data points for the bell curve
|
||||
const step = (max - min) / 100;
|
||||
|
||||
for (let x = min; x <= max; x += step) {
|
||||
xData.push(x);
|
||||
@@ -148,7 +151,7 @@ h1 {
|
||||
const myChart = echarts.init(document.getElementById('bellCurveChart'));
|
||||
|
||||
const option = {
|
||||
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
@@ -175,36 +178,30 @@ h1 {
|
||||
|
||||
myChart.setOption(option);
|
||||
|
||||
// Function to sort the table when clicking on column headers
|
||||
// Function to sort the table columns
|
||||
function sortTable(n) {
|
||||
const table = document.getElementById("trafficTable");
|
||||
const rows = Array.from(table.rows).slice(1); // Get all rows except the header
|
||||
const isNumeric = !isNaN(rows[0].cells[n].innerText); // Check if column contains numeric data
|
||||
const rows = Array.from(table.rows).slice(1); // Skip header
|
||||
const isNumeric = !isNaN(rows[0].cells[n].innerText);
|
||||
let sortedRows;
|
||||
|
||||
if (isNumeric) {
|
||||
sortedRows = rows.sort((a, b) => {
|
||||
const cellA = parseFloat(a.cells[n].innerText);
|
||||
const cellB = parseFloat(b.cells[n].innerText);
|
||||
return cellA - cellB; // Numeric sort
|
||||
return parseFloat(a.cells[n].innerText) - parseFloat(b.cells[n].innerText);
|
||||
});
|
||||
} else {
|
||||
sortedRows = rows.sort((a, b) => {
|
||||
const cellA = a.cells[n].innerText.toLowerCase();
|
||||
const cellB = b.cells[n].innerText.toLowerCase();
|
||||
return cellA.localeCompare(cellB); // Alphabetic sort
|
||||
return a.cells[n].innerText.toLowerCase().localeCompare(b.cells[n].innerText.toLowerCase());
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle the direction of the sort (ascending or descending)
|
||||
if (table.rows[0].cells[n].getAttribute('data-sort-direction') === 'asc') {
|
||||
sortedRows.reverse(); // Reverse the order for descending
|
||||
sortedRows.reverse();
|
||||
table.rows[0].cells[n].setAttribute('data-sort-direction', 'desc');
|
||||
} else {
|
||||
table.rows[0].cells[n].setAttribute('data-sort-direction', 'asc');
|
||||
}
|
||||
|
||||
// Append sorted rows back to the table body
|
||||
sortedRows.forEach(row => table.tBodies[0].appendChild(row));
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user