MedASR-Bench / src /components /docs /SplitsTable.tsx
ngoan
MedASR Bench: full platform + Hugging Face Docker Space packaging
d70f132
Raw
History Blame Contribute Delete
4.81 kB
import Badge from "@/components/ui/Badge";
import { fmt } from "@/lib/data";
import type { DatasetInfo } from "@/lib/types";
import HourBar from "./HourBar";
export interface SplitsTableProps {
/** Frozen split inventory of a live dataset. */
splits: NonNullable<DatasetInfo["splits"]>;
/** Dataset name for the accessible caption, e.g. "ViMedCSS". */
datasetName?: string;
}
const ROWS: ReadonlyArray<{
key: keyof NonNullable<DatasetInfo["splits"]>;
name: string;
tone: "muted" | "accent" | "accent-soft";
badge?: { label: string; variant: "accent" | "outline" };
role: string;
}> = [
{
key: "train",
name: "Train",
tone: "muted",
role: "Adaptation corpus — Track C systems may train on this split and nothing else.",
},
{
key: "valid",
name: "Valid",
tone: "muted",
role: "Hyperparameter tuning and checkpoint selection. Never reported as a result.",
},
{
key: "test",
name: "Test",
tone: "accent",
badge: { label: "Primary", variant: "accent" },
role: "The primary leaderboard — every headline number on the home page is scored here.",
},
{
key: "hard",
name: "Hard",
tone: "accent-soft",
badge: { label: "Generalization", variant: "outline" },
role: "Rare and unseen terms, disjoint from Train — the generalization leaderboard.",
},
];
/** Dataset split table with proportional hour-bars and role captions. */
export default function SplitsTable({ splits, datasetName }: SplitsTableProps) {
const totalHours = ROWS.reduce((sum, r) => sum + splits[r.key].hours, 0);
return (
<div className="hairline spotlight-row depth-1 overflow-x-auto rounded-sm bg-surface">
<table className="w-full min-w-[680px] border-collapse text-sm">
<caption className="sr-only">
{datasetName ?? "Dataset"} splits: hours, utterances, share of total
audio, and the role of each split
</caption>
<thead>
<tr className="hairline-b text-left">
<th
scope="col"
className="num px-4 py-3 text-[11px] font-normal uppercase tracking-[0.14em] text-muted"
>
Split
</th>
<th
scope="col"
className="num px-4 py-3 text-right text-[11px] font-normal uppercase tracking-[0.14em] text-muted"
>
Hours
</th>
<th
scope="col"
className="num px-4 py-3 text-right text-[11px] font-normal uppercase tracking-[0.14em] text-muted"
>
Utterances
</th>
<th
scope="col"
className="num px-4 py-3 text-[11px] font-normal uppercase tracking-[0.14em] text-muted"
>
Share of audio
</th>
<th
scope="col"
className="num px-4 py-3 text-[11px] font-normal uppercase tracking-[0.14em] text-muted"
>
Role
</th>
</tr>
</thead>
<tbody>
{ROWS.map((row, i) => {
const s = splits[row.key];
const share = s.hours / totalHours;
return (
<tr
key={row.key}
className={i < ROWS.length - 1 ? "hairline-b align-top" : "align-top"}
>
<th
scope="row"
className="whitespace-nowrap px-4 py-3.5 text-left font-medium text-text"
>
<span className="inline-flex items-center gap-2">
{row.name}
{row.badge && (
<Badge variant={row.badge.variant}>{row.badge.label}</Badge>
)}
</span>
</th>
<td className="num whitespace-nowrap px-4 py-3.5 text-right text-text">
{fmt(s.hours)}
<span className="text-muted"> h</span>
</td>
<td className="num whitespace-nowrap px-4 py-3.5 text-right text-text">
{s.utts.toLocaleString("en-US")}
</td>
<td className="px-4 py-3.5">
<div className="flex items-center gap-2.5">
<HourBar share={share} tone={row.tone} className="w-24 md:w-32" />
<span className="num text-[11px] text-muted">
{(share * 100).toFixed(1)}%
</span>
</div>
</td>
<td className="min-w-[16rem] px-4 py-3.5 text-[13px] leading-relaxed text-muted">
{row.role}
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}