Spaces:
Running
Running
File size: 4,809 Bytes
d70f132 | 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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | 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>
);
}
|