import React from 'react'; import { cn } from '../../utils/cn'; import NodeItem from '../NodeItem'; import LinkItem from '../LinkItem'; import { PackageBoundaries } from '../PackageBoundaries'; import { DEFAULT_NODE_COLOR, DEFAULT_NODE_SIZE, DEFAULT_LINK_COLOR, DEFAULT_LINK_WIDTH, } from '../constants'; import { GraphNode, GraphLink, ForceDirectedGraphProps } from './types'; import { unpinAllNodes } from './useGraphInteractions'; interface GraphCanvasProps extends Pick< ForceDirectedGraphProps, | 'width' | 'height' | 'className' | 'selectedNodeId' | 'hoveredNodeId' | 'defaultNodeColor' | 'defaultNodeSize' | 'defaultLinkColor' | 'defaultLinkWidth' | 'showNodeLabels' | 'showLinkLabels' | 'onNodeClick' | 'onNodeHover' | 'onLinkClick' | 'packageBounds' > { svgRef: React.RefObject; gRef: React.RefObject; nodes: GraphNode[]; links: GraphLink[]; pinnedNodes: Set; handleNodeDoubleClick: (e: React.MouseEvent, node: GraphNode) => void; handleDragStart: (e: React.MouseEvent, node: GraphNode) => void; restart: () => void; setPinnedNodes: React.Dispatch>>; } export const GraphCanvas: React.FC = ({ svgRef, gRef, width, height, className, nodes, links, pinnedNodes, selectedNodeId, hoveredNodeId, defaultNodeColor = DEFAULT_NODE_COLOR, defaultNodeSize = DEFAULT_NODE_SIZE, defaultLinkColor = DEFAULT_LINK_COLOR, defaultLinkWidth = DEFAULT_LINK_WIDTH, showNodeLabels = true, showLinkLabels = false, onNodeClick, onNodeHover, onLinkClick, packageBounds, handleNodeDoubleClick, handleDragStart, restart, setPinnedNodes, }) => { return ( { unpinAllNodes(nodes); setPinnedNodes(new Set()); restart(); }} > {links.map((link, i) => ( ))} {nodes.map((node) => ( onNodeHover?.(n)} onMouseLeave={() => onNodeHover?.(null)} onMouseDown={handleDragStart} /> ))} ); };