fix: 修复 CompactTableShell 组件的样式,确保表格在小屏幕上可滚动
This commit is contained in:
@@ -967,11 +967,81 @@ def _build_catalog(wf: dict, *, prefer_reports: bool = True) -> tuple[dict[str,
|
||||
"quality": lane_quality,
|
||||
}
|
||||
|
||||
# ── ADAS label collection helpers ──
|
||||
|
||||
def _collect_adas_label_stats(batch_dir: Path, class_name_map: dict[int, str]) -> dict[str, Any]:
|
||||
"""Scan all known ADAS label formats and return {label_count, class_counts}."""
|
||||
label_count = 0
|
||||
class_counts: dict[str, int] = {}
|
||||
|
||||
# 1. quaternion_json — standard 2D/3D detection JSON
|
||||
qdir = batch_dir / "labels" / "quaternion_json"
|
||||
if qdir.is_dir():
|
||||
for qf in sorted(qdir.glob("*.json")):
|
||||
try:
|
||||
qdata = json.loads(qf.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
continue
|
||||
for det in qdata.get("detections") or []:
|
||||
label_count += 1
|
||||
cls = str(det.get("class_name") or det.get("class_id", "unknown"))
|
||||
class_counts[cls] = class_counts.get(cls, 0) + 1
|
||||
|
||||
# 2. yolo-hbb — YOLO horizontal bounding box text files
|
||||
yolo_dir = batch_dir / "labels" / "yolo-hbb"
|
||||
if yolo_dir.is_dir():
|
||||
for txt in sorted(yolo_dir.glob("*.txt")):
|
||||
try:
|
||||
for line in txt.read_text(encoding="utf-8", errors="ignore").splitlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
parts = line.split()
|
||||
try:
|
||||
cls_id = int(float(parts[0]))
|
||||
except (ValueError, IndexError):
|
||||
continue
|
||||
cls_name = class_name_map.get(cls_id, f"class_{cls_id}")
|
||||
class_counts[cls_name] = class_counts.get(cls_name, 0) + 1
|
||||
label_count += 1
|
||||
except OSError:
|
||||
continue
|
||||
|
||||
return {"label_count": label_count, "class_counts": class_counts}
|
||||
|
||||
# ── ADAS catalog ──
|
||||
adas_root = proj_root(wf, "adas")
|
||||
out["adas"] = {}
|
||||
adas_packs_dir = adas_root / "packs"
|
||||
if adas_packs_dir.is_dir():
|
||||
# Pre-scan for quaternion_json text_prompts to build class name maps per task
|
||||
_task_class_names: dict[str, dict[int, str]] = {} # task → {class_id: class_name}
|
||||
for pack_dir in sorted(adas_packs_dir.iterdir()):
|
||||
if pack_dir.name.startswith(".") or not pack_dir.is_dir():
|
||||
continue
|
||||
sources_dir = pack_dir / "sources"
|
||||
if not sources_dir.is_dir():
|
||||
continue
|
||||
for batch_dir in sorted(sources_dir.iterdir()):
|
||||
if batch_dir.name.startswith(".") or not batch_dir.is_dir():
|
||||
continue
|
||||
qdir = batch_dir / "labels" / "quaternion_json"
|
||||
if not qdir.is_dir():
|
||||
continue
|
||||
meta = read_meta(batch_dir) or {}
|
||||
task = meta.get("task", "")
|
||||
if not task or task in _task_class_names:
|
||||
continue
|
||||
try:
|
||||
first_qf = next(qdir.glob("*.json"), None)
|
||||
if first_qf:
|
||||
qdata = json.loads(first_qf.read_text(encoding="utf-8"))
|
||||
prompts = qdata.get("text_prompts")
|
||||
if isinstance(prompts, list) and prompts:
|
||||
_task_class_names[task] = {i: str(name) for i, name in enumerate(prompts)}
|
||||
except (OSError, json.JSONDecodeError, StopIteration):
|
||||
continue
|
||||
|
||||
for pack_dir in sorted(adas_packs_dir.iterdir()):
|
||||
if pack_dir.name.startswith(".") or not pack_dir.is_dir():
|
||||
continue
|
||||
@@ -996,20 +1066,14 @@ def _build_catalog(wf: dict, *, prefer_reports: bool = True) -> tuple[dict[str,
|
||||
task = meta.get("task", "")
|
||||
counts = meta.get("counts", {})
|
||||
img_count = counts.get("images", 0)
|
||||
# Count quaternion_json detections
|
||||
qdir = batch_dir / "labels" / "quaternion_json"
|
||||
label_count = 0
|
||||
class_counts: dict[str, int] = {}
|
||||
if qdir.is_dir():
|
||||
for qf in sorted(qdir.glob("*.json")):
|
||||
try:
|
||||
qdata = json.loads(qf.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
continue
|
||||
for det in qdata.get("detections") or []:
|
||||
label_count += 1
|
||||
cls = str(det.get("class_name") or det.get("class_id", "unknown"))
|
||||
class_counts[cls] = class_counts.get(cls, 0) + 1
|
||||
|
||||
# Collect label stats from all known ADAS label formats
|
||||
label_stats = _collect_adas_label_stats(batch_dir, _task_class_names.get(task, {}))
|
||||
label_count = label_stats["label_count"]
|
||||
class_counts = label_stats["class_counts"]
|
||||
|
||||
# Count images from directory if meta is missing
|
||||
if img_count == 0:
|
||||
imgs_dir = batch_dir / "images"
|
||||
|
||||
@@ -8,8 +8,8 @@ type CompactTableShellProps = {
|
||||
};
|
||||
|
||||
export const CompactTableShell: React.FC<CompactTableShellProps> = ({ children, colWidths }) => (
|
||||
<div className="rounded-xl border border-gray-200 bg-white overflow-hidden">
|
||||
<div className="overflow-hidden">
|
||||
<div className="rounded-xl border border-gray-200 bg-white">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="table-auto table-fixed w-full min-w-0 [&_th]:py-1.5 [&_th]:px-2 [&_th]:text-center [&_td]:py-1.5 [&_td]:px-2 [&_td]:text-center">
|
||||
{colWidths && colWidths.length > 0 && (
|
||||
<colgroup>
|
||||
|
||||
Reference in New Issue
Block a user