Spaces:
Sleeping
Sleeping
| "use client"; | |
| import { useState } from "react"; | |
| import { | |
| Bar, | |
| BarChart, | |
| CartesianGrid, | |
| ResponsiveContainer, | |
| Tooltip, | |
| XAxis, | |
| YAxis, | |
| } from "recharts"; | |
| export interface TopicWer { | |
| topic: string; | |
| wer: number; | |
| } | |
| export interface TopicChartProps { | |
| data: TopicWer[]; | |
| } | |
| /** | |
| * Horizontal per-topic WER bar chart. Rendered only when a run actually | |
| * recorded a per-topic breakdown (platform-verified runs). | |
| * Colors tuned for the lifted palette: category labels in full text ink, | |
| * brighter accent bars. The one-shot bar draw-in is gated on | |
| * prefers-reduced-motion (recharts animation does not read the CSS override). | |
| */ | |
| export default function TopicChart({ data }: TopicChartProps) { | |
| /* lazy init: only meaningful client-side — ResponsiveContainer measures | |
| on mount anyway, so there is no server-rendered chart to mismatch */ | |
| const [animate] = useState( | |
| () => | |
| typeof window !== "undefined" && | |
| !window.matchMedia("(prefers-reduced-motion: reduce)").matches, | |
| ); | |
| return ( | |
| <div | |
| role="img" | |
| aria-label={`Per-topic WER: ${data | |
| .map((d) => `${d.topic} ${d.wer.toFixed(2)} percent`) | |
| .join(", ")}`} | |
| style={{ height: data.length * 44 + 40 }} | |
| > | |
| <ResponsiveContainer width="100%" height="100%"> | |
| <BarChart | |
| data={data} | |
| layout="vertical" | |
| margin={{ top: 4, right: 28, bottom: 4, left: 8 }} | |
| > | |
| <CartesianGrid horizontal={false} stroke="var(--line)" /> | |
| <XAxis | |
| type="number" | |
| unit="%" | |
| tick={{ | |
| fill: "var(--muted)", | |
| fontSize: 11, | |
| fontFamily: "var(--font-mono)", | |
| }} | |
| axisLine={{ stroke: "var(--line)" }} | |
| tickLine={false} | |
| /> | |
| <YAxis | |
| type="category" | |
| dataKey="topic" | |
| width={170} | |
| tick={{ fill: "var(--text)", fontSize: 12 }} | |
| axisLine={false} | |
| tickLine={false} | |
| /> | |
| <Tooltip | |
| cursor={{ fill: "var(--accent-dim)" }} | |
| contentStyle={{ | |
| background: "var(--surface-2)", | |
| border: "1px solid var(--line)", | |
| borderRadius: 2, | |
| fontFamily: "var(--font-mono)", | |
| fontSize: 12, | |
| color: "var(--text)", | |
| }} | |
| labelStyle={{ color: "var(--text)" }} | |
| formatter={(value) => [`${Number(value).toFixed(2)} %`, "WER"]} | |
| /> | |
| <Bar | |
| dataKey="wer" | |
| fill="var(--accent)" | |
| fillOpacity={0.7} | |
| barSize={14} | |
| radius={[0, 2, 2, 0]} | |
| isAnimationActive={animate} | |
| animationDuration={700} | |
| animationEasing="ease-out" | |
| /> | |
| </BarChart> | |
| </ResponsiveContainer> | |
| </div> | |
| ); | |
| } | |