feat: recon surveys with OUI/vendor lookup and report views
Reconnaissance surveys (GPSD-tethered scan recording), OUI vendor lookup for client/AP tables, survey/report pages, and the matching test_recon.py suite. Co-authored with the recon-feature agent whose work was finished in this checkout.
This commit is contained in:
@@ -10,7 +10,10 @@ const MiniChart = (() => {
|
||||
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||
const w = canvas.clientWidth, h = 140;
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
const max = Math.max(o.max || 10, ...series.map((s) => Math.max(...s.points, 0)), 1);
|
||||
const oMin = o.min == null ? 0 : o.min;
|
||||
const max = Math.max(o.max || 10, ...series.map((s) => Math.max(...s.points, oMin)), oMin + 1);
|
||||
const min = Math.min(oMin, ...series.map((s) => Math.min(...s.points, oMin)));
|
||||
const span = Math.max(max - min, 1);
|
||||
const pad = 8;
|
||||
ctx.strokeStyle = o.grid || '#e0e0e0';
|
||||
ctx.lineWidth = 1;
|
||||
@@ -28,14 +31,14 @@ const MiniChart = (() => {
|
||||
pts.forEach((v, i) => {
|
||||
if (v == null) { started = false; return; }
|
||||
const x = pad + (w - pad * 2) * i / Math.max(pts.length - 1, 1);
|
||||
const y = h - pad - (h - pad * 2) * (v / max);
|
||||
const y = h - pad - (h - pad * 2) * ((v - min) / span);
|
||||
if (!started) { ctx.moveTo(x, y); started = true; } else ctx.lineTo(x, y);
|
||||
});
|
||||
ctx.stroke();
|
||||
const last = pts[pts.length - 1];
|
||||
if (last != null) {
|
||||
const x = pad + (w - pad * 2) * (pts.length - 1) / Math.max(pts.length - 1, 1);
|
||||
const y = h - pad - (h - pad * 2) * (last / max);
|
||||
const y = h - pad - (h - pad * 2) * ((last - min) / span);
|
||||
ctx.fillStyle = s.color || '#1976d2';
|
||||
ctx.beginPath(); ctx.arc(x, y, 3, 0, Math.PI * 2); ctx.fill();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user