diff --git a/src/container/EdgeRenderer/index.tsx b/src/container/EdgeRenderer/index.tsx index 155609a4..6e913f72 100644 --- a/src/container/EdgeRenderer/index.tsx +++ b/src/container/EdgeRenderer/index.tsx @@ -4,7 +4,7 @@ import { useStoreState } from '../../store/hooks'; import ConnectionLine from '../../components/ConnectionLine/index'; import { isEdge } from '../../utils/graph'; import MarkerDefinitions from './MarkerDefinitions'; -import { getHandlePosition, getHandle } from './utils'; +import { getHandlePosition, getHandle, isEdgeVisible } from './utils'; import { Position, Edge, @@ -13,6 +13,7 @@ import { Elements, ConnectionLineType, ConnectionLineComponent, + Transform, } from '../../types'; interface EdgeRendererProps { @@ -56,24 +57,33 @@ function getEdgePositions( }; } +type SourceTargetNode = { + sourceNode: Node | null; + targetNode: Node | null; +}; + +const initialSourceTarget: SourceTargetNode = { sourceNode: null, targetNode: null }; + function renderEdge( edge: Edge, props: EdgeRendererProps, - visibleNodes: Node[], nodes: Node[], selectedElements: Elements | null, - elementsSelectable: boolean + elementsSelectable: boolean, + transform: Transform, + width: number, + height: number ) { const sourceHandleId = edge.sourceHandle || null; const targetHandleId = edge.targetHandle || null; - - const sourceNode = nodes.find((n) => n.id === edge.source); - const targetNode = nodes.find((n) => n.id === edge.target); - const renderEdge = visibleNodes.some((n) => n.id === edge.source || n.id == edge.target); - - if (!renderEdge) { - return null; - } + const { sourceNode, targetNode } = nodes.reduce((res, node) => { + if (node.id === edge.source) { + res.sourceNode = node; + } else if (node.id === edge.target) { + res.targetNode = node; + } + return res; + }, initialSourceTarget); if (!sourceNode) { console.warn(`couldn't create edge for source id: ${edge.source}`); @@ -89,6 +99,18 @@ function renderEdge( return null; } + const renderEdge = isEdgeVisible({ + sourcePos: sourceNode.__rf.position, + targetPos: targetNode.__rf.position, + width, + height, + transform, + }); + + if (!renderEdge) { + return null; + } + const edgeType = edge.type || 'default'; const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default; const sourceHandle = getHandle(sourceNode.__rf.handleBounds.source, sourceHandleId); @@ -153,7 +175,7 @@ function renderEdge( } const EdgeRenderer = (props: EdgeRendererProps) => { - const [tX, tY, tScale] = useStoreState((state) => state.transform); + const transform = useStoreState((state) => state.transform); const edges = useStoreState((state) => state.edges); const connectionNodeId = useStoreState((state) => state.connectionNodeId); const connectionHandleId = useStoreState((state) => state.connectionHandleId); @@ -164,32 +186,32 @@ const EdgeRenderer = (props: EdgeRendererProps) => { const elementsSelectable = useStoreState((state) => state.elementsSelectable); const width = useStoreState((state) => state.width); const height = useStoreState((state) => state.height); - const visibleNodes = useStoreState((state) => state.visibleNodes); const nodes = useStoreState((state) => state.nodes); - const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props; - if (!width) { return null; } - const transformStyle = `translate(${tX},${tY}) scale(${tScale})`; + const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props; + const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`; const renderConnectionLine = connectionNodeId && connectionHandleType; return ( - {edges.map((edge: Edge) => renderEdge(edge, props, visibleNodes, nodes, selectedElements, elementsSelectable))} + {edges.map((edge: Edge) => + renderEdge(edge, props, nodes, selectedElements, elementsSelectable, transform, width, height) + )} {renderConnectionLine && ( 0; +} diff --git a/src/utils/graph.ts b/src/utils/graph.ts index 7af52a57..177ec12c 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -154,14 +154,14 @@ const getBoundsOfBoxes = (box1: Box, box2: Box): Box => ({ y2: Math.max(box1.y2, box2.y2), }); -const rectToBox = ({ x, y, width, height }: Rect): Box => ({ +export const rectToBox = ({ x, y, width, height }: Rect): Box => ({ x, y, x2: x + width, y2: y + height, }); -const boxToRect = ({ x, y, x2, y2 }: Box): Rect => ({ +export const boxToRect = ({ x, y, x2, y2 }: Box): Rect => ({ x, y, width: x2 - x,