import { useState } from 'react'; import type { GraphStatistics, ConnectivityInfo } from '../types'; import { NODE_TYPE_LABELS, NODE_COLORS } from '../constants'; interface Props { statistics: GraphStatistics; processingTime: number; imageName: string; edited?: boolean; connectivity?: ConnectivityInfo | null; onFocusNode?: (id: string) => void; onToggleBroken?: (show: boolean) => void; } const MAX_LISTED = 40; const REASON_LABEL: Record = { isolated: 'no edges', room: 'room', exit: 'exit' }; export default function StatsPanel({ statistics, processingTime, imageName, edited, connectivity, onFocusNode, onToggleBroken, }: Props) { const [open, setOpen] = useState(true); const [connOpen, setConnOpen] = useState(false); const { total_nodes, total_edges, node_types, pruning_reduction } = statistics; const broken = connectivity && !connectivity.fullyConnected; const toggleConn = () => setConnOpen((o) => { const next = !o; onToggleBroken?.(next); return next; }); return (
{open && (
Image {imageName}
Processing Time {processingTime > 0 ? `${processingTime.toFixed(1)}s` : 'Cached'}

Total Nodes {total_nodes}
Total Edges {total_edges}
{connectivity && ( <>
Connectivity {connectivity.score}%{' '} {broken ? ( ) : ( )}
{broken && connOpen && (
{connectivity.isolatedCount > 0 && (
{connectivity.isolatedCount} node {connectivity.isolatedCount === 1 ? '' : 's'} with no edges
)} {connectivity.roomsDisconnected > 0 && (
{connectivity.roomsDisconnected} room {connectivity.roomsDisconnected === 1 ? '' : 's'} unreachable
)} {connectivity.exitsDisconnected > 0 && (
{connectivity.exitsDisconnected} exit door {connectivity.exitsDisconnected === 1 ? '' : 's'} unreachable
)}
The smaller, disconnected subgraph is highlighted in red on the graph. Click a node to zoom to it.
{connectivity.offenders.slice(0, MAX_LISTED).map((n) => ( ))} {connectivity.offenders.length > MAX_LISTED && (
+ {connectivity.offenders.length - MAX_LISTED} more
)}
)} )} {pruning_reduction != null && pruning_reduction > 0 && (
Pruning Reduction {pruning_reduction}%
)}
{Object.entries(node_types).map(([type, count]) => (
{NODE_TYPE_LABELS[type] || type} {count}
))}
)}
); }