add attribute area and score to detail stream tooltip

This commit is contained in:
Josh Hawkins 2025-11-25 07:14:25 -06:00
parent ede07f43cb
commit 93de8471d8

View File

@ -681,22 +681,62 @@ function LifecycleItem({
}) })
: ""; : "";
const ratio = const ratio = useMemo(
Array.isArray(item?.data.box) && item?.data.box.length >= 4 () =>
? (aspectRatio * (item?.data.box[2] / item?.data.box[3])).toFixed(2) Array.isArray(item?.data.box) && item?.data.box.length >= 4
: "N/A"; ? (aspectRatio * (item?.data.box[2] / item?.data.box[3])).toFixed(2)
const areaPx = : "N/A",
Array.isArray(item?.data.box) && item?.data.box.length >= 4 [aspectRatio, item],
? Math.round( );
(config?.cameras[item?.camera]?.detect?.width ?? 0) *
(config?.cameras[item?.camera]?.detect?.height ?? 0) * const areaPx = useMemo(
(item?.data.box[2] * item?.data.box[3]), () =>
) Array.isArray(item?.data.box) && item?.data.box.length >= 4
: undefined; ? Math.round(
const areaPct = (config?.cameras[item?.camera]?.detect?.width ?? 0) *
Array.isArray(item?.data.box) && item?.data.box.length >= 4 (config?.cameras[item?.camera]?.detect?.height ?? 0) *
? (item?.data.box[2] * item?.data.box[3]).toFixed(4) (item?.data.box[2] * item?.data.box[3]),
: undefined; )
: undefined,
[config, item],
);
const areaPct = useMemo(
() =>
Array.isArray(item?.data.box) && item?.data.box.length >= 4
? (item?.data.box[2] * item?.data.box[3]).toFixed(4)
: undefined,
[item],
);
const attributeAreaPx = useMemo(
() =>
Array.isArray(item?.data.attribute_box) &&
item?.data.attribute_box.length >= 4
? Math.round(
(config?.cameras[item?.camera]?.detect?.width ?? 0) *
(config?.cameras[item?.camera]?.detect?.height ?? 0) *
(item?.data.attribute_box[2] * item?.data.attribute_box[3]),
)
: undefined,
[config, item],
);
const attributeAreaPct = useMemo(
() =>
Array.isArray(item?.data.attribute_box) &&
item?.data.attribute_box.length >= 4
? (item?.data.attribute_box[2] * item?.data.attribute_box[3]).toFixed(4)
: undefined,
[item],
);
const score = useMemo(() => {
if (item?.data?.score !== undefined) {
return (item.data.score * 100).toFixed(0) + "%";
}
return "N/A";
}, [item?.data?.score]);
return ( return (
<div <div
@ -733,6 +773,13 @@ function LifecycleItem({
<TooltipContent> <TooltipContent>
<div className="mt-1 flex flex-wrap items-start gap-3 text-sm text-secondary-foreground"> <div className="mt-1 flex flex-wrap items-start gap-3 text-sm text-secondary-foreground">
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<div className="flex items-start gap-1">
<span className="text-muted-foreground">
{t("trackingDetails.lifecycleItemDesc.header.score")}
</span>
<span className="font-medium text-foreground">{score}</span>
</div>
<div className="flex items-start gap-1"> <div className="flex items-start gap-1">
<span className="text-muted-foreground"> <span className="text-muted-foreground">
{t("trackingDetails.lifecycleItemDesc.header.ratio")} {t("trackingDetails.lifecycleItemDesc.header.ratio")}
@ -742,7 +789,13 @@ function LifecycleItem({
<div className="flex items-start gap-1"> <div className="flex items-start gap-1">
<span className="text-muted-foreground"> <span className="text-muted-foreground">
{t("trackingDetails.lifecycleItemDesc.header.area")} {t("trackingDetails.lifecycleItemDesc.header.area")}{" "}
{attributeAreaPx !== undefined &&
attributeAreaPct !== undefined && (
<span className="text-muted-foreground">
({getTranslatedLabel(item.data.label)})
</span>
)}
</span> </span>
{areaPx !== undefined && areaPct !== undefined ? ( {areaPx !== undefined && areaPct !== undefined ? (
<span className="font-medium text-foreground"> <span className="font-medium text-foreground">
@ -754,6 +807,26 @@ function LifecycleItem({
<span>N/A</span> <span>N/A</span>
)} )}
</div> </div>
{attributeAreaPx !== undefined &&
attributeAreaPct !== undefined && (
<div className="flex items-start gap-1">
<span className="text-muted-foreground">
{t("trackingDetails.lifecycleItemDesc.header.area")}{" "}
{attributeAreaPx !== undefined &&
attributeAreaPct !== undefined && (
<span className="text-muted-foreground">
({getTranslatedLabel(item.data.attribute)})
</span>
)}
</span>
<span className="font-medium text-foreground">
{attributeAreaPx} {t("pixels", { ns: "common" })}{" "}
<span className="text-secondary-foreground">·</span>{" "}
{attributeAreaPct}%
</span>
</div>
)}
</div> </div>
</div> </div>
</TooltipContent> </TooltipContent>
@ -820,7 +893,7 @@ function ObjectTimeline({
}, [config, fullTimeline, review]); }, [config, fullTimeline, review]);
if (isValidating && (!timeline || timeline.length === 0)) { if (isValidating && (!timeline || timeline.length === 0)) {
return <ActivityIndicator className="ml-2 size-3" />; return <ActivityIndicator className="ml-2.5 size-3" />;
} }
if (!timeline || timeline.length === 0) { if (!timeline || timeline.length === 0) {