"use client"; import { useEffect, useState } from "react"; interface RadarChartProps { data: { label: string; value: number; max?: number }[]; size?: number; color?: string; } /** * RadarChart — animated SVG radar/spider chart for multi-dimensional scores. * Used for DCS breakdowns, evidence quality, and research reliability. */ export function RadarChart({ data, size = 240, color = "hsl(var(--primary))" }: RadarChartProps) { const [animated, setAnimated] = useState(false); const center = size / 2; const maxRadius = size / 2 - 40; const numAxes = data.length; useEffect(() => { const timer = setTimeout(() => setAnimated(true), 100); return () => clearTimeout(timer); }, []); function getPoint(index: number, value: number, max: number = 100) { const angle = (index / numAxes) * Math.PI * 2 - Math.PI / 2; const radius = animated ? (value / max) * maxRadius : 0; return { x: center + Math.cos(angle) * radius, y: center + Math.sin(angle) * radius, }; } function getAxisEnd(index: number) { const angle = (index / numAxes) * Math.PI * 2 - Math.PI / 2; return { x: center + Math.cos(angle) * maxRadius, y: center + Math.sin(angle) * maxRadius, }; } function getLabelPos(index: number) { const angle = (index / numAxes) * Math.PI * 2 - Math.PI / 2; const r = maxRadius + 20; return { x: center + Math.cos(angle) * r, y: center + Math.sin(angle) * r, }; } const points = data.map((d, i) => { const p = getPoint(i, d.value, d.max || 100); return `${p.x},${p.y}`; }).join(" "); // Grid rings at 25%, 50%, 75%, 100% const gridLevels = [0.25, 0.5, 0.75, 1.0]; return ( {/* Grid rings */} {gridLevels.map((level) => { const ringPoints = data.map((_, i) => { const angle = (i / numAxes) * Math.PI * 2 - Math.PI / 2; return `${center + Math.cos(angle) * maxRadius * level},${center + Math.sin(angle) * maxRadius * level}`; }).join(" "); return ( ); })} {/* Axes */} {data.map((_, i) => { const end = getAxisEnd(i); return ( ); })} {/* Data polygon */} {/* Data points */} {data.map((d, i) => { const p = getPoint(i, d.value, d.max || 100); return ( ); })} {/* Labels */} {data.map((d, i) => { const pos = getLabelPos(i); return ( {d.label} ); })} ); }