import { HandleElement, MarkerType, Position, Rect, XYPosition } from '@reactflow/system'; // this is used for straight edges and simple smoothstep edges (LTR, RTL, BTT, TTB) export function getEdgeCenter({ sourceX, sourceY, targetX, targetY, }: { sourceX: number; sourceY: number; targetX: number; targetY: number; }): [number, number, number, number] { const xOffset = Math.abs(targetX - sourceX) / 2; const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset; const yOffset = Math.abs(targetY - sourceY) / 2; const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; return [centerX, centerY, xOffset, yOffset]; } export const getMarkerEnd = (markerType?: MarkerType, markerEndId?: string): string => { if (typeof markerEndId !== 'undefined' && markerEndId) { return `url(#${markerEndId})`; } return typeof markerType !== 'undefined' ? `url(#react-flow__${markerType})` : 'none'; }; export function getHandlePosition(position: Position, nodeRect: Rect, handle: HandleElement | null = null): XYPosition { const x = (handle?.x || 0) + nodeRect.x; const y = (handle?.y || 0) + nodeRect.y; const width = handle?.width || nodeRect.width; const height = handle?.height || nodeRect.height; switch (position) { case Position.Top: return { x: x + width / 2, y, }; case Position.Right: return { x: x + width, y: y + height / 2, }; case Position.Bottom: return { x: x + width / 2, y: y + height, }; case Position.Left: return { x, y: y + height / 2, }; } } export function getHandle(bounds: HandleElement[], handleId?: string | null): HandleElement | null { if (!bounds) { return null; } if (bounds.length === 1 || !handleId) { return bounds[0]; } else if (handleId) { return bounds.find((d) => d.id === handleId) || null; } return null; }