/* global React */ const { useMemo } = React; // Minimal SVG line chart with multi-series + grid + last-value label. // props: series=[{key, color, points:[{x,y}]}], height, width, padding, formatY function LineChart({ series, formatY, showGrid = true, showAxis = true }) { const W = 800, H = 280, P = { l: 50, r: 60, t: 14, b: 20 }; const all = series.flatMap(s => s.points); if (!all.length) return null; const xs = all.map(p => p.x), ys = all.map(p => p.y); const xmin = Math.min(...xs), xmax = Math.max(...xs); const ymin = Math.min(...ys), ymax = Math.max(...ys); const pad = (ymax - ymin) * 0.08 || 1; const y0 = ymin - pad, y1 = ymax + pad; const sx = (x) => P.l + ((x - xmin) / (xmax - xmin || 1)) * (W - P.l - P.r); const sy = (y) => P.t + (1 - (y - y0) / (y1 - y0 || 1)) * (H - P.t - P.b); const fmt = formatY || ((y) => Math.round(y).toLocaleString()); const ticks = 5; const yTicks = Array.from({ length: ticks }, (_, i) => y0 + ((y1 - y0) * i) / (ticks - 1)); return ( ); } function Sparkline({ values, color = '#7d8590', width = 60, height = 24 }) { if (!values || values.length < 2) return null; const min = Math.min(...values), max = Math.max(...values); const sx = (i) => (i / (values.length - 1)) * width; const sy = (v) => height - ((v - min) / (max - min || 1)) * height; const d = values.map((v, i) => `${i === 0 ? 'M' : 'L'}${sx(i).toFixed(1)},${sy(v).toFixed(1)}`).join(' '); return ( ); } // Bar visualizer for strategy comparison function StratBar({ value, max, color = 'var(--accent)' }) { const pct = Math.max(2, Math.min(100, (Math.abs(value) / max) * 100)); return (