File size: 3,026 Bytes
65cee4e 6231cfe 65cee4e 6231cfe 65cee4e 6231cfe 65cee4e 6231cfe 65cee4e 6231cfe 65cee4e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 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 (
<g transform={`translate(${x},${y})`}>
<text x={0} y={0} dy={14} textAnchor="middle" fontSize={11} fill="#6b7280">
{formatVersion(ver)}
</text>
<text x={0} y={0} dy={28} textAnchor="middle" fontSize={10} fill="#9ca3af">
{shortDate}
</text>
</g>
)
}
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 (
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-6">
<h2 className="text-sm font-semibold text-gray-700 mb-4">Metric Evolution Across Versions</h2>
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data} margin={{ top: 4, right: 16, left: 0, bottom: 8 }}>
<CartesianGrid strokeDasharray="3 3" stroke="#f3f4f6" />
<XAxis
dataKey="version"
tick={<VersionTick dateMap={dateMap} />}
height={48}
interval={0}
/>
<YAxis domain={[0, 100]} tickFormatter={fmt} tick={{ fontSize: 12 }} width={40} />
<Tooltip
formatter={(v) => `${v}%`}
labelFormatter={(ver) => formatVersion(ver)}
/>
<Legend wrapperStyle={{ fontSize: 12 }} />
{METRICS.map(m => (
<Line
key={m.key}
type="monotone"
dataKey={m.key}
name={m.label}
stroke={m.color}
strokeWidth={2}
dot={{ r: 4 }}
connectNulls
/>
))}
</LineChart>
</ResponsiveContainer>
</div>
)
}
|