mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-06-04 08:51:19 +00:00
Analytics: widen to 1600px, side-by-side card layout
- max-width 900px → 1600px for analytics page - Added analytics-grid CSS class for auto-fit columns - Hash Stats: distribution + timeline side-by-side, adopters + top hops side-by-side - RF, Topology, Channels already used analytics-row flex layout - Cards now fill available screen width instead of being squished
This commit is contained in:
+20
-19
@@ -648,33 +648,33 @@
|
||||
const maxCount = Math.max(d[1] || 0, d[2] || 0, d[3] || 0, 1);
|
||||
|
||||
el.innerHTML = `
|
||||
<div class="analytics-card">
|
||||
<h3>Hash Size Distribution</h3>
|
||||
<p class="text-muted">${total.toLocaleString()} packets with path hops</p>
|
||||
<div class="hash-bars">
|
||||
${[1, 2, 3].map(size => {
|
||||
const count = d[size] || 0;
|
||||
const width = Math.max((count / maxCount) * 100, count ? 2 : 0);
|
||||
const colors = { 1: '#ef4444', 2: '#22c55e', 3: '#3b82f6' };
|
||||
return `<div class="hash-bar-row">
|
||||
<div class="analytics-row">
|
||||
<div class="analytics-card flex-1">
|
||||
<h3>Hash Size Distribution</h3>
|
||||
<p class="text-muted">${total.toLocaleString()} packets with path hops</p>
|
||||
<div class="hash-bars">
|
||||
${[1, 2, 3].map(size => {
|
||||
const count = d[size] || 0;
|
||||
const width = Math.max((count / maxCount) * 100, count ? 2 : 0);
|
||||
const colors = { 1: '#ef4444', 2: '#22c55e', 3: '#3b82f6' };
|
||||
return `<div class="hash-bar-row">
|
||||
<div class="hash-bar-label"><strong>${size}-byte</strong> <span class="text-muted">(${size * 8}-bit, ${Math.pow(256, size).toLocaleString()} IDs)</span></div>
|
||||
<div class="hash-bar-track"><div class="hash-bar-fill" style="width:${width}%;background:${colors[size]}"></div></div>
|
||||
<div class="hash-bar-value">${count.toLocaleString()} <span class="text-muted">(${pct(count)}%)</span></div>
|
||||
</div>`;
|
||||
}).join('')}
|
||||
}).join('')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="analytics-row">
|
||||
<div class="analytics-card flex-1">
|
||||
<h3>📈 Hash Size Over Time</h3>
|
||||
${renderHashTimeline(data.hourly)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="analytics-card">
|
||||
<h3>Multi-Byte Hash Adopters</h3>
|
||||
<p class="text-muted">Nodes advertising with 2+ byte hash paths</p>
|
||||
<div class="analytics-row">
|
||||
<div class="analytics-card flex-1">
|
||||
<h3>Multi-Byte Hash Adopters</h3>
|
||||
<p class="text-muted">Nodes advertising with 2+ byte hash paths</p>
|
||||
${data.multiByteNodes.length ? `
|
||||
<table class="analytics-table">
|
||||
<thead><tr><th>Node</th><th>Hash Size</th><th>Adverts</th><th>Last Seen</th></tr></thead>
|
||||
@@ -688,10 +688,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
` : '<div class="text-muted" style="padding:16px">No multi-byte adopters found</div>'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="analytics-card">
|
||||
<h3>Top Path Hops</h3>
|
||||
<div class="analytics-card flex-1">
|
||||
<h3>Top Path Hops</h3>
|
||||
<table class="analytics-table">
|
||||
<thead><tr><th>Hop</th><th>Node</th><th>Bytes</th><th>Appearances</th></tr></thead>
|
||||
<tbody>
|
||||
@@ -706,6 +706,7 @@
|
||||
}).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
+4
-1
@@ -998,10 +998,13 @@ button.ch-item.ch-item-encrypted .ch-badge { filter: grayscale(0.6); }
|
||||
.node-activity-time { color: var(--text-muted); white-space: nowrap; min-width: 70px; font-size: 12px; }
|
||||
|
||||
/* Analytics page */
|
||||
.analytics-page { padding: 16px; max-width: 900px; margin: 0 auto; overflow-y: auto; height: 100%; }
|
||||
.analytics-page { padding: 16px 24px; max-width: 1600px; margin: 0 auto; overflow-y: auto; height: 100%; }
|
||||
.analytics-header { margin-bottom: 20px; }
|
||||
.analytics-header h2 { margin: 0 0 4px; }
|
||||
.analytics-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px; margin-bottom: 16px; }
|
||||
.analytics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 16px; margin-bottom: 16px; }
|
||||
.analytics-grid .analytics-card { margin-bottom: 0; }
|
||||
.analytics-full { grid-column: 1 / -1; }
|
||||
.analytics-card h3 { margin: 0 0 8px; font-size: 15px; }
|
||||
.analytics-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
.analytics-table th { text-align: left; padding: 8px; border-bottom: 2px solid var(--border); font-size: 12px; text-transform: uppercase; color: var(--text-muted); }
|
||||
|
||||
Reference in New Issue
Block a user