import { useVisualizerStore } from '@/core/store'; import type { LayerType, LayerParams, TensorShape } from '@/schema/types'; import { LAYER_CATEGORIES } from '@/schema/types'; import styles from './InfoPanel.module.css'; /** * Format tensor shape for display */ function formatShape(shape?: TensorShape): string { if (!shape || shape.length === 0) return 'N/A'; return `[${shape.join(', ')}]`; } /** * Format parameter value for display */ function formatParamValue(value: unknown): string { if (value === null || value === undefined) return 'N/A'; if (Array.isArray(value)) return `[${value.join(', ')}]`; if (typeof value === 'boolean') return value ? 'Yes' : 'No'; if (typeof value === 'number') return value.toLocaleString(); return String(value); } /** * Get human-readable layer type name */ function getLayerTypeName(type: LayerType): string { const names: Partial> = { conv2d: '2D Convolution', conv3d: '3D Convolution', convTranspose2d: 'Transposed Conv2D', linear: 'Linear (Dense)', batchNorm2d: 'Batch Normalization 2D', layerNorm: 'Layer Normalization', multiHeadAttention: 'Multi-Head Attention', maxPool2d: 'Max Pooling 2D', avgPool2d: 'Average Pooling 2D', globalAvgPool: 'Global Average Pooling', relu: 'ReLU Activation', gelu: 'GELU Activation', sigmoid: 'Sigmoid Activation', softmax: 'Softmax', }; return names[type] || type.charAt(0).toUpperCase() + type.slice(1); } /** * Layer parameter display component */ function LayerParamsDisplay({ params }: { params?: LayerParams }) { if (!params) return null; const relevantParams = Object.entries(params).filter(([_, v]) => v !== undefined && v !== null); if (relevantParams.length === 0) return null; return (

Parameters

{relevantParams.map(([key, value]) => ( ))}
{key} {formatParamValue(value)}
); } /** * Info panel for selected node */ export function InfoPanel() { const selection = useVisualizerStore(state => state.selection); const computedNodes = useVisualizerStore(state => state.computedNodes); const selectNode = useVisualizerStore(state => state.selectNode); const selectedNode = selection.selectedNodeId ? computedNodes.get(selection.selectedNodeId) : null; if (!selectedNode) { return (

Click on a layer to view details

Use mouse to orbit, scroll to zoom

); } const category = LAYER_CATEGORIES[selectedNode.type]; return (

{selectedNode.name}

{category} {getLayerTypeName(selectedNode.type)}

Shapes

Input: {formatShape(selectedNode.inputShape)}
Output: {formatShape(selectedNode.outputShape)}
{selectedNode.attributes && Object.keys(selectedNode.attributes).length > 0 && (

Attributes

              {JSON.stringify(selectedNode.attributes, null, 2)}
            
)}

Position

({selectedNode.computedPosition.x.toFixed(2)},{' '} {selectedNode.computedPosition.y.toFixed(2)},{' '} {selectedNode.computedPosition.z.toFixed(2)})
); } export default InfoPanel;