File size: 2,328 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
import clsx from "clsx";
import { fmt } from "@/lib/data";
import type { DatasetInfo } from "@/lib/types";

type Splits = NonNullable<DatasetInfo["splits"]>;

export interface SplitMiniBarProps {
  splits: Splits;
  className?: string;
}

/* Segment palette mirrors HourBar tones: Test carries the phosphor note,
   Hard a softer echo, Train/Valid stay quiet teal-greys. */
const SEGMENTS: ReadonlyArray<{
  key: keyof Splits;
  label: string;
  fill: string;
}> = [
  {
    key: "train",
    label: "Train",
    fill: "bg-[color-mix(in_srgb,var(--accent)_16%,var(--muted)_46%)]",
  },
  {
    key: "valid",
    label: "Valid",
    fill: "bg-[color-mix(in_srgb,var(--accent)_10%,var(--muted)_30%)]",
  },
  { key: "test", label: "Test", fill: "bg-accent/75" },
  { key: "hard", label: "Hard", fill: "bg-accent/40" },
];

/**
 * Compact split-distribution readout for dataset cards: one segmented
 * hour bar plus a mono legend. The bar is decorative; the legend carries
 * the numbers.
 */
export default function SplitMiniBar({ splits, className }: SplitMiniBarProps) {
  const total = SEGMENTS.reduce((sum, s) => sum + splits[s.key].hours, 0);

  return (
    <div className={clsx("flex flex-col gap-2.5", className)}>
      <div
        aria-hidden
        className="hairline flex h-2.5 w-full gap-px overflow-hidden rounded-sm bg-surface-2"
      >
        {SEGMENTS.map((s) => (
          <div
            key={s.key}
            className={clsx("h-full", s.fill)}
            style={{ width: `${(splits[s.key].hours / total) * 100}%` }}
          />
        ))}
      </div>
      {/* 2×2 legend — four columns crowd the card's narrow readout column
          and wrap the unit onto its own line */}
      <dl className="grid grid-cols-2 gap-x-8 gap-y-1.5">
        {SEGMENTS.map((s) => (
          <div key={s.key} className="flex items-baseline gap-1.5">
            <span
              aria-hidden
              className={clsx("size-2 shrink-0 self-center rounded-[1px]", s.fill)}
            />
            <dt className="text-[12px] text-muted">{s.label}</dt>
            <dd className="num ml-auto text-[12px] whitespace-nowrap text-text">
              {fmt(splits[s.key].hours)}
              <span className="text-muted"> h</span>
            </dd>
          </div>
        ))}
      </dl>
    </div>
  );
}