MedASR-Bench / src /components /model /TopicChart.tsx
ngoan
MedASR Bench: full platform + Hugging Face Docker Space packaging
d70f132
Raw
History Blame Contribute Delete
2.86 kB
"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>
);
}