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,
|
"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 catalog ──
|
||||||
adas_root = proj_root(wf, "adas")
|
adas_root = proj_root(wf, "adas")
|
||||||
out["adas"] = {}
|
out["adas"] = {}
|
||||||
adas_packs_dir = adas_root / "packs"
|
adas_packs_dir = adas_root / "packs"
|
||||||
if adas_packs_dir.is_dir():
|
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()):
|
for pack_dir in sorted(adas_packs_dir.iterdir()):
|
||||||
if pack_dir.name.startswith(".") or not pack_dir.is_dir():
|
if pack_dir.name.startswith(".") or not pack_dir.is_dir():
|
||||||
continue
|
continue
|
||||||
@@ -996,20 +1066,14 @@ def _build_catalog(wf: dict, *, prefer_reports: bool = True) -> tuple[dict[str,
|
|||||||
task = meta.get("task", "")
|
task = meta.get("task", "")
|
||||||
counts = meta.get("counts", {})
|
counts = meta.get("counts", {})
|
||||||
img_count = counts.get("images", 0)
|
img_count = counts.get("images", 0)
|
||||||
# Count quaternion_json detections
|
|
||||||
qdir = batch_dir / "labels" / "quaternion_json"
|
|
||||||
label_count = 0
|
label_count = 0
|
||||||
class_counts: dict[str, int] = {}
|
class_counts: dict[str, int] = {}
|
||||||
if qdir.is_dir():
|
|
||||||
for qf in sorted(qdir.glob("*.json")):
|
# Collect label stats from all known ADAS label formats
|
||||||
try:
|
label_stats = _collect_adas_label_stats(batch_dir, _task_class_names.get(task, {}))
|
||||||
qdata = json.loads(qf.read_text(encoding="utf-8"))
|
label_count = label_stats["label_count"]
|
||||||
except (OSError, json.JSONDecodeError):
|
class_counts = label_stats["class_counts"]
|
||||||
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
|
|
||||||
# Count images from directory if meta is missing
|
# Count images from directory if meta is missing
|
||||||
if img_count == 0:
|
if img_count == 0:
|
||||||
imgs_dir = batch_dir / "images"
|
imgs_dir = batch_dir / "images"
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ type CompactTableShellProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CompactTableShell: React.FC<CompactTableShellProps> = ({ children, colWidths }) => (
|
export const CompactTableShell: React.FC<CompactTableShellProps> = ({ children, colWidths }) => (
|
||||||
<div className="rounded-xl border border-gray-200 bg-white overflow-hidden">
|
<div className="rounded-xl border border-gray-200 bg-white">
|
||||||
<div className="overflow-hidden">
|
<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">
|
<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 && (
|
{colWidths && colWidths.length > 0 && (
|
||||||
<colgroup>
|
<colgroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user