/** * symbols.ts — Symbol list page behaviour. * * - Live text filter on symbol addresses (data-addr attribute) * - Client-side kind filter via sym2-kind-select dropdown * - SVG sparkline bar chart from data-weekly attribute * - Op filter is server-side via ?op= query param */ const SPARK_W = 96; const SPARK_H = 28; const SPARK_BARS = 12; const SPARK_GAP = 2; function renderSparklines(): void { document.querySelectorAll('.sym2-sparkline[data-weekly]').forEach((el) => { const raw = el.dataset.weekly ?? ''; if (!raw) { el.style.display = 'none'; return; } const vals = raw.split(',').map(Number).filter((n) => !isNaN(n)); if (!vals.length || vals.every((v) => v === 0)) { el.style.display = 'none'; return; } const max = Math.max(...vals, 1); const barW = (SPARK_W - SPARK_GAP * (SPARK_BARS - 1)) / SPARK_BARS; const bars = vals.map((v, i) => { const pct = v / max; const h = Math.max(pct * SPARK_H, pct > 0 ? 2 : 0); const x = i * (barW + SPARK_GAP); const y = SPARK_H - h; const opacity = 0.25 + pct * 0.75; return ``; }).join(''); el.innerHTML = ``; }); } export function initSymbols(): void { renderSparklines(); const searchInput = document.getElementById('sym2-search-input') as HTMLInputElement | null; const kindSelect = document.getElementById('sym2-kind-select') as HTMLSelectElement | null; const rows = Array.from(document.querySelectorAll('.sym2-row')); function applyFilter(): void { const q = searchInput ? searchInput.value.toLowerCase() : ''; const activeKind = kindSelect ? kindSelect.value : ''; rows.forEach((row) => { const addr = (row.dataset.addr ?? '').toLowerCase(); const kind = row.dataset.kind ?? ''; const matchQ = !q || addr.includes(q); const matchKind = !activeKind || kind === activeKind; row.classList.toggle('sym2-row--hidden', !(matchQ && matchKind)); }); } if (searchInput) searchInput.addEventListener('input', applyFilter); if (kindSelect) kindSelect.addEventListener('change', applyFilter); }