import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts' const METRICS = [ { key: 'answer_correctness', label: 'Answer Correctness', color: '#6366f1' }, { key: 'answer_relevancy', label: 'Answer Relevancy', color: '#10b981' }, { key: 'context_recall', label: 'Context Recall', color: '#f59e0b' }, { key: 'precision_at_5', label: 'Precision@5', color: '#ef4444' }, ] const MAJOR_NAMES = { 1: 'Violet', 2: 'Indigo', 3: 'Azure', 4: 'Amber', 5: 'Scarlet' } function formatVersion(version) { const match = version.match(/^v(\d+)\.(\d+)/) if (!match) return version const [, major, minor] = match const name = MAJOR_NAMES[Number(major)] ?? `v${major}` return `${name} (v${major}.${minor})` } function VersionTick({ x, y, payload, dateMap }) { const ver = payload.value const rawDate = dateMap[ver] const shortDate = rawDate ? new Date(rawDate).toLocaleDateString('en-IN', { day: 'numeric', month: 'short', year: '2-digit' }) : '' return ( {formatVersion(ver)} {shortDate} ) } export default function EvolutionChart({ runs, index }) { if (!runs.length) return null const dateMap = Object.fromEntries(index.map(e => [e.version, e.date])) const data = runs.map((run, i) => ({ version: index[i]?.version ?? `run${i + 1}`, ...Object.fromEntries( METRICS.map(m => [m.key, run.metrics?.[m.key] != null ? parseFloat((run.metrics[m.key] * 100).toFixed(1)) : null ]) ), })) const fmt = (v) => `${v}%` return (

Metric Evolution Across Versions

} height={48} interval={0} /> `${v}%`} labelFormatter={(ver) => formatVersion(ver)} /> {METRICS.map(m => ( ))}
) }