import { useMemo, useState } from "react"; import { seqColor } from "@/lib/colors"; /** * D3-style heatmap. Rows = layers (0..n_layers-1), cols = steps (1..n). * Color = L2 norm of last-token residual at (layer, step). */ const DEFAULT_CAPTURE_LAYERS = [6, 12, 18, 24]; export default function ActivationTimelineHeatmap({ steps = [], n_layers = 4, // 4 captured layers in v2 (not all 26) capture_layers = DEFAULT_CAPTURE_LAYERS, // actual layer numbers for labels onSelect, selected, }) { const { matrix, min, max } = useMemo(() => { const m = Array.from({ length: n_layers }, () => Array(steps.length).fill(0), ); let lo = Infinity; let hi = -Infinity; steps.forEach((s, sIdx) => { (s.layer_l2_norms || []).forEach((v, lIdx) => { if (lIdx >= n_layers) return; m[lIdx][sIdx] = v; if (v < lo) lo = v; if (v > hi) hi = v; }); }); if (!Number.isFinite(lo)) lo = 0; if (!Number.isFinite(hi)) hi = 1; return { matrix: m, min: lo, max: hi }; }, [steps, n_layers]); const cellW = 28; const cellH = 20; const padL = 38; const padT = 22; const w = padL + steps.length * (cellW + 2); const h = padT + n_layers * (cellH + 2); const [hover, setHover] = useState(null); return (