ui: encryption landscape card — ring + HTML legend with counts

This commit is contained in:
2026-08-19 06:53:35 -05:00
parent 66a62ce234
commit 53e995d5a7
2 changed files with 23 additions and 11 deletions
@@ -1495,16 +1495,14 @@ views.recon = (root) => {
chanBox.appendChild(chanEmpty);
const encBody = titleCard('Encryption Landscape', null);
const encValue = h('div', { class: 'recon-card-value', text: '—' });
const encSub = h('div', { class: 'recon-card-sub', text: '' });
encBody.appendChild(encValue);
encBody.appendChild(encSub);
const encBox = h('div', { class: 'recon-chart-box' });
encBody.appendChild(encBox);
const encCanvas = h('canvas', { id: 'recon-encryption' });
encBox.appendChild(encCanvas);
const encEmpty = h('div', { class: 'recon-no-data', text: 'No encryption data yet — run a scan.' });
encBox.appendChild(encEmpty);
const encLegend = h('div', { class: 'recon-enc-legend' });
encBody.appendChild(encLegend);
const hsBody = titleCard('Handshakes', '#/recon/handshakes');
const hsCount = h('span', { class: 'recon-hs-count', text: '0' });
@@ -2258,12 +2256,6 @@ views.recon = (root) => {
const b = reconEncBucket(a.encryption);
encCounts[b] = (encCounts[b] || 0) + 1;
});
let topEnc = null, topEncN = 0;
Object.keys(encCounts).forEach((k) => {
if (encCounts[k] > topEncN) { topEnc = k; topEncN = encCounts[k]; }
});
encValue.textContent = topEnc || '—';
encSub.textContent = topEnc ? topEncN + ' of ' + n + ' APs' : '';
const land = document.getElementById('recon-landscape');
if (land && typeof MiniChart !== 'undefined' && MiniChart.doughnut) {
@@ -2311,7 +2303,7 @@ views.recon = (root) => {
if (aps.length) {
MiniChart.doughnut(enc, RECON_ENC_BUCKETS.map((k, i) => ({
label: k, value: encCounts[k] || 0, color: RECON_ENC_COLORS[i]
})), { legend: true, height: 66 });
})), { legend: false, height: 120 });
enc.classList.remove('hidden');
encEmpty.classList.add('hidden');
} else {
@@ -2320,6 +2312,21 @@ views.recon = (root) => {
}
} catch (e) {}
}
const encLegend = document.getElementById('recon-enc-legend');
if (encLegend) {
encLegend.innerHTML = '';
RECON_ENC_BUCKETS.forEach((k, i) => {
const c = encCounts[k] || 0;
if (!c) return;
const entry = h('div', { class: 'recon-enc-entry' });
const dot = h('span', { class: 'recon-enc-dot' });
dot.style.background = RECON_ENC_COLORS[i];
entry.appendChild(dot);
entry.appendChild(h('span', { class: 'recon-enc-label', text: k }));
entry.appendChild(h('span', { class: 'recon-enc-count', text: String(c) }));
encLegend.appendChild(entry);
});
}
}
function detailUrl() {