@aiready/components 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/useForceSimulation.ts","../../src/utils/cn.ts","../../src/charts/ForceDirectedGraph.tsx"],"names":["d3","useRef","useState","useEffect","pack","zoom"],"mappings":"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","file":"ForceDirectedGraph.js","sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport * as d3 from 'd3';\n\nexport interface SimulationNode extends d3.SimulationNodeDatum {\n id: string;\n [key: string]: any;\n}\n\nexport interface SimulationLink extends d3.SimulationLinkDatum<SimulationNode> {\n source: string | SimulationNode;\n target: string | SimulationNode;\n [key: string]: any;\n}\n\nexport interface ForceSimulationOptions {\n /**\n * Strength of the charge force (repulsion between nodes)\n * @default -300\n */\n chargeStrength?: number;\n\n /**\n * Distance for links between nodes\n * @default 100\n */\n linkDistance?: number;\n\n /**\n * Strength of the link force\n * @default 1\n */\n linkStrength?: number;\n\n /**\n * Strength of collision detection\n * @default 1\n */\n collisionStrength?: number;\n\n /**\n * Radius for collision detection (node size)\n * @default 10\n */\n collisionRadius?: number;\n\n /**\n * Strength of centering force\n * @default 0.1\n */\n centerStrength?: number;\n\n /**\n * Width of the simulation space\n */\n width: number;\n\n /**\n * Height of the simulation space\n */\n height: number;\n\n /**\n * Alpha decay rate (how quickly the simulation cools down)\n * @default 0.0228\n */\n alphaDecay?: number;\n\n /**\n * Velocity decay (friction)\n * @default 0.4\n */\n velocityDecay?: number;\n\n /**\n * Optional tick callback invoked on each simulation tick with current nodes/links and the simulation instance\n */\n onTick?: (nodes: SimulationNode[], links: SimulationLink[], sim: d3.Simulation<SimulationNode, SimulationLink>) => void;\n}\n\nexport interface UseForceSimulationReturn {\n /**\n * Current nodes with positions\n */\n nodes: SimulationNode[];\n\n /**\n * Current links\n */\n links: SimulationLink[];\n\n /**\n * Restart the simulation\n */\n restart: () => void;\n\n /**\n * Stop the simulation\n */\n stop: () => void;\n\n /**\n * Whether the simulation is currently running\n */\n isRunning: boolean;\n\n /**\n * Current alpha value (simulation heat)\n */\n alpha: number;\n}\n\n/**\n * Hook for managing d3-force simulations\n * Automatically handles simulation lifecycle, tick updates, and cleanup\n *\n * @param initialNodes - Initial nodes for the simulation\n * @param initialLinks - Initial links for the simulation\n * @param options - Configuration options for the force simulation\n * @returns Simulation state and control functions\n *\n * @example\n * ```tsx\n * function NetworkGraph() {\n * const nodes = [\n * { id: 'node1', name: 'Node 1' },\n * { id: 'node2', name: 'Node 2' },\n * { id: 'node3', name: 'Node 3' },\n * ];\n *\n * const links = [\n * { source: 'node1', target: 'node2' },\n * { source: 'node2', target: 'node3' },\n * ];\n *\n * const { nodes: simulatedNodes, links: simulatedLinks, restart } = useForceSimulation(\n * nodes,\n * links,\n * {\n * width: 800,\n * height: 600,\n * chargeStrength: -500,\n * linkDistance: 150,\n * }\n * );\n *\n * return (\n * <svg width={800} height={600}>\n * {simulatedLinks.map((link, i) => (\n * <line\n * key={i}\n * x1={(link.source as SimulationNode).x}\n * y1={(link.source as SimulationNode).y}\n * x2={(link.target as SimulationNode).x}\n * y2={(link.target as SimulationNode).y}\n * stroke=\"#999\"\n * />\n * ))}\n * {simulatedNodes.map((node) => (\n * <circle\n * key={node.id}\n * cx={node.x}\n * cy={node.y}\n * r={10}\n * fill=\"#69b3a2\"\n * />\n * ))}\n * </svg>\n * );\n * }\n * ```\n */\nexport function useForceSimulation(\n initialNodes: SimulationNode[],\n initialLinks: SimulationLink[],\n options: ForceSimulationOptions\n): UseForceSimulationReturn & { setForcesEnabled: (enabled: boolean) => void } {\n const {\n chargeStrength = -300,\n linkDistance = 100,\n linkStrength = 1,\n collisionStrength = 1,\n collisionRadius = 10,\n centerStrength = 0.1,\n width,\n height,\n alphaDecay = 0.0228,\n velocityDecay = 0.4,\n onTick,\n } = options;\n\n const [nodes, setNodes] = useState<SimulationNode[]>(initialNodes);\n const [links, setLinks] = useState<SimulationLink[]>(initialLinks);\n const [isRunning, setIsRunning] = useState(false);\n const [alpha, setAlpha] = useState(1);\n\n const simulationRef = useRef<d3.Simulation<SimulationNode, SimulationLink> | null>(null);\n\n useEffect(() => {\n // Create a copy of nodes and links to avoid mutating the original data\n const nodesCopy = initialNodes.map((node) => ({ ...node }));\n const linksCopy = initialLinks.map((link) => ({ ...link }));\n\n // Create the simulation\n const simulation = d3\n .forceSimulation<SimulationNode>(nodesCopy)\n .force(\n 'link',\n d3\n .forceLink<SimulationNode, SimulationLink>(linksCopy)\n .id((d) => d.id)\n .distance((d: any) => (d && d.distance != null ? d.distance : linkDistance))\n .strength(linkStrength)\n )\n .force('charge', d3.forceManyBody().strength(chargeStrength))\n .force('center', d3.forceCenter(width / 2, height / 2).strength(centerStrength))\n .force(\n 'collision',\n d3\n .forceCollide<SimulationNode>()\n .radius((d: any) => {\n // Use node-specific size when available and add configured padding to ensure minimum spacing\n const nodeSize = (d && d.size) ? d.size : 10;\n return nodeSize + collisionRadius;\n })\n .strength(collisionStrength)\n )\n .alphaDecay(alphaDecay)\n .velocityDecay(velocityDecay);\n\n simulationRef.current = simulation;\n\n // Update state on each tick\n simulation.on('tick', () => {\n try {\n if (typeof onTick === 'function') onTick(nodesCopy, linksCopy, simulation);\n } catch (e) {\n // ignore user tick errors\n }\n setNodes([...nodesCopy]);\n setLinks([...linksCopy]);\n setAlpha(simulation.alpha());\n setIsRunning(simulation.alpha() > simulation.alphaMin());\n });\n\n simulation.on('end', () => {\n setIsRunning(false);\n });\n\n // Cleanup on unmount\n return () => {\n simulation.stop();\n };\n }, [\n initialNodes,\n initialLinks,\n chargeStrength,\n linkDistance,\n linkStrength,\n collisionStrength,\n collisionRadius,\n centerStrength,\n width,\n height,\n alphaDecay,\n velocityDecay,\n onTick,\n ]);\n\n const restart = () => {\n if (simulationRef.current) {\n simulationRef.current.alpha(1).restart();\n setIsRunning(true);\n }\n };\n\n const stop = () => {\n if (simulationRef.current) {\n simulationRef.current.stop();\n setIsRunning(false);\n }\n };\n\n const originalForcesRef = useRef({ charge: chargeStrength, link: linkStrength, collision: collisionStrength });\n const forcesEnabledRef = useRef(true);\n\n const setForcesEnabled = (enabled: boolean) => {\n const sim = simulationRef.current;\n if (!sim) return;\n // avoid repeated updates\n if (forcesEnabledRef.current === enabled) return;\n forcesEnabledRef.current = enabled;\n\n try {\n // Only toggle charge and link forces to avoid collapse; keep collision/centering\n const charge: any = sim.force('charge');\n if (charge && typeof charge.strength === 'function') {\n charge.strength(enabled ? originalForcesRef.current.charge : 0);\n }\n\n const link: any = sim.force('link');\n if (link && typeof link.strength === 'function') {\n link.strength(enabled ? originalForcesRef.current.link : 0);\n }\n } catch (e) {\n // ignore\n }\n };\n\n return {\n nodes,\n links,\n restart,\n stop,\n isRunning,\n alpha,\n setForcesEnabled,\n };\n}\n\n/**\n * Hook for creating a draggable force simulation\n * Provides drag handlers that can be attached to node elements\n *\n * @param simulation - The d3 force simulation instance\n * @returns Drag behavior that can be applied to nodes\n *\n * @example\n * ```tsx\n * function DraggableNetworkGraph() {\n * const simulation = useRef<d3.Simulation<SimulationNode, SimulationLink>>();\n * const drag = useDrag(simulation.current);\n *\n * return (\n * <svg>\n * {nodes.map((node) => (\n * <circle\n * key={node.id}\n * {...drag}\n * cx={node.x}\n * cy={node.y}\n * r={10}\n * />\n * ))}\n * </svg>\n * );\n * }\n * ```\n */\nexport function useDrag(simulation: d3.Simulation<SimulationNode, any> | null | undefined) {\n const dragStarted = (event: any, node: SimulationNode) => {\n if (!simulation) return;\n if (!event.active) simulation.alphaTarget(0.3).restart();\n node.fx = node.x;\n node.fy = node.y;\n };\n\n const dragged = (event: any, node: SimulationNode) => {\n node.fx = event.x;\n node.fy = event.y;\n };\n\n const dragEnded = (event: any, node: SimulationNode) => {\n if (!simulation) return;\n if (!event.active) simulation.alphaTarget(0);\n node.fx = null;\n node.fy = null;\n };\n\n return {\n onDragStart: dragStarted,\n onDrag: dragged,\n onDragEnd: dragEnded,\n };\n}","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merges class names using clsx and tailwind-merge\n * @param inputs - Class values to merge\n * @returns Merged class names\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import React, { useCallback, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';\nimport * as d3 from 'd3';\nimport {\n useForceSimulation,\n type SimulationNode,\n type SimulationLink,\n type ForceSimulationOptions,\n} from '../hooks/useForceSimulation';\nimport { cn } from '../utils/cn';\n\nexport interface GraphNode extends SimulationNode {\n id: string;\n label?: string;\n color?: string;\n size?: number;\n group?: string;\n}\n\nexport interface GraphLink extends SimulationLink {\n color?: string;\n width?: number;\n label?: string;\n}\n\nexport interface ForceDirectedGraphHandle {\n /**\n * Pin all nodes in place\n */\n pinAll: () => void;\n\n /**\n * Unpin all nodes (release constraints)\n */\n unpinAll: () => void;\n\n /**\n * Reset all nodes to auto-layout (unpin and restart simulation)\n */\n resetLayout: () => void;\n\n /**\n * Fit all nodes in the current view\n */\n fitView: () => void;\n\n /**\n * Get currently pinned node IDs\n */\n getPinnedNodes: () => string[];\n\n /**\n * Toggle dragging mode\n */\n setDragMode: (enabled: boolean) => void;\n}\n\nexport interface ForceDirectedGraphProps {\n /**\n * Array of nodes to display\n */\n nodes: GraphNode[];\n\n /**\n * Array of links between nodes\n */\n links: GraphLink[];\n\n /**\n * Width of the graph container\n */\n width: number;\n\n /**\n * Height of the graph container\n */\n height: number;\n\n /**\n * Force simulation options\n */\n simulationOptions?: Partial<ForceSimulationOptions>;\n\n /**\n * Whether to enable zoom and pan\n * @default true\n */\n enableZoom?: boolean;\n\n /**\n * Whether to enable node dragging\n * @default true\n */\n enableDrag?: boolean;\n\n /**\n * Callback when a node is clicked\n */\n onNodeClick?: (node: GraphNode) => void;\n\n /**\n * Callback when a node is hovered\n */\n onNodeHover?: (node: GraphNode | null) => void;\n\n /**\n * Callback when a link is clicked\n */\n onLinkClick?: (link: GraphLink) => void;\n\n /**\n * Selected node ID\n */\n selectedNodeId?: string;\n\n /**\n * Hovered node ID\n */\n hoveredNodeId?: string;\n\n /**\n * Default node color\n * @default \"#69b3a2\"\n */\n defaultNodeColor?: string;\n\n /**\n * Default node size\n * @default 10\n */\n defaultNodeSize?: number;\n\n /**\n * Default link color\n * @default \"#999\"\n */\n defaultLinkColor?: string;\n\n /**\n * Default link width\n * @default 1\n */\n defaultLinkWidth?: number;\n\n /**\n * Whether to show node labels\n * @default true\n */\n showNodeLabels?: boolean;\n\n /**\n * Whether to show link labels\n * @default false\n */\n showLinkLabels?: boolean;\n\n /**\n * Additional CSS classes\n */\n className?: string;\n\n /**\n * Manual layout mode: disables forces, allows free dragging\n * @default false\n */\n manualLayout?: boolean;\n\n /**\n * Callback when manual layout mode is toggled\n */\n onManualLayoutChange?: (enabled: boolean) => void;\n\n /**\n * Package bounds computed by the parent (pack layout): map of `pkg:group` -> {x,y,r}\n */\n packageBounds?: Record<string, { x: number; y: number; r: number }>;\n}\n\nexport const ForceDirectedGraph = forwardRef<ForceDirectedGraphHandle, ForceDirectedGraphProps>(\n (\n {\n nodes: initialNodes,\n links: initialLinks,\n width,\n height,\n simulationOptions,\n enableZoom = true,\n enableDrag = true,\n onNodeClick,\n onNodeHover,\n onLinkClick,\n selectedNodeId,\n hoveredNodeId,\n defaultNodeColor = '#69b3a2',\n defaultNodeSize = 10,\n defaultLinkColor = '#999',\n defaultLinkWidth = 1,\n showNodeLabels = true,\n showLinkLabels = false,\n className,\n manualLayout = false,\n onManualLayoutChange,\n packageBounds,\n },\n ref\n ) => {\n const svgRef = useRef<SVGSVGElement>(null);\n const gRef = useRef<SVGGElement>(null);\n const [transform, setTransform] = useState({ k: 1, x: 0, y: 0 });\n const dragNodeRef = useRef<GraphNode | null>(null);\n const dragActiveRef = useRef(false);\n const [pinnedNodes, setPinnedNodes] = useState<Set<string>>(new Set());\n const internalDragEnabledRef = useRef(enableDrag);\n\n // Update the ref when enableDrag prop changes\n useEffect(() => {\n internalDragEnabledRef.current = enableDrag;\n }, [enableDrag]);\n\n // Initialize simulation with manualLayout mode\n const onTick = (nodesCopy: any[], _linksCopy: any[], _sim: any) => {\n const bounds = packageBounds && Object.keys(packageBounds).length ? packageBounds : undefined;\n // fallback: if parent didn't provide packageBounds, compute locally from initialNodes\n let effectiveBounds = bounds;\n if (!effectiveBounds) {\n try {\n const counts: Record<string, number> = {};\n (initialNodes || []).forEach((n: any) => {\n if (n && n.kind === 'file') {\n const g = n.packageGroup || 'root';\n counts[g] = (counts[g] || 0) + 1;\n }\n });\n const children = Object.keys(counts).map((k) => ({ name: k, value: counts[k] }));\n if (children.length > 0) {\n const root = d3.hierarchy<any>({ children } as any).sum((d: any) => d.value as number);\n const pack = d3.pack().size([width, height]).padding(30);\n const packed = pack(root);\n const map: Record<string, { x: number; y: number; r: number }> = {};\n if (packed.children) {\n packed.children.forEach((c: any) => {\n map[`pkg:${c.data.name}`] = { x: c.x, y: c.y, r: c.r * 0.95 };\n });\n effectiveBounds = map;\n }\n }\n } catch (e) {\n // ignore fallback errors\n }\n }\n if (!effectiveBounds) return;\n try {\n Object.values(nodesCopy).forEach((n: any) => {\n if (!n) return;\n // only constrain file nodes (package nodes have their own fx/fy)\n if (n.kind === 'package') return;\n const pkg = n.packageGroup;\n if (!pkg) return;\n const bound = effectiveBounds[`pkg:${pkg}`];\n if (!bound) return;\n const margin = (n.size || 10) + 12;\n const dx = (n.x || 0) - bound.x;\n const dy = (n.y || 0) - bound.y;\n const dist = Math.sqrt(dx * dx + dy * dy) || 0.0001;\n const maxDist = Math.max(1, bound.r - margin);\n if (dist > maxDist) {\n const desiredX = bound.x + dx * (maxDist / dist);\n const desiredY = bound.y + dy * (maxDist / dist);\n // apply a soft corrective velocity toward the desired position\n const softness = 0.08;\n n.vx = (n.vx || 0) + (desiredX - n.x) * softness;\n n.vy = (n.vy || 0) + (desiredY - n.y) * softness;\n }\n });\n } catch (e) {\n // ignore\n }\n };\n\n const { nodes, links, restart, stop, setForcesEnabled } = useForceSimulation(initialNodes, initialLinks, {\n width,\n height,\n chargeStrength: manualLayout ? 0 : undefined,\n onTick,\n ...simulationOptions,\n });\n\n // If package bounds are provided, add a tick-time clamp via the hook's onTick option\n useEffect(() => {\n if (!packageBounds) return;\n // nothing to do here because the hook will call onTick passed in creation; we need to recreate simulation to use onTick\n // So restart the simulation to pick up potential changes in node bounds.\n try { restart(); } catch (e) {}\n }, [packageBounds, restart]);\n\n // If manual layout is enabled or any nodes are pinned, disable forces\n useEffect(() => {\n try {\n if (manualLayout || pinnedNodes.size > 0) setForcesEnabled(false);\n else setForcesEnabled(true);\n } catch (e) {\n // ignore\n }\n }, [manualLayout, pinnedNodes, setForcesEnabled]);\n\n // Expose imperative handle for parent components\n useImperativeHandle(\n ref,\n () => ({\n pinAll: () => {\n const newPinned = new Set<string>();\n nodes.forEach((node) => {\n node.fx = node.x;\n node.fy = node.y;\n newPinned.add(node.id);\n });\n setPinnedNodes(newPinned);\n restart();\n },\n\n unpinAll: () => {\n nodes.forEach((node) => {\n node.fx = null;\n node.fy = null;\n });\n setPinnedNodes(new Set());\n restart();\n },\n\n resetLayout: () => {\n nodes.forEach((node) => {\n node.fx = null;\n node.fy = null;\n });\n setPinnedNodes(new Set());\n restart();\n },\n\n fitView: () => {\n if (!svgRef.current || !nodes.length) return;\n\n // Calculate bounds\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n nodes.forEach((node) => {\n if (node.x !== undefined && node.y !== undefined) {\n const size = node.size || 10;\n minX = Math.min(minX, node.x - size);\n maxX = Math.max(maxX, node.x + size);\n minY = Math.min(minY, node.y - size);\n maxY = Math.max(maxY, node.y + size);\n }\n });\n\n if (!isFinite(minX)) return;\n\n const padding = 40;\n const nodeWidth = maxX - minX;\n const nodeHeight = maxY - minY;\n const scale = Math.min(\n (width - padding * 2) / nodeWidth,\n (height - padding * 2) / nodeHeight,\n 10\n );\n\n const centerX = (minX + maxX) / 2;\n const centerY = (minY + maxY) / 2;\n\n const x = width / 2 - centerX * scale;\n const y = height / 2 - centerY * scale;\n\n if (gRef.current && svgRef.current) {\n const svg = d3.select(svgRef.current);\n const newTransform = d3.zoomIdentity.translate(x, y).scale(scale);\n svg.transition().duration(300).call(d3.zoom<SVGSVGElement, unknown>().transform as any, newTransform);\n setTransform(newTransform);\n }\n },\n\n getPinnedNodes: () => Array.from(pinnedNodes),\n\n setDragMode: (enabled: boolean) => {\n internalDragEnabledRef.current = enabled;\n },\n }),\n [nodes, pinnedNodes, restart, width, height]\n );\n\n // Notify parent when manual layout mode changes (uses the prop so it's not unused)\n useEffect(() => {\n try {\n if (typeof onManualLayoutChange === 'function') onManualLayoutChange(manualLayout);\n } catch (e) {\n // ignore errors from callbacks\n }\n }, [manualLayout, onManualLayoutChange]);\n\n // Set up zoom behavior\n useEffect(() => {\n if (!enableZoom || !svgRef.current || !gRef.current) return;\n\n const svg = d3.select(svgRef.current);\n const g = d3.select(gRef.current);\n\n const zoom = d3\n .zoom<SVGSVGElement, unknown>()\n .scaleExtent([0.1, 10])\n .on('zoom', (event) => {\n g.attr('transform', event.transform);\n setTransform(event.transform);\n });\n\n svg.call(zoom);\n\n return () => {\n svg.on('.zoom', null);\n };\n }, [enableZoom]);\n\n // Set up drag behavior with global listeners for smoother dragging\n const handleDragStart = useCallback(\n (event: React.MouseEvent, node: GraphNode) => {\n if (!enableDrag) return;\n event.preventDefault();\n event.stopPropagation();\n // pause forces while dragging to avoid the whole graph moving\n dragActiveRef.current = true;\n dragNodeRef.current = node;\n node.fx = node.x;\n node.fy = node.y;\n setPinnedNodes((prev) => new Set([...prev, node.id]));\n try { stop(); } catch (e) {}\n },\n [enableDrag, restart]\n );\n\n useEffect(() => {\n if (!enableDrag) return;\n\n const handleWindowMove = (event: MouseEvent) => {\n if (!dragActiveRef.current || !dragNodeRef.current) return;\n const svg = svgRef.current;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const x = (event.clientX - rect.left - transform.x) / transform.k;\n const y = (event.clientY - rect.top - transform.y) / transform.k;\n dragNodeRef.current.fx = x;\n dragNodeRef.current.fy = y;\n };\n\n const handleWindowUp = () => {\n if (!dragActiveRef.current) return;\n // Keep fx/fy set to pin the node where it was dropped.\n try { setForcesEnabled(true); restart(); } catch (e) {}\n dragNodeRef.current = null;\n dragActiveRef.current = false;\n };\n\n const handleWindowLeave = (event: MouseEvent) => {\n if (event.relatedTarget === null) handleWindowUp();\n };\n\n window.addEventListener('mousemove', handleWindowMove);\n window.addEventListener('mouseup', handleWindowUp);\n window.addEventListener('mouseout', handleWindowLeave);\n window.addEventListener('blur', handleWindowUp);\n\n return () => {\n window.removeEventListener('mousemove', handleWindowMove);\n window.removeEventListener('mouseup', handleWindowUp);\n window.removeEventListener('mouseout', handleWindowLeave);\n window.removeEventListener('blur', handleWindowUp);\n };\n }, [enableDrag, transform]);\n\n // Attach d3.drag behavior to node groups rendered by React. This helps make\n // dragging more robust across transforms and pointer behaviors.\n useEffect(() => {\n if (!gRef.current || !enableDrag) return;\n const g = d3.select(gRef.current);\n const dragBehavior = d3\n .drag<SVGGElement, unknown>()\n .on('start', function (event) {\n try {\n const target = (event.sourceEvent && (event.sourceEvent.target as Element)) || (event.target as Element);\n const grp = target.closest?.('g.node') as Element | null;\n const id = grp?.getAttribute('data-id');\n if (!id) return;\n const node = nodes.find((n) => n.id === id) as GraphNode | undefined;\n if (!node) return;\n if (!internalDragEnabledRef.current) return;\n if (!event.active) restart();\n dragActiveRef.current = true;\n dragNodeRef.current = node;\n node.fx = node.x;\n node.fy = node.y;\n setPinnedNodes((prev) => new Set([...prev, node.id]));\n } catch (e) {\n // ignore\n }\n })\n .on('drag', function (event) {\n if (!dragActiveRef.current || !dragNodeRef.current) return;\n const svg = svgRef.current;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const x = (event.sourceEvent.clientX - rect.left - transform.x) / transform.k;\n const y = (event.sourceEvent.clientY - rect.top - transform.y) / transform.k;\n dragNodeRef.current.fx = x;\n dragNodeRef.current.fy = y;\n })\n .on('end', function () {\n // re-enable forces when drag ends\n try { setForcesEnabled(true); restart(); } catch (e) {}\n dragNodeRef.current = null;\n dragActiveRef.current = false;\n });\n\n try {\n g.selectAll('g.node').call(dragBehavior as any);\n } catch (e) {\n // ignore attach errors\n }\n\n return () => {\n try {\n g.selectAll('g.node').on('.drag', null as any);\n } catch (e) {\n /* ignore */\n }\n };\n }, [gRef, enableDrag, nodes, transform, restart]);\n\n const handleNodeClick = useCallback(\n (node: GraphNode) => {\n onNodeClick?.(node);\n },\n [onNodeClick]\n );\n\n const handleNodeDoubleClick = useCallback(\n (event: React.MouseEvent, node: GraphNode) => {\n event.stopPropagation();\n if (!enableDrag) return;\n if (node.fx === null || node.fx === undefined) {\n node.fx = node.x;\n node.fy = node.y;\n setPinnedNodes((prev) => new Set([...prev, node.id]));\n } else {\n node.fx = null;\n node.fy = null;\n setPinnedNodes((prev) => {\n const next = new Set(prev);\n next.delete(node.id);\n return next;\n });\n }\n restart();\n },\n [enableDrag, restart]\n );\n\n const handleCanvasDoubleClick = useCallback(() => {\n nodes.forEach((node) => {\n node.fx = null;\n node.fy = null;\n });\n setPinnedNodes(new Set());\n restart();\n }, [nodes, restart]);\n\n const handleNodeMouseEnter = useCallback(\n (node: GraphNode) => {\n onNodeHover?.(node);\n },\n [onNodeHover]\n );\n\n const handleNodeMouseLeave = useCallback(() => {\n onNodeHover?.(null);\n }, [onNodeHover]);\n\n const handleLinkClick = useCallback(\n (link: GraphLink) => {\n onLinkClick?.(link);\n },\n [onLinkClick]\n );\n\n return (\n <svg\n ref={svgRef}\n width={width}\n height={height}\n className={cn('bg-white dark:bg-gray-900', className)}\n onDoubleClick={handleCanvasDoubleClick}\n >\n <defs>\n {/* Arrow marker for directed graphs */}\n <marker\n id=\"arrow\"\n viewBox=\"0 0 10 10\"\n refX=\"20\"\n refY=\"5\"\n markerWidth=\"6\"\n markerHeight=\"6\"\n orient=\"auto\"\n >\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill={defaultLinkColor} />\n </marker>\n </defs>\n\n <g ref={gRef}>\n \n {/* Render links */}\n {links.map((link, i) => {\n const source = link.source as GraphNode;\n const target = link.target as GraphNode;\n if (source.x == null || source.y == null || target.x == null || target.y == null) return null;\n\n return (\n <g key={`link-${i}`}>\n <line\n x1={source.x}\n y1={source.y}\n x2={target.x}\n y2={target.y}\n stroke={link.color || defaultLinkColor}\n strokeWidth={link.width || defaultLinkWidth}\n opacity={0.6}\n className=\"cursor-pointer transition-opacity hover:opacity-100\"\n onClick={() => handleLinkClick(link)}\n />\n {showLinkLabels && link.label && (\n <text\n x={(source.x + target.x) / 2}\n y={(source.y + target.y) / 2}\n fill=\"#666\"\n fontSize=\"10\"\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n pointerEvents=\"none\"\n >\n {link.label}\n </text>\n )}\n </g>\n );\n })}\n\n {/* Render nodes */}\n {nodes.map((node) => {\n if (node.x == null || node.y == null) return null;\n\n const isSelected = selectedNodeId === node.id;\n const isHovered = hoveredNodeId === node.id;\n const nodeSize = node.size || defaultNodeSize;\n const nodeColor = node.color || defaultNodeColor;\n\n return (\n <g\n key={node.id}\n transform={`translate(${node.x},${node.y})`}\n className=\"cursor-pointer node\"\n data-id={node.id}\n onClick={() => handleNodeClick(node)}\n onDoubleClick={(event) => handleNodeDoubleClick(event, node)}\n onMouseEnter={() => handleNodeMouseEnter(node)}\n onMouseLeave={handleNodeMouseLeave}\n onMouseDown={(e) => handleDragStart(e, node)}\n >\n <circle\n r={nodeSize}\n fill={nodeColor}\n stroke={isSelected ? '#000' : isHovered ? '#666' : 'none'}\n strokeWidth={pinnedNodes.has(node.id) ? 3 : isSelected ? 2.5 : isHovered ? 2 : 1.5}\n opacity={isHovered || isSelected ? 1 : 0.9}\n className=\"transition-all\"\n />\n {pinnedNodes.has(node.id) && (\n <circle\n r={nodeSize + 4}\n fill=\"none\"\n stroke=\"#ff6b6b\"\n strokeWidth={1}\n opacity={0.5}\n className=\"pointer-events-none\"\n />\n )}\n {showNodeLabels && node.label && (\n <text\n y={nodeSize + 15}\n fill=\"#333\"\n fontSize=\"12\"\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n pointerEvents=\"none\"\n className=\"select-none\"\n >\n {node.label}\n </text>\n )}\n </g>\n );\n })}\n {/* Package boundary circles (from parent pack layout) - drawn on top for visibility */}\n {packageBounds && Object.keys(packageBounds).length > 0 && (\n <g className=\"package-boundaries\" pointerEvents=\"none\">\n {Object.entries(packageBounds).map(([pid, b]) => (\n <g key={pid}>\n <circle\n cx={b.x}\n cy={b.y}\n r={b.r}\n fill=\"rgba(148,163,184,0.06)\"\n stroke=\"#475569\"\n strokeWidth={2}\n strokeDasharray=\"6 6\"\n opacity={0.9}\n />\n <text\n x={b.x}\n y={Math.max(12, b.y - b.r + 14)}\n fill=\"#475569\"\n fontSize={11}\n textAnchor=\"middle\"\n pointerEvents=\"none\"\n >\n {pid.replace(/^pkg:/, '')}\n </text>\n </g>\n ))}\n </g>\n )}\n </g>\n </svg>\n );\n }\n);\n\nForceDirectedGraph.displayName = 'ForceDirectedGraph';"]}
1
+ {"version":3,"sources":["../../src/hooks/useForceSimulation.ts","../../src/utils/cn.ts","../../src/charts/NodeItem.tsx","../../src/charts/LinkItem.tsx","../../src/charts/ForceDirectedGraph.tsx"],"names":["d3","e","jsxs","jsx","useRef","useState","useEffect","pack","packageAreas","localPositions","zoom"],"mappings":"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","file":"ForceDirectedGraph.js","sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport * as d3 from 'd3';\n\nexport interface SimulationNode extends d3.SimulationNodeDatum {\n id: string;\n [key: string]: any;\n}\n\nexport interface SimulationLink extends d3.SimulationLinkDatum<SimulationNode> {\n source: string | SimulationNode;\n target: string | SimulationNode;\n [key: string]: any;\n}\n\nexport interface ForceSimulationOptions {\n /**\n * Strength of the charge force (repulsion between nodes)\n * @default -300\n */\n chargeStrength?: number;\n\n /**\n * Distance for links between nodes\n * @default 100\n */\n linkDistance?: number;\n\n /**\n * Strength of the link force\n * @default 1\n */\n linkStrength?: number;\n\n /**\n * Strength of collision detection\n * @default 1\n */\n collisionStrength?: number;\n\n /**\n * Radius for collision detection (node size)\n * @default 10\n */\n collisionRadius?: number;\n\n /**\n * Strength of centering force\n * @default 0.1\n */\n centerStrength?: number;\n\n /**\n * Width of the simulation space\n */\n width: number;\n\n /**\n * Height of the simulation space\n */\n height: number;\n\n /**\n * Alpha decay rate (how quickly the simulation cools down)\n * @default 0.0228\n */\n alphaDecay?: number;\n\n /**\n * Alpha target controls the resting energy of the simulation. When set to 0\n * the simulation will cool and stop moving once forces settle. Increase to\n * keep the graph more dynamic.\n * @default 0\n */\n alphaTarget?: number;\n\n /**\n * Warm alpha used when (re)starting the simulation to give it a small amount\n * of energy. This mirrors the Observable example which sets a modest\n * alphaTarget when dragging instead of forcing alpha to 1.\n * @default 0.3\n */\n warmAlpha?: number;\n\n /**\n * Minimum alpha threshold below which the simulation is considered cooled\n * and will stop. Increasing this makes the simulation stop earlier.\n * @default 0.01\n */\n alphaMin?: number;\n\n /**\n * When true, zero node velocities and snap positions when the simulation\n * stops to reduce residual jitter.\n * @default true\n */\n stabilizeOnStop?: boolean;\n\n /**\n * Maximum time (ms) to allow the simulation to run after creation/restart.\n * If the simulation hasn't cooled by this time, it will be force-stopped\n * to prevent indefinite animation. Set to 0 to disable.\n * @default 3000\n */\n maxSimulationTimeMs?: number;\n\n /**\n * Velocity decay (friction)\n * @default 0.4\n */\n velocityDecay?: number;\n\n /**\n * Optional tick callback invoked on each simulation tick with current nodes/links and the simulation instance\n */\n onTick?: (nodes: SimulationNode[], links: SimulationLink[], sim: d3.Simulation<SimulationNode, SimulationLink>) => void;\n}\n\nexport interface UseForceSimulationReturn {\n /**\n * Current nodes with positions\n */\n nodes: SimulationNode[];\n\n /**\n * Current links\n */\n links: SimulationLink[];\n\n /**\n * Restart the simulation\n */\n restart: () => void;\n\n /**\n * Stop the simulation\n */\n stop: () => void;\n\n /**\n * Whether the simulation is currently running\n */\n isRunning: boolean;\n\n /**\n * Current alpha value (simulation heat)\n */\n alpha: number;\n}\n\n/**\n * Hook for managing d3-force simulations\n * Automatically handles simulation lifecycle, tick updates, and cleanup\n *\n * @param initialNodes - Initial nodes for the simulation\n * @param initialLinks - Initial links for the simulation\n * @param options - Configuration options for the force simulation\n * @returns Simulation state and control functions\n *\n * @example\n * ```tsx\n * function NetworkGraph() {\n * const nodes = [\n * { id: 'node1', name: 'Node 1' },\n * { id: 'node2', name: 'Node 2' },\n * { id: 'node3', name: 'Node 3' },\n * ];\n *\n * const links = [\n * { source: 'node1', target: 'node2' },\n * { source: 'node2', target: 'node3' },\n * ];\n *\n * const { nodes: simulatedNodes, links: simulatedLinks, restart } = useForceSimulation(\n * nodes,\n * links,\n * {\n * width: 800,\n * height: 600,\n * chargeStrength: -500,\n * linkDistance: 150,\n * }\n * );\n *\n * return (\n * <svg width={800} height={600}>\n * {simulatedLinks.map((link, i) => (\n * <line\n * key={i}\n * x1={(link.source as SimulationNode).x}\n * y1={(link.source as SimulationNode).y}\n * x2={(link.target as SimulationNode).x}\n * y2={(link.target as SimulationNode).y}\n * stroke=\"#999\"\n * />\n * ))}\n * {simulatedNodes.map((node) => (\n * <circle\n * key={node.id}\n * cx={node.x}\n * cy={node.y}\n * r={10}\n * fill=\"#69b3a2\"\n * />\n * ))}\n * </svg>\n * );\n * }\n * ```\n */\nexport function useForceSimulation(\n initialNodes: SimulationNode[],\n initialLinks: SimulationLink[],\n options: ForceSimulationOptions\n): UseForceSimulationReturn & { setForcesEnabled: (enabled: boolean) => void } {\n const {\n chargeStrength = -300,\n linkDistance = 100,\n linkStrength = 1,\n collisionStrength = 1,\n collisionRadius = 10,\n centerStrength = 0.1,\n width,\n height,\n alphaDecay = 0.0228,\n velocityDecay = 0.4,\n alphaTarget = 0,\n warmAlpha = 0.3,\n alphaMin = 0.01,\n // @ts-ignore allow extra option\n stabilizeOnStop = true,\n onTick,\n // Optional throttle in milliseconds for tick updates (reduce React re-renders)\n // Lower values = smoother but more CPU; default ~30ms (~33fps)\n // @ts-ignore allow extra option\n tickThrottleMs = 33,\n // @ts-ignore allow extra option\n maxSimulationTimeMs = 3000,\n } = options;\n\n const [nodes, setNodes] = useState<SimulationNode[]>(initialNodes);\n const [links, setLinks] = useState<SimulationLink[]>(initialLinks);\n const [isRunning, setIsRunning] = useState(false);\n const [alpha, setAlpha] = useState(1);\n\n const simulationRef = useRef<d3.Simulation<SimulationNode, SimulationLink> | null>(null);\n const stopTimeoutRef = useRef<number | null>(null);\n\n // Create lightweight keys for nodes/links so we only recreate the simulation\n // when the actual identity/content of inputs change (not when parent passes\n // new array references on each render).\n const nodesKey = initialNodes.map((n) => n.id).join('|');\n const linksKey = (initialLinks || []).map((l) => {\n const s = typeof l.source === 'string' ? l.source : (l.source as any)?.id;\n const t = typeof l.target === 'string' ? l.target : (l.target as any)?.id;\n return `${s}->${t}:${(l as any).type || ''}`;\n }).join('|');\n\n useEffect(() => {\n // Create a copy of nodes and links to avoid mutating the original data\n const nodesCopy = initialNodes.map((node) => ({ ...node }));\n const linksCopy = initialLinks.map((link) => ({ ...link }));\n\n // ALWAYS seed initial positions to ensure nodes don't stack at origin\n // This is critical for force-directed graphs to work properly\n try {\n // Always seed positions for all nodes when simulation is created\n // This ensures nodes start spread out even if they have coordinates\n nodesCopy.forEach((n, i) => {\n // Use deterministic but more widely spread positions based on index\n const angle = (i * 2 * Math.PI) / nodesCopy.length;\n // Larger seed radius to encourage an initial spread\n const radius = Math.min(width, height) * 0.45;\n n.x = width / 2 + radius * Math.cos(angle);\n n.y = height / 2 + radius * Math.sin(angle);\n // Add very small random velocity to avoid large initial motion\n (n as any).vx = (Math.random() - 0.5) * 2;\n (n as any).vy = (Math.random() - 0.5) * 2;\n });\n } catch (e) {\n // If error, fall back to random positions\n nodesCopy.forEach((n) => {\n n.x = Math.random() * width;\n n.y = Math.random() * height;\n (n as any).vx = (Math.random() - 0.5) * 10;\n (n as any).vy = (Math.random() - 0.5) * 10;\n });\n }\n\n // Create the simulation\n const simulation = (d3.forceSimulation(nodesCopy as any) as unknown) as d3.Simulation<SimulationNode, SimulationLink>;\n\n // Configure link force separately to avoid using generic type args on d3 helpers\n try {\n const linkForce = (d3.forceLink(linksCopy as any) as unknown) as d3.ForceLink<SimulationNode, SimulationLink>;\n linkForce.id((d: any) => d.id).distance((d: any) => (d && d.distance != null ? d.distance : linkDistance)).strength(linkStrength);\n simulation.force('link', linkForce as any);\n } catch (e) {\n // fallback: attach a plain link force\n try { simulation.force('link', d3.forceLink(linksCopy as any) as any); } catch (e) {}\n }\n ;\n\n try {\n simulation.force('charge', d3.forceManyBody().strength(chargeStrength) as any);\n simulation.force('center', d3.forceCenter(width / 2, height / 2).strength(centerStrength) as any);\n const collide = d3.forceCollide().radius((d: any) => {\n const nodeSize = (d && d.size) ? d.size : 10;\n return nodeSize + collisionRadius;\n }).strength(collisionStrength as any) as any;\n simulation.force('collision', collide);\n simulation.force('x', d3.forceX(width / 2).strength(Math.max(0.02, centerStrength * 0.5)) as any);\n simulation.force('y', d3.forceY(height / 2).strength(Math.max(0.02, centerStrength * 0.5)) as any);\n simulation.alphaDecay(alphaDecay);\n simulation.velocityDecay(velocityDecay);\n simulation.alphaMin(alphaMin);\n try { simulation.alphaTarget(alphaTarget); } catch (e) {}\n try { simulation.alpha(warmAlpha); } catch (e) {}\n } catch (e) {\n // ignore force configuration errors\n }\n\n simulationRef.current = simulation;\n\n // Force-stop timeout to ensure simulation doesn't run forever.\n if (stopTimeoutRef.current != null) {\n try { (globalThis.clearTimeout as any)(stopTimeoutRef.current); } catch (e) {}\n stopTimeoutRef.current = null;\n }\n if (maxSimulationTimeMs && maxSimulationTimeMs > 0) {\n stopTimeoutRef.current = (globalThis.setTimeout as any)(() => {\n try {\n if (stabilizeOnStop) {\n nodesCopy.forEach((n) => {\n (n as any).vx = 0;\n (n as any).vy = 0;\n if (typeof n.x === 'number') n.x = Number(n.x.toFixed(3));\n if (typeof n.y === 'number') n.y = Number(n.y.toFixed(3));\n });\n }\n simulation.alpha(0);\n simulation.stop();\n } catch (e) {}\n setIsRunning(false);\n setNodes([...nodesCopy]);\n setLinks([...linksCopy]);\n }, maxSimulationTimeMs) as unknown as number;\n }\n\n // Update state on each tick. Batch updates via requestAnimationFrame to avoid\n // excessive React re-renders which can cause visual flicker.\n let rafId: number | null = null;\n let lastUpdate = 0;\n const tickHandler = () => {\n try {\n if (typeof onTick === 'function') onTick(nodesCopy, linksCopy, simulation);\n } catch (e) {\n // ignore user tick errors\n }\n\n // If simulation alpha has cooled below the configured minimum, stop it to\n // ensure nodes don't drift indefinitely (acts as a hard-stop safeguard).\n try {\n if (simulation.alpha() <= (alphaMin as number)) {\n try {\n if (stabilizeOnStop) {\n nodesCopy.forEach((n) => {\n (n as any).vx = 0;\n (n as any).vy = 0;\n if (typeof n.x === 'number') n.x = Number(n.x.toFixed(3));\n if (typeof n.y === 'number') n.y = Number(n.y.toFixed(3));\n });\n }\n simulation.stop();\n } catch (e) {}\n setAlpha(simulation.alpha());\n setIsRunning(false);\n setNodes([...nodesCopy]);\n setLinks([...linksCopy]);\n return;\n }\n } catch (e) {\n // ignore\n }\n\n const now = Date.now();\n const shouldUpdate = now - lastUpdate >= (tickThrottleMs as number);\n if (rafId == null && shouldUpdate) {\n rafId = (globalThis.requestAnimationFrame || ((cb: FrameRequestCallback) => setTimeout(cb, 16)))(() => {\n rafId = null;\n lastUpdate = Date.now();\n setNodes([...nodesCopy]);\n setLinks([...linksCopy]);\n setAlpha(simulation.alpha());\n setIsRunning(simulation.alpha() > simulation.alphaMin());\n }) as unknown as number;\n }\n };\n\n simulation.on('tick', tickHandler);\n\n simulation.on('end', () => {\n setIsRunning(false);\n });\n\n // Cleanup on unmount\n return () => {\n try {\n simulation.on('tick', null as any);\n } catch (e) {}\n if (stopTimeoutRef.current != null) {\n try { (globalThis.clearTimeout as any)(stopTimeoutRef.current); } catch (e) {}\n stopTimeoutRef.current = null;\n }\n if (rafId != null) {\n try { (globalThis.cancelAnimationFrame || ((id: number) => clearTimeout(id)))(rafId); } catch (e) {}\n rafId = null;\n }\n simulation.stop();\n };\n }, [\n nodesKey,\n linksKey,\n chargeStrength,\n linkDistance,\n linkStrength,\n collisionStrength,\n collisionRadius,\n centerStrength,\n width,\n height,\n alphaDecay,\n velocityDecay,\n alphaTarget,\n alphaMin,\n stabilizeOnStop,\n tickThrottleMs,\n maxSimulationTimeMs,\n ]);\n\n const restart = () => {\n if (simulationRef.current) {\n // Reheat the simulation to a modest alpha target rather than forcing\n // full heat; this matches the Observable pattern and helps stability.\n try { simulationRef.current.alphaTarget(warmAlpha).restart(); } catch (e) { simulationRef.current.restart(); }\n setIsRunning(true);\n // Reset safety timeout when simulation is manually restarted\n if (stopTimeoutRef.current != null) {\n try { (globalThis.clearTimeout as any)(stopTimeoutRef.current); } catch (e) {}\n stopTimeoutRef.current = null;\n }\n if (maxSimulationTimeMs && maxSimulationTimeMs > 0) {\n stopTimeoutRef.current = (globalThis.setTimeout as any)(() => {\n try { simulationRef.current?.alpha(0); simulationRef.current?.stop(); } catch (e) {}\n setIsRunning(false);\n }, maxSimulationTimeMs) as unknown as number;\n }\n }\n };\n\n const stop = () => {\n if (simulationRef.current) {\n simulationRef.current.stop();\n setIsRunning(false);\n }\n };\n\n const originalForcesRef = useRef({ charge: chargeStrength, link: linkStrength, collision: collisionStrength });\n const forcesEnabledRef = useRef(true);\n\n const setForcesEnabled = (enabled: boolean) => {\n const sim = simulationRef.current;\n if (!sim) return;\n // avoid repeated updates\n if (forcesEnabledRef.current === enabled) return;\n forcesEnabledRef.current = enabled;\n\n try {\n // Only toggle charge and link forces to avoid collapse; keep collision/centering\n const charge: any = sim.force('charge');\n if (charge && typeof charge.strength === 'function') {\n charge.strength(enabled ? originalForcesRef.current.charge : 0);\n }\n\n const link: any = sim.force('link');\n if (link && typeof link.strength === 'function') {\n link.strength(enabled ? originalForcesRef.current.link : 0);\n }\n } catch (e) {\n // ignore\n }\n };\n\n return {\n nodes,\n links,\n restart,\n stop,\n isRunning,\n alpha,\n setForcesEnabled,\n };\n}\n\n/**\n * Hook for creating a draggable force simulation\n * Provides drag handlers that can be attached to node elements\n *\n * @param simulation - The d3 force simulation instance\n * @returns Drag behavior that can be applied to nodes\n *\n * @example\n * ```tsx\n * function DraggableNetworkGraph() {\n * const simulation = useRef<d3.Simulation<SimulationNode, SimulationLink>>();\n * const drag = useDrag(simulation.current);\n *\n * return (\n * <svg>\n * {nodes.map((node) => (\n * <circle\n * key={node.id}\n * {...drag}\n * cx={node.x}\n * cy={node.y}\n * r={10}\n * />\n * ))}\n * </svg>\n * );\n * }\n * ```\n */\nexport function useDrag(simulation: d3.Simulation<SimulationNode, any> | null | undefined) {\n const dragStarted = (event: any, node: SimulationNode) => {\n if (!simulation) return;\n if (!event.active) simulation.alphaTarget(0.3).restart();\n node.fx = node.x;\n node.fy = node.y;\n };\n\n const dragged = (event: any, node: SimulationNode) => {\n node.fx = event.x;\n node.fy = event.y;\n };\n\n const dragEnded = (event: any, node: SimulationNode) => {\n if (!simulation) return;\n if (!event.active) simulation.alphaTarget(0);\n node.fx = null;\n node.fy = null;\n };\n\n return {\n onDragStart: dragStarted,\n onDrag: dragged,\n onDragEnd: dragEnded,\n };\n}","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Merges class names using clsx and tailwind-merge\n * @param inputs - Class values to merge\n * @returns Merged class names\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}","import React from 'react';\nimport type { GraphNode } from './ForceDirectedGraph';\n\nexport interface NodeItemProps {\n node: GraphNode;\n isSelected: boolean;\n isHovered: boolean;\n pinned: boolean;\n defaultNodeSize: number;\n defaultNodeColor: string;\n showLabel?: boolean;\n onClick?: (n: GraphNode) => void;\n onDoubleClick?: (e: React.MouseEvent, n: GraphNode) => void;\n onMouseEnter?: (n: GraphNode) => void;\n onMouseLeave?: () => void;\n onMouseDown?: (e: React.MouseEvent, n: GraphNode) => void;\n}\n\nexport const NodeItem: React.FC<NodeItemProps> = ({\n node,\n isSelected,\n isHovered,\n pinned,\n defaultNodeSize,\n defaultNodeColor,\n showLabel = true,\n onClick,\n onDoubleClick,\n onMouseEnter,\n onMouseLeave,\n onMouseDown,\n}) => {\n const nodeSize = node.size || defaultNodeSize;\n const nodeColor = node.color || defaultNodeColor;\n\n const x = node.x ?? 0;\n const y = node.y ?? 0;\n\n return (\n <g\n key={node.id}\n className=\"cursor-pointer node\"\n data-id={node.id}\n transform={`translate(${x},${y})`}\n onClick={() => onClick?.(node)}\n onDoubleClick={(e) => onDoubleClick?.(e, node)}\n onMouseEnter={() => onMouseEnter?.(node)}\n onMouseLeave={() => onMouseLeave?.()}\n onMouseDown={(e) => onMouseDown?.(e, node)}\n >\n <circle\n r={nodeSize}\n fill={nodeColor}\n stroke={isSelected ? '#000' : isHovered ? '#666' : 'none'}\n strokeWidth={pinned ? 3 : isSelected ? 2.5 : isHovered ? 2 : 1.5}\n opacity={isHovered || isSelected ? 1 : 0.9}\n />\n {pinned && (\n <circle r={nodeSize + 4} fill=\"none\" stroke=\"#ff6b6b\" strokeWidth={1} opacity={0.5} className=\"pointer-events-none\" />\n )}\n {showLabel && node.label && (\n <text y={nodeSize + 15} fill=\"#333\" fontSize=\"12\" textAnchor=\"middle\" dominantBaseline=\"middle\" pointerEvents=\"none\" className=\"select-none\">\n {node.label}\n </text>\n )}\n </g>\n );\n};\n\nexport default NodeItem;\n","import React from 'react';\nimport type { GraphLink, GraphNode } from './ForceDirectedGraph';\n\nexport interface LinkItemProps {\n link: GraphLink;\n onClick?: (l: GraphLink) => void;\n defaultWidth?: number;\n showLabel?: boolean;\n nodes?: GraphNode[]; // Optional nodes array to resolve string IDs to node objects\n}\n\nexport const LinkItem: React.FC<LinkItemProps> = ({ link, onClick, defaultWidth, showLabel = true, nodes = [] }) => {\n const src = (link.source as any)?.id ?? (typeof link.source === 'string' ? link.source : undefined);\n const tgt = (link.target as any)?.id ?? (typeof link.target === 'string' ? link.target : undefined);\n\n // Helper to get node position from source/target (which could be node object or string ID)\n const getNodePosition = (nodeOrId: string | GraphNode): { x: number; y: number } | null => {\n if (typeof nodeOrId === 'object' && nodeOrId !== null) {\n // It's a node object\n const node = nodeOrId as GraphNode;\n return { x: node.x ?? 0, y: node.y ?? 0 };\n } else if (typeof nodeOrId === 'string') {\n // It's a string ID, try to find in nodes array\n const found = nodes.find(n => n.id === nodeOrId);\n if (found) return { x: found.x ?? 0, y: found.y ?? 0 };\n }\n return null;\n };\n\n const sourcePos = getNodePosition(link.source);\n const targetPos = getNodePosition(link.target);\n\n // If we can't get positions, render nothing (or a placeholder)\n if (!sourcePos || !targetPos) {\n return null;\n }\n\n // Calculate midpoint for label positioning\n const midX = (sourcePos.x + targetPos.x) / 2;\n const midY = (sourcePos.y + targetPos.y) / 2;\n\n return (\n <g>\n <line\n x1={sourcePos.x}\n y1={sourcePos.y}\n x2={targetPos.x}\n y2={targetPos.y}\n data-source={src}\n data-target={tgt}\n stroke={link.color}\n strokeWidth={link.width ?? defaultWidth ?? 1}\n opacity={0.6}\n className=\"cursor-pointer transition-opacity hover:opacity-100\"\n onClick={() => onClick?.(link)}\n />\n {showLabel && link.label && (\n <text\n x={midX}\n y={midY}\n fill=\"#666\"\n fontSize=\"10\"\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n pointerEvents=\"none\"\n >\n {link.label}\n </text>\n )}\n </g>\n );\n};\n\nexport default LinkItem;\n","import React, { useCallback, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';\nimport * as d3 from 'd3';\nimport { useForceSimulation, type SimulationNode, type SimulationLink, type ForceSimulationOptions } from '../hooks/useForceSimulation';\nimport { cn } from '../utils/cn';\nimport NodeItem from './NodeItem';\nimport LinkItem from './LinkItem';\n\nexport interface GraphNode extends SimulationNode {\n id: string;\n label?: string;\n color?: string;\n size?: number;\n group?: string;\n kind?: 'file' | 'package';\n packageGroup?: string;\n}\n\nexport interface GraphLink extends SimulationLink {\n color?: string;\n width?: number;\n label?: string;\n}\n\nexport interface ForceDirectedGraphHandle {\n pinAll: () => void;\n unpinAll: () => void;\n resetLayout: () => void;\n fitView: () => void;\n getPinnedNodes: () => string[];\n setDragMode: (enabled: boolean) => void;\n}\n\nexport interface ForceDirectedGraphProps {\n nodes: GraphNode[];\n links: GraphLink[];\n width: number;\n height: number;\n simulationOptions?: Partial<ForceSimulationOptions>;\n enableZoom?: boolean;\n enableDrag?: boolean;\n onNodeClick?: (node: GraphNode) => void;\n onNodeHover?: (node: GraphNode | null) => void;\n onLinkClick?: (link: GraphLink) => void;\n selectedNodeId?: string;\n hoveredNodeId?: string;\n defaultNodeColor?: string;\n defaultNodeSize?: number;\n defaultLinkColor?: string;\n defaultLinkWidth?: number;\n showNodeLabels?: boolean;\n showLinkLabels?: boolean;\n className?: string;\n manualLayout?: boolean;\n onManualLayoutChange?: (enabled: boolean) => void;\n packageBounds?: Record<string, { x: number; y: number; r: number }>;\n }\n\nexport const ForceDirectedGraph = forwardRef<ForceDirectedGraphHandle, ForceDirectedGraphProps>(\n (\n {\n nodes: initialNodes,\n links: initialLinks,\n width,\n height,\n simulationOptions,\n enableZoom = true,\n enableDrag = true,\n onNodeClick,\n onNodeHover,\n onLinkClick,\n selectedNodeId,\n hoveredNodeId,\n defaultNodeColor = '#69b3a2',\n defaultNodeSize = 10,\n defaultLinkColor = '#999',\n defaultLinkWidth = 1,\n showNodeLabels = true,\n showLinkLabels = false,\n className,\n manualLayout = false,\n onManualLayoutChange,\n packageBounds,\n },\n ref\n ) => {\n const svgRef = useRef<SVGSVGElement>(null);\n const gRef = useRef<SVGGElement>(null);\n const [transform, setTransform] = useState({ k: 1, x: 0, y: 0 });\n const transformRef = useRef(transform);\n const dragNodeRef = useRef<GraphNode | null>(null);\n const dragActiveRef = useRef(false);\n const [pinnedNodes, setPinnedNodes] = useState<Set<string>>(new Set());\n const internalDragEnabledRef = useRef(enableDrag);\n\n // Update the ref when enableDrag prop changes\n useEffect(() => {\n internalDragEnabledRef.current = enableDrag;\n }, [enableDrag]);\n\n // Initialize simulation - let React handle rendering based on node positions\n const onTick = (_nodesCopy: any[], _linksCopy: any[], _sim: any) => {\n // If package bounds are provided, gently pull file nodes toward their\n // package center to create meaningful clusters.\n try {\n const boundsToUse = clusterBounds?.bounds ?? packageBounds;\n const nodeClusterMap = clusterBounds?.nodeToCluster ?? {};\n if (boundsToUse) {\n Object.values(nodesById).forEach((n) => {\n if (!n) return;\n // Prefer explicit `group`, but fall back to `packageGroup` which is\n // provided by the visualizer data. This ensures file nodes are\n // pulled toward their package center (pkg:<name>) as intended.\n const group = (n as any).group ?? (n as any).packageGroup as string | undefined;\n const clusterKey = nodeClusterMap[n.id];\n const key = clusterKey ?? (group ? `pkg:${group}` : undefined);\n if (!key) return;\n const center = (boundsToUse as any)[key];\n if (!center) return;\n const dx = center.x - (n.x ?? 0);\n const dy = center.y - (n.y ?? 0);\n const dist = Math.sqrt(dx * dx + dy * dy);\n // Much stronger pull so nodes reliably settle inside cluster areas\n const pullStrength = Math.min(0.5, 0.15 * (dist / (center.r || 200)) + 0.06);\n if (!isNaN(pullStrength) && isFinite(pullStrength)) {\n n.vx = (n.vx ?? 0) + (dx / (dist || 1)) * pullStrength;\n n.vy = (n.vy ?? 0) + (dy / (dist || 1)) * pullStrength;\n }\n // If outside cluster radius, apply a stronger inward correction scaled to excess\n if (center.r && dist > center.r) {\n const excess = (dist - center.r) / (dist || 1);\n n.vx = (n.vx ?? 0) - dx * 0.02 * excess;\n n.vy = (n.vy ?? 0) - dy * 0.02 * excess;\n }\n });\n }\n } catch (e) {\n // ignore grouping errors\n }\n\n // No DOM updates needed - React will re-render based on nodes state from useForceSimulation\n // The useForceSimulation hook already calls setNodes on each tick (throttled)\n // React components (NodeItem, LinkItem) will use node.x, node.y from the nodes state\n };\n\n // main simulation is created after seeding below (so seededNodes can be used)\n\n // --- Two-phase hierarchical layout: Phase A (package centers) + Phase B (local layouts)\n // Compute package areas and per-node local positions, then seed the main simulation.\n const { packageAreas, localPositions } = React.useMemo(() => {\n try {\n if (!initialNodes || !initialNodes.length) return { packageAreas: {}, localPositions: {} };\n // Group nodes by package/group key\n const groups = new Map<string, any[]>();\n initialNodes.forEach((n: any) => {\n const key = n.packageGroup || n.group || 'root';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(n);\n });\n\n const groupKeys = Array.from(groups.keys());\n // Build pack layout for package centers\n const children = groupKeys.map((k) => ({ name: k, value: Math.max(1, groups.get(k)!.length) }));\n const root: any = d3.hierarchy({ children } as any);\n root.sum((d: any) => d.value);\n const pack: any = d3.pack().size([width, height]).padding(Math.max(20, Math.min(width, height) * 0.03));\n const packed: any = pack(root);\n const packageAreas: Record<string, { x: number; y: number; r: number }> = {};\n if (packed.children) {\n packed.children.forEach((c: any) => {\n const name = c.data.name;\n packageAreas[name] = { x: c.x, y: c.y, r: Math.max(40, c.r) };\n });\n }\n\n // For each package, run a short local force simulation offscreen to compute local positions\n const localPositions: Record<string, { x: number; y: number }> = {};\n groups.forEach((nodesInGroup, _key) => {\n if (!nodesInGroup || nodesInGroup.length === 0) return;\n // create shallow copies for the local sim\n const localNodes = nodesInGroup.map((n: any) => ({ id: n.id, x: Math.random() * 10 - 5, y: Math.random() * 10 - 5, size: n.size || 10 }));\n // links restricted to intra-package\n const localLinks = (initialLinks || []).filter((l: any) => {\n const s = typeof l.source === 'string' ? l.source : (l.source && l.source.id);\n const t = typeof l.target === 'string' ? l.target : (l.target && l.target.id);\n return localNodes.some((ln: any) => ln.id === s) && localNodes.some((ln: any) => ln.id === t);\n }).map((l: any) => ({ source: typeof l.source === 'string' ? l.source : l.source.id, target: typeof l.target === 'string' ? l.target : l.target.id }));\n\n if (localNodes.length === 1) {\n localPositions[localNodes[0].id] = { x: 0, y: 0 };\n return;\n }\n\n const sim = d3.forceSimulation(localNodes as any)\n .force('link', d3.forceLink(localLinks as any).id((d: any) => d.id).distance(30).strength(0.8))\n .force('charge', d3.forceManyBody().strength(-15))\n .force('collide', d3.forceCollide((d: any) => (d.size || 10) + 6).iterations(2))\n .stop();\n\n // Run several synchronous ticks to settle local layout\n const ticks = 300;\n for (let i = 0; i < ticks; i++) sim.tick();\n\n localNodes.forEach((ln: any) => {\n localPositions[ln.id] = { x: ln.x ?? 0, y: ln.y ?? 0 };\n });\n });\n\n return { packageAreas, localPositions };\n } catch (e) {\n return { packageAreas: {}, localPositions: {} };\n }\n }, [initialNodes, initialLinks, width, height]);\n\n // Seed main simulation nodes with package-local coordinates mapped into package areas\n const seededNodes = React.useMemo(() => {\n if (!initialNodes || !Object.keys(packageAreas || {}).length) return initialNodes;\n return initialNodes.map((n: any) => {\n const key = n.packageGroup || n.group || 'root';\n const area = packageAreas[key];\n const lp = localPositions[n.id];\n if (!area || !lp) return n;\n // scale local layout to fit inside package radius\n const scale = Math.max(0.5, (area.r * 0.6) / (Math.max(1, Math.sqrt(lp.x * lp.x + lp.y * lp.y)) || 1));\n return { ...n, x: area.x + lp.x * scale, y: area.y + lp.y * scale };\n });\n }, [initialNodes, packageAreas, localPositions]);\n\n\n // Compute dependency-based clusters (connected components on dependency links)\n // create the main force simulation using seeded nodes\n const { nodes, links, restart, stop, setForcesEnabled } = useForceSimulation(seededNodes || initialNodes, initialLinks, {\n width,\n height,\n chargeStrength: manualLayout ? 0 : undefined,\n onTick,\n ...simulationOptions,\n });\n\n // Helper map id -> node for quick lookup in onTick\n const nodesById = React.useMemo(() => {\n const m: Record<string, any> = {};\n (nodes || []).forEach((n: any) => {\n if (n && n.id) m[n.id] = n;\n });\n return m;\n }, [nodes]);\n\n const clusterBounds = React.useMemo(() => {\n try {\n if (!links || !nodes) return null;\n const nodeIds = new Set(nodes.map((n) => n.id));\n const adj = new Map<string, Set<string>>();\n nodes.forEach((n) => adj.set(n.id, new Set()));\n links.forEach((l: any) => {\n const type = l.type || 'reference';\n if (type !== 'dependency') return;\n const s = typeof l.source === 'string' ? l.source : (l.source && l.source.id) || null;\n const t = typeof l.target === 'string' ? l.target : (l.target && l.target.id) || null;\n if (!s || !t) return;\n if (!nodeIds.has(s) || !nodeIds.has(t)) return;\n adj.get(s)?.add(t);\n adj.get(t)?.add(s);\n });\n\n const visited = new Set<string>();\n const comps: Array<string[]> = [];\n for (const nid of nodeIds) {\n if (visited.has(nid)) continue;\n const stack = [nid];\n const comp: string[] = [];\n visited.add(nid);\n while (stack.length) {\n const cur = stack.pop()!;\n comp.push(cur);\n const neigh = adj.get(cur);\n if (!neigh) continue;\n for (const nb of neigh) {\n if (!visited.has(nb)) {\n visited.add(nb);\n stack.push(nb);\n }\n }\n }\n comps.push(comp);\n }\n\n if (comps.length <= 1) return null;\n\n // Increase spread: scale the packing area slightly larger than viewport,\n // give more padding between clusters, and bias radii upward so nodes\n // have more room to sit inside cluster circles.\n const children = comps.map((c, i) => ({ name: String(i), value: Math.max(1, c.length) }));\n d3.hierarchy({ children } as any).sum((d: any) => d.value).sort((a: any, b: any) => b.value - a.value);\n // Use a radial layout to guarantee very large separation between clusters.\n // Place cluster centers on a circle around the viewport center with a\n // radius scaled aggressively by viewport size and cluster count.\n const num = comps.length;\n const cx = width / 2;\n const cy = height / 2;\n // Circle radius grows with viewport and number of clusters to force separation\n const base = Math.max(width, height);\n // Make cluster circle radius extremely large so clusters are very far apart.\n // Scale with number of clusters to avoid crowding; multiply heavily for drastic separation.\n const circleRadius = base * Math.max(30, num * 20, Math.sqrt(num) * 12);\n const map: Record<string, { x: number; y: number; r: number }> = {};\n comps.forEach((c, i) => {\n const angle = (2 * Math.PI * i) / num;\n const x = cx + Math.cos(angle) * circleRadius;\n const y = cy + Math.sin(angle) * circleRadius;\n const sizeBias = Math.sqrt(Math.max(1, c.length));\n const r = Math.max(200, 100 * sizeBias);\n map[`cluster:${i}`] = { x, y, r };\n });\n // Map node id -> cluster id center\n const nodeToCluster: Record<string, string> = {};\n comps.forEach((c, i) => c.forEach((nid) => (nodeToCluster[nid] = `cluster:${i}`)));\n return { bounds: map, nodeToCluster };\n } catch (e) {\n return null;\n }\n }, [nodes, links, width, height]);\n\n // If package or cluster bounds are provided, recreate the simulation so onTick gets the latest bounds\n useEffect(() => {\n if (!packageBounds && !clusterBounds && (!packageAreas || Object.keys(packageAreas).length === 0)) return;\n try {\n restart();\n } catch (e) {\n // ignore\n }\n }, [packageBounds, clusterBounds, packageAreas, restart]);\n\n // If manual layout is enabled or any nodes are pinned, disable forces\n useEffect(() => {\n try {\n if (manualLayout || pinnedNodes.size > 0) setForcesEnabled(false);\n else setForcesEnabled(true);\n } catch (e) {\n // ignore\n }\n }, [manualLayout, pinnedNodes, setForcesEnabled]);\n\n // Expose imperative handle for parent components\n useImperativeHandle(\n ref,\n () => ({\n pinAll: () => {\n const newPinned = new Set<string>();\n nodes.forEach((node) => {\n node.fx = node.x;\n node.fy = node.y;\n newPinned.add(node.id);\n });\n setPinnedNodes(newPinned);\n restart();\n },\n\n unpinAll: () => {\n nodes.forEach((node) => {\n node.fx = null;\n node.fy = null;\n });\n setPinnedNodes(new Set());\n restart();\n },\n\n resetLayout: () => {\n nodes.forEach((node) => {\n node.fx = null;\n node.fy = null;\n });\n setPinnedNodes(new Set());\n restart();\n },\n\n fitView: () => {\n if (!svgRef.current || !nodes.length) return;\n\n // Calculate bounds\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n nodes.forEach((node) => {\n if (node.x !== undefined && node.y !== undefined) {\n const size = node.size || 10;\n minX = Math.min(minX, node.x - size);\n maxX = Math.max(maxX, node.x + size);\n minY = Math.min(minY, node.y - size);\n maxY = Math.max(maxY, node.y + size);\n }\n });\n\n if (!isFinite(minX)) return;\n\n const padding = 40;\n const nodeWidth = maxX - minX;\n const nodeHeight = maxY - minY;\n const scale = Math.min(\n (width - padding * 2) / nodeWidth,\n (height - padding * 2) / nodeHeight,\n 10\n );\n\n const centerX = (minX + maxX) / 2;\n const centerY = (minY + maxY) / 2;\n\n const x = width / 2 - centerX * scale;\n const y = height / 2 - centerY * scale;\n\n if (gRef.current && svgRef.current) {\n const svg = d3.select(svgRef.current);\n const newTransform = d3.zoomIdentity.translate(x, y).scale(scale);\n svg.transition().duration(300).call(d3.zoom<SVGSVGElement, unknown>().transform as any, newTransform);\n setTransform(newTransform);\n }\n },\n\n getPinnedNodes: () => Array.from(pinnedNodes),\n\n setDragMode: (enabled: boolean) => {\n internalDragEnabledRef.current = enabled;\n },\n }),\n [nodes, pinnedNodes, restart, width, height]\n );\n\n // Notify parent when manual layout mode changes (uses the prop so it's not unused)\n useEffect(() => {\n try {\n if (typeof onManualLayoutChange === 'function') onManualLayoutChange(manualLayout);\n } catch (e) {\n // ignore errors from callbacks\n }\n }, [manualLayout, onManualLayoutChange]);\n\n // Set up zoom behavior\n useEffect(() => {\n if (!enableZoom || !svgRef.current || !gRef.current) return;\n\n const svg = d3.select(svgRef.current);\n const g = d3.select(gRef.current);\n\n const zoom = d3\n .zoom<SVGSVGElement, unknown>()\n .scaleExtent([0.1, 10])\n .on('zoom', (event) => {\n g.attr('transform', event.transform);\n transformRef.current = event.transform;\n setTransform(event.transform);\n });\n\n svg.call(zoom);\n\n return () => {\n svg.on('.zoom', null);\n };\n }, [enableZoom]);\n\n // Run a one-time DOM positioning pass when nodes/links change so elements\n // rendered by React are positioned to the simulation's seeded coordinates\n useEffect(() => {\n if (!gRef.current) return;\n try {\n const g = d3.select(gRef.current);\n g.selectAll<SVGGElement, any>('g.node').each(function (this: SVGGElement) {\n const datum = d3.select(this).datum() as any;\n if (!datum) return;\n d3.select(this).attr('transform', `translate(${datum.x || 0},${datum.y || 0})`);\n });\n\n g.selectAll<SVGLineElement, any>('line').each(function (this: SVGLineElement) {\n const l = d3.select(this).datum() as any;\n if (!l) return;\n const s: any = typeof l.source === 'object' ? l.source : nodes.find((n) => n.id === l.source) || l.source;\n const t: any = typeof l.target === 'object' ? l.target : nodes.find((n) => n.id === l.target) || l.target;\n if (!s || !t) return;\n d3.select(this).attr('x1', s.x).attr('y1', s.y).attr('x2', t.x).attr('y2', t.y);\n });\n } catch (e) {\n // ignore\n }\n }, [nodes, links]);\n\n // Set up drag behavior with global listeners for smoother dragging\n const handleDragStart = useCallback(\n (event: React.MouseEvent, node: GraphNode) => {\n if (!enableDrag) return;\n event.preventDefault();\n event.stopPropagation();\n // pause forces while dragging to avoid the whole graph moving\n dragActiveRef.current = true;\n dragNodeRef.current = node;\n node.fx = node.x;\n node.fy = node.y;\n setPinnedNodes((prev) => new Set([...prev, node.id]));\n try { stop(); } catch (e) {}\n },\n [enableDrag, restart]\n );\n\n useEffect(() => {\n if (!enableDrag) return;\n\n const handleWindowMove = (event: MouseEvent) => {\n if (!dragActiveRef.current || !dragNodeRef.current) return;\n const svg = svgRef.current;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const t: any = transformRef.current;\n const x = (event.clientX - rect.left - t.x) / t.k;\n const y = (event.clientY - rect.top - t.y) / t.k;\n dragNodeRef.current.fx = x;\n dragNodeRef.current.fy = y;\n };\n\n const handleWindowUp = () => {\n if (!dragActiveRef.current) return;\n // Keep fx/fy set to pin the node where it was dropped.\n try { setForcesEnabled(true); restart(); } catch (e) {}\n dragNodeRef.current = null;\n dragActiveRef.current = false;\n };\n\n const handleWindowLeave = (event: MouseEvent) => {\n if (event.relatedTarget === null) handleWindowUp();\n };\n\n window.addEventListener('mousemove', handleWindowMove);\n window.addEventListener('mouseup', handleWindowUp);\n window.addEventListener('mouseout', handleWindowLeave);\n window.addEventListener('blur', handleWindowUp);\n\n return () => {\n window.removeEventListener('mousemove', handleWindowMove);\n window.removeEventListener('mouseup', handleWindowUp);\n window.removeEventListener('mouseout', handleWindowLeave);\n window.removeEventListener('blur', handleWindowUp);\n };\n }, [enableDrag]);\n\n // Attach d3.drag behavior to node groups rendered by React. This helps make\n // dragging more robust across transforms and pointer behaviors.\n useEffect(() => {\n if (!gRef.current || !enableDrag) return;\n const g = d3.select(gRef.current);\n const dragBehavior = d3\n .drag<SVGGElement, unknown>()\n .on('start', function (event) {\n try {\n const target = (event.sourceEvent && (event.sourceEvent.target as Element)) || (event.target as Element);\n const grp = target.closest?.('g.node') as Element | null;\n const id = grp?.getAttribute('data-id');\n if (!id) return;\n const node = nodes.find((n) => n.id === id) as GraphNode | undefined;\n if (!node) return;\n if (!internalDragEnabledRef.current) return;\n if (!event.active) restart();\n dragActiveRef.current = true;\n dragNodeRef.current = node;\n node.fx = node.x;\n node.fy = node.y;\n setPinnedNodes((prev) => new Set([...prev, node.id]));\n } catch (e) {\n // ignore\n }\n })\n .on('drag', function (event) {\n if (!dragActiveRef.current || !dragNodeRef.current) return;\n const svg = svgRef.current;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const x = (event.sourceEvent.clientX - rect.left - transform.x) / transform.k;\n const y = (event.sourceEvent.clientY - rect.top - transform.y) / transform.k;\n dragNodeRef.current.fx = x;\n dragNodeRef.current.fy = y;\n })\n .on('end', function () {\n // re-enable forces when drag ends\n try { setForcesEnabled(true); restart(); } catch (e) {}\n dragNodeRef.current = null;\n dragActiveRef.current = false;\n });\n\n try {\n g.selectAll('g.node').call(dragBehavior as any);\n } catch (e) {\n // ignore attach errors\n }\n\n return () => {\n try {\n g.selectAll('g.node').on('.drag', null as any);\n } catch (e) {\n /* ignore */\n }\n };\n }, [gRef, enableDrag, nodes, transform, restart]);\n\n const handleNodeClick = useCallback(\n (node: GraphNode) => {\n onNodeClick?.(node);\n },\n [onNodeClick]\n );\n\n const handleNodeDoubleClick = useCallback(\n (event: React.MouseEvent, node: GraphNode) => {\n event.stopPropagation();\n if (!enableDrag) return;\n if (node.fx === null || node.fx === undefined) {\n node.fx = node.x;\n node.fy = node.y;\n setPinnedNodes((prev) => new Set([...prev, node.id]));\n } else {\n node.fx = null;\n node.fy = null;\n setPinnedNodes((prev) => {\n const next = new Set(prev);\n next.delete(node.id);\n return next;\n });\n }\n restart();\n },\n [enableDrag, restart]\n );\n\n const handleCanvasDoubleClick = useCallback(() => {\n nodes.forEach((node) => {\n node.fx = null;\n node.fy = null;\n });\n setPinnedNodes(new Set());\n restart();\n }, [nodes, restart]);\n\n const handleNodeMouseEnter = useCallback(\n (node: GraphNode) => {\n onNodeHover?.(node);\n },\n [onNodeHover]\n );\n\n const handleNodeMouseLeave = useCallback(() => {\n onNodeHover?.(null);\n }, [onNodeHover]);\n\n const handleLinkClick = useCallback(\n (link: GraphLink) => {\n onLinkClick?.(link);\n },\n [onLinkClick]\n );\n\n return (\n <svg\n ref={svgRef}\n width={width}\n height={height}\n className={cn('bg-white dark:bg-gray-900', className)}\n onDoubleClick={handleCanvasDoubleClick}\n >\n <defs>\n {/* Arrow marker for directed graphs */}\n <marker\n id=\"arrow\"\n viewBox=\"0 0 10 10\"\n refX=\"20\"\n refY=\"5\"\n markerWidth=\"6\"\n markerHeight=\"6\"\n orient=\"auto\"\n >\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill={defaultLinkColor} />\n </marker>\n </defs>\n\n <g ref={gRef}>\n \n {/* Render links via LinkItem (positions updated by D3) */}\n {links.map((link, i) => (\n <LinkItem\n key={`link-${i}`}\n link={link as GraphLink}\n onClick={handleLinkClick}\n defaultWidth={defaultLinkWidth}\n showLabel={showLinkLabels}\n nodes={nodes}\n />\n ))}\n\n {/* Render nodes via NodeItem (D3 will set transforms) */}\n {nodes.map((node) => (\n <NodeItem\n key={node.id}\n node={node as GraphNode}\n isSelected={selectedNodeId === node.id}\n isHovered={hoveredNodeId === node.id}\n pinned={pinnedNodes.has(node.id)}\n defaultNodeSize={defaultNodeSize}\n defaultNodeColor={defaultNodeColor}\n showLabel={showNodeLabels}\n onClick={handleNodeClick}\n onDoubleClick={handleNodeDoubleClick}\n onMouseEnter={handleNodeMouseEnter}\n onMouseLeave={handleNodeMouseLeave}\n onMouseDown={handleDragStart}\n />\n ))}\n {/* Package boundary circles (from parent pack layout) - drawn on top for visibility */}\n {packageBounds && Object.keys(packageBounds).length > 0 && (\n <g className=\"package-boundaries\" pointerEvents=\"none\">\n {Object.entries(packageBounds).map(([pid, b]) => (\n <g key={pid}>\n <circle\n cx={b.x}\n cy={b.y}\n r={b.r}\n fill=\"rgba(148,163,184,0.06)\"\n stroke=\"#475569\"\n strokeWidth={2}\n strokeDasharray=\"6 6\"\n opacity={0.9}\n />\n <text\n x={b.x}\n y={Math.max(12, b.y - b.r + 14)}\n fill=\"#475569\"\n fontSize={11}\n textAnchor=\"middle\"\n pointerEvents=\"none\"\n >\n {pid.replace(/^pkg:/, '')}\n </text>\n </g>\n ))}\n </g>\n )}\n </g>\n </svg>\n );\n }\n);\n\nForceDirectedGraph.displayName = 'ForceDirectedGraph';"]}
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
7
7
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -19,6 +19,11 @@ interface ForceSimulationOptions {
19
19
  width: number;
20
20
  height: number;
21
21
  alphaDecay?: number;
22
+ alphaTarget?: number;
23
+ warmAlpha?: number;
24
+ alphaMin?: number;
25
+ stabilizeOnStop?: boolean;
26
+ maxSimulationTimeMs?: number;
22
27
  velocityDecay?: number;
23
28
  onTick?: (nodes: SimulationNode[], links: SimulationLink[], sim: d3.Simulation<SimulationNode, SimulationLink>) => void;
24
29
  }
@@ -14,46 +14,183 @@ function useForceSimulation(initialNodes, initialLinks, options) {
14
14
  height,
15
15
  alphaDecay = 0.0228,
16
16
  velocityDecay = 0.4,
17
- onTick
17
+ alphaTarget = 0,
18
+ warmAlpha = 0.3,
19
+ alphaMin = 0.01,
20
+ // @ts-ignore allow extra option
21
+ stabilizeOnStop = true,
22
+ onTick,
23
+ // Optional throttle in milliseconds for tick updates (reduce React re-renders)
24
+ // Lower values = smoother but more CPU; default ~30ms (~33fps)
25
+ // @ts-ignore allow extra option
26
+ tickThrottleMs = 33,
27
+ // @ts-ignore allow extra option
28
+ maxSimulationTimeMs = 3e3
18
29
  } = options;
19
30
  const [nodes, setNodes] = useState(initialNodes);
20
31
  const [links, setLinks] = useState(initialLinks);
21
32
  const [isRunning, setIsRunning] = useState(false);
22
33
  const [alpha, setAlpha] = useState(1);
23
34
  const simulationRef = useRef(null);
35
+ const stopTimeoutRef = useRef(null);
36
+ const nodesKey = initialNodes.map((n) => n.id).join("|");
37
+ const linksKey = (initialLinks || []).map((l) => {
38
+ const s = typeof l.source === "string" ? l.source : l.source?.id;
39
+ const t = typeof l.target === "string" ? l.target : l.target?.id;
40
+ return `${s}->${t}:${l.type || ""}`;
41
+ }).join("|");
24
42
  useEffect(() => {
25
43
  const nodesCopy = initialNodes.map((node) => ({ ...node }));
26
44
  const linksCopy = initialLinks.map((link) => ({ ...link }));
27
- const simulation = d3.forceSimulation(nodesCopy).force(
28
- "link",
29
- d3.forceLink(linksCopy).id((d) => d.id).distance((d) => d && d.distance != null ? d.distance : linkDistance).strength(linkStrength)
30
- ).force("charge", d3.forceManyBody().strength(chargeStrength)).force("center", d3.forceCenter(width / 2, height / 2).strength(centerStrength)).force(
31
- "collision",
32
- d3.forceCollide().radius((d) => {
45
+ try {
46
+ nodesCopy.forEach((n, i) => {
47
+ const angle = i * 2 * Math.PI / nodesCopy.length;
48
+ const radius = Math.min(width, height) * 0.45;
49
+ n.x = width / 2 + radius * Math.cos(angle);
50
+ n.y = height / 2 + radius * Math.sin(angle);
51
+ n.vx = (Math.random() - 0.5) * 2;
52
+ n.vy = (Math.random() - 0.5) * 2;
53
+ });
54
+ } catch (e) {
55
+ nodesCopy.forEach((n) => {
56
+ n.x = Math.random() * width;
57
+ n.y = Math.random() * height;
58
+ n.vx = (Math.random() - 0.5) * 10;
59
+ n.vy = (Math.random() - 0.5) * 10;
60
+ });
61
+ }
62
+ const simulation = d3.forceSimulation(nodesCopy);
63
+ try {
64
+ const linkForce = d3.forceLink(linksCopy);
65
+ linkForce.id((d) => d.id).distance((d) => d && d.distance != null ? d.distance : linkDistance).strength(linkStrength);
66
+ simulation.force("link", linkForce);
67
+ } catch (e) {
68
+ try {
69
+ simulation.force("link", d3.forceLink(linksCopy));
70
+ } catch (e2) {
71
+ }
72
+ }
73
+ try {
74
+ simulation.force("charge", d3.forceManyBody().strength(chargeStrength));
75
+ simulation.force("center", d3.forceCenter(width / 2, height / 2).strength(centerStrength));
76
+ const collide = d3.forceCollide().radius((d) => {
33
77
  const nodeSize = d && d.size ? d.size : 10;
34
78
  return nodeSize + collisionRadius;
35
- }).strength(collisionStrength)
36
- ).alphaDecay(alphaDecay).velocityDecay(velocityDecay);
79
+ }).strength(collisionStrength);
80
+ simulation.force("collision", collide);
81
+ simulation.force("x", d3.forceX(width / 2).strength(Math.max(0.02, centerStrength * 0.5)));
82
+ simulation.force("y", d3.forceY(height / 2).strength(Math.max(0.02, centerStrength * 0.5)));
83
+ simulation.alphaDecay(alphaDecay);
84
+ simulation.velocityDecay(velocityDecay);
85
+ simulation.alphaMin(alphaMin);
86
+ try {
87
+ simulation.alphaTarget(alphaTarget);
88
+ } catch (e) {
89
+ }
90
+ try {
91
+ simulation.alpha(warmAlpha);
92
+ } catch (e) {
93
+ }
94
+ } catch (e) {
95
+ }
37
96
  simulationRef.current = simulation;
38
- simulation.on("tick", () => {
97
+ if (stopTimeoutRef.current != null) {
98
+ try {
99
+ globalThis.clearTimeout(stopTimeoutRef.current);
100
+ } catch (e) {
101
+ }
102
+ stopTimeoutRef.current = null;
103
+ }
104
+ if (maxSimulationTimeMs && maxSimulationTimeMs > 0) {
105
+ stopTimeoutRef.current = globalThis.setTimeout(() => {
106
+ try {
107
+ if (stabilizeOnStop) {
108
+ nodesCopy.forEach((n) => {
109
+ n.vx = 0;
110
+ n.vy = 0;
111
+ if (typeof n.x === "number") n.x = Number(n.x.toFixed(3));
112
+ if (typeof n.y === "number") n.y = Number(n.y.toFixed(3));
113
+ });
114
+ }
115
+ simulation.alpha(0);
116
+ simulation.stop();
117
+ } catch (e) {
118
+ }
119
+ setIsRunning(false);
120
+ setNodes([...nodesCopy]);
121
+ setLinks([...linksCopy]);
122
+ }, maxSimulationTimeMs);
123
+ }
124
+ let rafId = null;
125
+ let lastUpdate = 0;
126
+ const tickHandler = () => {
39
127
  try {
40
128
  if (typeof onTick === "function") onTick(nodesCopy, linksCopy, simulation);
41
129
  } catch (e) {
42
130
  }
43
- setNodes([...nodesCopy]);
44
- setLinks([...linksCopy]);
45
- setAlpha(simulation.alpha());
46
- setIsRunning(simulation.alpha() > simulation.alphaMin());
47
- });
131
+ try {
132
+ if (simulation.alpha() <= alphaMin) {
133
+ try {
134
+ if (stabilizeOnStop) {
135
+ nodesCopy.forEach((n) => {
136
+ n.vx = 0;
137
+ n.vy = 0;
138
+ if (typeof n.x === "number") n.x = Number(n.x.toFixed(3));
139
+ if (typeof n.y === "number") n.y = Number(n.y.toFixed(3));
140
+ });
141
+ }
142
+ simulation.stop();
143
+ } catch (e) {
144
+ }
145
+ setAlpha(simulation.alpha());
146
+ setIsRunning(false);
147
+ setNodes([...nodesCopy]);
148
+ setLinks([...linksCopy]);
149
+ return;
150
+ }
151
+ } catch (e) {
152
+ }
153
+ const now = Date.now();
154
+ const shouldUpdate = now - lastUpdate >= tickThrottleMs;
155
+ if (rafId == null && shouldUpdate) {
156
+ rafId = (globalThis.requestAnimationFrame || ((cb) => setTimeout(cb, 16)))(() => {
157
+ rafId = null;
158
+ lastUpdate = Date.now();
159
+ setNodes([...nodesCopy]);
160
+ setLinks([...linksCopy]);
161
+ setAlpha(simulation.alpha());
162
+ setIsRunning(simulation.alpha() > simulation.alphaMin());
163
+ });
164
+ }
165
+ };
166
+ simulation.on("tick", tickHandler);
48
167
  simulation.on("end", () => {
49
168
  setIsRunning(false);
50
169
  });
51
170
  return () => {
171
+ try {
172
+ simulation.on("tick", null);
173
+ } catch (e) {
174
+ }
175
+ if (stopTimeoutRef.current != null) {
176
+ try {
177
+ globalThis.clearTimeout(stopTimeoutRef.current);
178
+ } catch (e) {
179
+ }
180
+ stopTimeoutRef.current = null;
181
+ }
182
+ if (rafId != null) {
183
+ try {
184
+ (globalThis.cancelAnimationFrame || ((id) => clearTimeout(id)))(rafId);
185
+ } catch (e) {
186
+ }
187
+ rafId = null;
188
+ }
52
189
  simulation.stop();
53
190
  };
54
191
  }, [
55
- initialNodes,
56
- initialLinks,
192
+ nodesKey,
193
+ linksKey,
57
194
  chargeStrength,
58
195
  linkDistance,
59
196
  linkStrength,
@@ -64,12 +201,37 @@ function useForceSimulation(initialNodes, initialLinks, options) {
64
201
  height,
65
202
  alphaDecay,
66
203
  velocityDecay,
67
- onTick
204
+ alphaTarget,
205
+ alphaMin,
206
+ stabilizeOnStop,
207
+ tickThrottleMs,
208
+ maxSimulationTimeMs
68
209
  ]);
69
210
  const restart = () => {
70
211
  if (simulationRef.current) {
71
- simulationRef.current.alpha(1).restart();
212
+ try {
213
+ simulationRef.current.alphaTarget(warmAlpha).restart();
214
+ } catch (e) {
215
+ simulationRef.current.restart();
216
+ }
72
217
  setIsRunning(true);
218
+ if (stopTimeoutRef.current != null) {
219
+ try {
220
+ globalThis.clearTimeout(stopTimeoutRef.current);
221
+ } catch (e) {
222
+ }
223
+ stopTimeoutRef.current = null;
224
+ }
225
+ if (maxSimulationTimeMs && maxSimulationTimeMs > 0) {
226
+ stopTimeoutRef.current = globalThis.setTimeout(() => {
227
+ try {
228
+ simulationRef.current?.alpha(0);
229
+ simulationRef.current?.stop();
230
+ } catch (e) {
231
+ }
232
+ setIsRunning(false);
233
+ }, maxSimulationTimeMs);
234
+ }
73
235
  }
74
236
  };
75
237
  const stop = () => {