Files
HSAP/platform/web/src/components/SplitCountsBars.tsx
Chengfang Lu e72bc061c5 feat: HSAP platform v2 — modular navigation, quality review, audit log, world model simulation
Major changes:
- New frontend (platform/web/): Vite + React 18 + TypeScript + Tailwind
- 4-module navigation: 数据送标 / 模型管理 / 车队管理 / 系统管理
- Data catalog with charts (DMS/ADAS/Lane 3-tab view)
- Quality review workflow (标注质检): Good/Fine/Bad scoring with auto-advance
- Audit enhancements: batch operations, rejection categories, Feishu notifications
- Operation audit log (操作日志)
- World model simulation studio (仿真工坊)
- Dataset version management with snapshots and diff
- ADAS 7-class dataset integration (138K images organized + compressed)
- User management with Feishu integration and pagination
- CRUD/search/filter on all pages, card layout redesign
- PIL-optimized image overlay rendering
- Auto-snapshot on build, in_review workflow stage
- Removed embedded algorithm code (now in workspace)
2026-06-03 11:40:21 +08:00

33 lines
1.3 KiB
TypeScript

import React from "react";
import { CHART_EMPTY_HINT } from "@/lib/chartStats";
import type { SplitCounts } from "@/lib/dmsCatalog";
type Props = { counts: SplitCounts; height?: number };
const LABELS: { key: keyof SplitCounts; label: string }[] = [
{ key: "train", label: "train" }, { key: "val", label: "val" }, { key: "test", label: "test" },
];
export const SplitCountsBars: React.FC<Props> = ({ counts, height = 120 }) => {
const total = counts.train + counts.val + counts.test;
if (total <= 0) return <p className="text-sm text-gray-400 m-0">{CHART_EMPTY_HINT}</p>;
const max = Math.max(counts.train, counts.val, counts.test, 1);
const barW = 48;
return (
<div className="flex items-end gap-6 justify-center" style={{ height }}>
{LABELS.map(({ key, label }) => {
const n = counts[key];
return (
<div key={key} className="flex flex-col items-center" style={{ width: barW }}>
<span className="text-sm tabular-nums font-semibold mb-1">{n}</span>
<div className="w-full rounded-t bg-blue-700" style={{ height: `${Math.max(8, Math.round((n / max) * (height - 48)))}px` }} />
<span className="text-xs text-gray-500 mt-2 font-mono">{label}</span>
</div>
);
})}
</div>
);
};