@ngx-km/path-finding 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-km-path-finding.mjs","sources":["../../../../libs/ngx-km-path-finding/src/lib/models/path-finding.models.ts","../../../../libs/ngx-km-path-finding/src/lib/utils/path.utils.ts","../../../../libs/ngx-km-path-finding/src/lib/utils/anchor.utils.ts","../../../../libs/ngx-km-path-finding/src/lib/utils/geometry.utils.ts","../../../../libs/ngx-km-path-finding/src/lib/strategies/orthogonal.strategy.ts","../../../../libs/ngx-km-path-finding/src/lib/strategies/bezier.strategy.ts","../../../../libs/ngx-km-path-finding/src/lib/strategies/straight.strategy.ts","../../../../libs/ngx-km-path-finding/src/lib/services/path-finding.service.ts","../../../../libs/ngx-km-path-finding/src/index.ts","../../../../libs/ngx-km-path-finding/src/ngx-km-path-finding.ts"],"sourcesContent":["/**\n * Path Finding Models\n *\n * Types and interfaces for obstacle-aware path routing between nodes.\n */\n\n/**\n * Type of path to generate\n * - orthogonal: Right-angle turns only (Manhattan-style)\n * - bezier: Smooth curved paths\n * - straight: Direct line (may overlap obstacles)\n */\nexport type PathType = 'orthogonal' | 'bezier' | 'straight';\n\n/**\n * Side of a node where a connection point is located\n */\nexport type ConnectionSide = 'top' | 'right' | 'bottom' | 'left';\n\n/**\n * A point in 2D space\n */\nexport interface Point {\n x: number;\n y: number;\n}\n\n/**\n * A rectangle representing a node's bounds\n */\nexport interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * A node with position and dimensions for path finding\n * Used as an obstacle when routing paths\n */\nexport interface PathNode {\n /** Unique identifier */\n id: string;\n /** X coordinate (top-left corner) */\n x: number;\n /** Y coordinate (top-left corner) */\n y: number;\n /** Width of the node */\n width: number;\n /** Height of the node */\n height: number;\n}\n\n/**\n * A relationship/edge between two nodes that needs a path\n */\nexport interface PathRelationship {\n /** Unique identifier for this relationship */\n id: string;\n /** ID of the source node */\n sourceId: string;\n /** ID of the target node */\n targetId: string;\n /** Optional: force connection from specific side of source */\n sourceAnchor?: ConnectionSide;\n /** Optional: force connection to specific side of target */\n targetAnchor?: ConnectionSide;\n}\n\n/**\n * A connection point on a node's edge\n */\nexport interface ConnectionPoint {\n /** The side of the node */\n side: ConnectionSide;\n /** X coordinate of the connection point */\n x: number;\n /** Y coordinate of the connection point */\n y: number;\n}\n\n/**\n * A waypoint along a path\n */\nexport interface Waypoint extends Point {\n /** Optional: indicates if this is a control point for bezier curves */\n isControlPoint?: boolean;\n}\n\n/**\n * A calculated path between two nodes\n */\nexport interface CalculatedPath {\n /** The relationship ID this path corresponds to */\n relationshipId: string;\n /** Source node ID */\n sourceId: string;\n /** Target node ID */\n targetId: string;\n /** Connection point on source node */\n sourcePoint: ConnectionPoint;\n /** Connection point on target node */\n targetPoint: ConnectionPoint;\n /** Ordered list of waypoints forming the path */\n waypoints: Waypoint[];\n /** The midpoint of the path (useful for labels/pills) */\n midpoint: Point;\n /** Total length of the path */\n length: number;\n /** Type of path */\n pathType: PathType;\n}\n\n/**\n * Options for path finding\n */\nexport interface PathFindingOptions {\n /** Type of path to generate */\n pathType?: PathType;\n /** Padding around obstacles when routing */\n obstaclePadding?: number;\n /** Minimum distance from node corners for connection points */\n cornerPadding?: number;\n /** Minimum spacing between connection points on same side */\n connectionSpacing?: number;\n /** Whether to allow paths to pass through other nodes */\n allowOverlap?: boolean;\n /** Whether to spread anchor points when multiple edges connect to the same side */\n spreadAnchors?: boolean;\n /** Spacing between spread anchor points (when spreadAnchors is enabled) */\n anchorSpacing?: number;\n}\n\n/**\n * Default path finding options\n */\nexport const DEFAULT_PATH_FINDING_OPTIONS: Required<PathFindingOptions> = {\n pathType: 'orthogonal',\n obstaclePadding: 20,\n cornerPadding: 10,\n connectionSpacing: 15,\n allowOverlap: false,\n spreadAnchors: true,\n anchorSpacing: 15,\n};\n\n/**\n * Input for path finding calculation\n */\nexport interface PathFindingInput {\n /** All nodes (used as obstacles) */\n nodes: PathNode[];\n /** Relationships to calculate paths for */\n relationships: PathRelationship[];\n /** Path finding options */\n options?: PathFindingOptions;\n}\n\n/**\n * Result of path finding calculation\n */\nexport interface PathFindingResult {\n /** Calculated paths for each relationship */\n paths: CalculatedPath[];\n}\n","/**\n * Path Utilities\n *\n * Functions for path manipulation, simplification, and measurement.\n */\n\nimport { Point, Waypoint } from '../models/path-finding.models';\n\n/**\n * Calculate the length of a route using Manhattan distance (orthogonal segments)\n * Used for comparing route candidates\n */\nexport function calculateRouteLength(points: Point[]): number {\n let length = 0;\n for (let i = 0; i < points.length - 1; i++) {\n length += Math.abs(points[i + 1].x - points[i].x) + Math.abs(points[i + 1].y - points[i].y);\n }\n return length;\n}\n\n/**\n * Calculate total path length using Euclidean distance\n * Excludes control points for bezier curves\n */\nexport function calculatePathLength(waypoints: Waypoint[]): number {\n let length = 0;\n const points = waypoints.filter((w) => !w.isControlPoint);\n\n for (let i = 0; i < points.length - 1; i++) {\n length += Math.hypot(points[i + 1].x - points[i].x, points[i + 1].y - points[i].y);\n }\n\n return length;\n}\n\n/**\n * Calculate the midpoint of a path\n * Returns the point at half the total path length\n */\nexport function calculateMidpoint(waypoints: Waypoint[]): Point {\n if (waypoints.length === 0) return { x: 0, y: 0 };\n if (waypoints.length === 1) return { x: waypoints[0].x, y: waypoints[0].y };\n\n const nonControlPoints = waypoints.filter((w) => !w.isControlPoint);\n\n if (nonControlPoints.length >= 2) {\n const totalLength = calculatePathLength(nonControlPoints);\n const targetLength = totalLength / 2;\n let accumulatedLength = 0;\n\n for (let i = 0; i < nonControlPoints.length - 1; i++) {\n const segmentLength = Math.hypot(\n nonControlPoints[i + 1].x - nonControlPoints[i].x,\n nonControlPoints[i + 1].y - nonControlPoints[i].y\n );\n\n if (accumulatedLength + segmentLength >= targetLength) {\n const remainingLength = targetLength - accumulatedLength;\n const ratio = segmentLength > 0 ? remainingLength / segmentLength : 0;\n\n return {\n x: nonControlPoints[i].x + (nonControlPoints[i + 1].x - nonControlPoints[i].x) * ratio,\n y: nonControlPoints[i].y + (nonControlPoints[i + 1].y - nonControlPoints[i].y) * ratio,\n };\n }\n\n accumulatedLength += segmentLength;\n }\n }\n\n const midIndex = Math.floor(nonControlPoints.length / 2);\n return { x: nonControlPoints[midIndex].x, y: nonControlPoints[midIndex].y };\n}\n\n/**\n * Simplify path by removing collinear points\n * This reduces redundant waypoints while preserving path shape\n */\nexport function simplifyPath(waypoints: Waypoint[]): Waypoint[] {\n if (waypoints.length <= 2) return waypoints;\n\n const simplified: Waypoint[] = [waypoints[0]];\n\n for (let i = 1; i < waypoints.length - 1; i++) {\n const prev = simplified[simplified.length - 1];\n const curr = waypoints[i];\n const next = waypoints[i + 1];\n\n const isCollinear =\n (Math.abs(prev.x - curr.x) < 0.001 && Math.abs(curr.x - next.x) < 0.001) ||\n (Math.abs(prev.y - curr.y) < 0.001 && Math.abs(curr.y - next.y) < 0.001);\n\n if (!isCollinear) {\n simplified.push(curr);\n }\n }\n\n simplified.push(waypoints[waypoints.length - 1]);\n return simplified;\n}\n","/**\n * Anchor Utilities\n *\n * Functions for calculating connection points and anchor slot assignments.\n */\n\nimport { Point, PathNode, ConnectionSide, ConnectionPoint, CalculatedPath } from '../models/path-finding.models';\nimport { clamp } from './geometry.utils';\n\n/**\n * Anchor slot assignment for spreading multiple connections on the same side\n */\nexport interface AnchorSlot {\n nodeId: string;\n side: ConnectionSide;\n relationshipId: string;\n isSource: boolean;\n slotIndex: number;\n totalSlots: number;\n}\n\n/**\n * Padded connection point - sits at padding distance from node edge\n */\nexport interface PaddedPoint {\n x: number;\n y: number;\n side: ConnectionSide;\n nodeEdgeX: number;\n nodeEdgeY: number;\n}\n\n/**\n * Get preferred connection side based on relative position of nodes\n */\nexport function getPreferredSide(from: PathNode, to: PathNode): ConnectionSide {\n const fromCenterX = from.x + from.width / 2;\n const fromCenterY = from.y + from.height / 2;\n const toCenterX = to.x + to.width / 2;\n const toCenterY = to.y + to.height / 2;\n\n const dx = toCenterX - fromCenterX;\n const dy = toCenterY - fromCenterY;\n\n if (Math.abs(dx) > Math.abs(dy)) {\n return dx > 0 ? 'right' : 'left';\n } else {\n return dy > 0 ? 'bottom' : 'top';\n }\n}\n\n/**\n * Get connection point on a node\n */\nexport function getConnectionPoint(\n node: PathNode,\n targetNode: PathNode,\n forcedAnchor: ConnectionSide | undefined,\n cornerPadding: number,\n slot?: AnchorSlot,\n anchorSpacing?: number\n): ConnectionPoint {\n const side = forcedAnchor || getPreferredSide(node, targetNode);\n const point = getPointOnSide(node, side, cornerPadding, slot, anchorSpacing);\n return { side, x: point.x, y: point.y };\n}\n\n/**\n * Get point on a specific side of a node\n * Uses even distribution when multiple slots are on the same side\n */\nexport function getPointOnSide(\n node: PathNode,\n side: ConnectionSide,\n cornerPadding: number,\n slot?: AnchorSlot,\n _anchorSpacing?: number // kept for API compatibility but not used\n): Point {\n // Calculate position on edge using even distribution\n const isVerticalSide = side === 'left' || side === 'right';\n const edgeLength = isVerticalSide ? node.height : node.width;\n const usableLength = edgeLength - 2 * cornerPadding;\n\n let edgePosition: number;\n if (slot && slot.totalSlots > 1) {\n // Distribute evenly: for N slots, divide into N+1 segments\n const t = (slot.slotIndex + 1) / (slot.totalSlots + 1);\n edgePosition = cornerPadding + t * usableLength;\n } else {\n // Single slot or no slot - use center\n edgePosition = edgeLength / 2;\n }\n\n switch (side) {\n case 'top':\n return {\n x: node.x + edgePosition,\n y: node.y,\n };\n case 'bottom':\n return {\n x: node.x + edgePosition,\n y: node.y + node.height,\n };\n case 'left':\n return {\n x: node.x,\n y: node.y + edgePosition,\n };\n case 'right':\n return {\n x: node.x + node.width,\n y: node.y + edgePosition,\n };\n }\n}\n\n/**\n * Get a padded point - sits at padding distance from node edge\n * Uses even distribution when multiple slots are on the same side\n */\nexport function getPaddedPoint(\n node: PathNode,\n side: ConnectionSide,\n padding: number,\n cornerPadding: number,\n slot?: AnchorSlot\n): PaddedPoint {\n // Calculate position on edge using even distribution\n const isVerticalSide = side === 'left' || side === 'right';\n const edgeLength = isVerticalSide ? node.height : node.width;\n const usableLength = edgeLength - 2 * cornerPadding;\n\n let edgePosition: number;\n if (slot && slot.totalSlots > 1) {\n // Distribute evenly: for N slots, divide into N+1 segments\n const t = (slot.slotIndex + 1) / (slot.totalSlots + 1);\n edgePosition = cornerPadding + t * usableLength;\n } else {\n // Single slot or no slot - use center\n edgePosition = edgeLength / 2;\n }\n\n switch (side) {\n case 'top': {\n const edgeX = node.x + edgePosition;\n return {\n x: edgeX,\n y: node.y - padding,\n side,\n nodeEdgeX: edgeX,\n nodeEdgeY: node.y,\n };\n }\n case 'bottom': {\n const edgeX = node.x + edgePosition;\n return {\n x: edgeX,\n y: node.y + node.height + padding,\n side,\n nodeEdgeX: edgeX,\n nodeEdgeY: node.y + node.height,\n };\n }\n case 'left': {\n const edgeY = node.y + edgePosition;\n return {\n x: node.x - padding,\n y: edgeY,\n side,\n nodeEdgeX: node.x,\n nodeEdgeY: edgeY,\n };\n }\n case 'right': {\n const edgeY = node.y + edgePosition;\n return {\n x: node.x + node.width + padding,\n y: edgeY,\n side,\n nodeEdgeX: node.x + node.width,\n nodeEdgeY: edgeY,\n };\n }\n }\n}\n\n/**\n * Calculate actual slot positions on a node edge\n * Uses even distribution across the available edge space\n */\nexport function calculateSlotPositions(\n node: PathNode,\n side: ConnectionSide,\n totalSlots: number,\n cornerPadding = 5\n): Array<{ x: number; y: number }> {\n const positions: Array<{ x: number; y: number }> = [];\n\n // Calculate the available range on this edge\n const isVerticalSide = side === 'left' || side === 'right';\n const edgeLength = isVerticalSide ? node.height : node.width;\n const usableLength = edgeLength - 2 * cornerPadding;\n\n for (let i = 0; i < totalSlots; i++) {\n // Distribute evenly: for N slots, divide into N+1 segments\n // and place slots at positions 1, 2, ..., N\n const t = (i + 1) / (totalSlots + 1);\n const offset = cornerPadding + t * usableLength;\n\n switch (side) {\n case 'top':\n positions.push({ x: node.x + offset, y: node.y });\n break;\n case 'bottom':\n positions.push({ x: node.x + offset, y: node.y + node.height });\n break;\n case 'left':\n positions.push({ x: node.x, y: node.y + offset });\n break;\n case 'right':\n positions.push({ x: node.x + node.width, y: node.y + offset });\n break;\n }\n }\n\n return positions;\n}\n\n/**\n * Find optimal slot assignment to minimize crossings\n * Returns an array where assignment[connIndex] = slotIndex\n */\nexport function findOptimalSlotAssignment(\n connections: Array<{ otherNodeX: number; otherNodeY: number; relationshipId: string; isSource: boolean }>,\n slotPositions: Array<{ x: number; y: number }>\n): number[] {\n const n = connections.length;\n\n // For small numbers, try all permutations to find the best one\n if (n <= 6) {\n return findBestPermutation(connections, slotPositions);\n }\n\n // For larger numbers, use greedy assignment based on distance\n return greedySlotAssignment(connections, slotPositions);\n}\n\n/**\n * Try all permutations to find the one with minimum total distance\n */\nfunction findBestPermutation(\n connections: Array<{ otherNodeX: number; otherNodeY: number }>,\n slotPositions: Array<{ x: number; y: number }>\n): number[] {\n const n = connections.length;\n const indices = Array.from({ length: n }, (_, i) => i);\n let bestAssignment = indices.slice();\n let bestScore = Infinity;\n\n // Generate all permutations\n const permute = (arr: number[], start: number) => {\n if (start === arr.length - 1) {\n // Calculate score for this permutation\n let totalDist = 0;\n for (let i = 0; i < n; i++) {\n const slot = slotPositions[arr[i]];\n const conn = connections[i];\n totalDist += Math.hypot(conn.otherNodeX - slot.x, conn.otherNodeY - slot.y);\n }\n\n if (totalDist < bestScore) {\n bestScore = totalDist;\n bestAssignment = arr.slice();\n }\n return;\n }\n\n for (let i = start; i < arr.length; i++) {\n [arr[start], arr[i]] = [arr[i], arr[start]];\n permute(arr, start + 1);\n [arr[start], arr[i]] = [arr[i], arr[start]];\n }\n };\n\n permute(indices, 0);\n return bestAssignment;\n}\n\n/**\n * Greedy slot assignment for larger numbers of connections\n */\nfunction greedySlotAssignment(\n connections: Array<{ otherNodeX: number; otherNodeY: number }>,\n slotPositions: Array<{ x: number; y: number }>\n): number[] {\n const n = connections.length;\n const assignment: number[] = new Array(n).fill(-1);\n const usedSlots = new Set<number>();\n\n // Create distance matrix\n const distances: Array<{ connIdx: number; slotIdx: number; dist: number }> = [];\n for (let c = 0; c < n; c++) {\n for (let s = 0; s < n; s++) {\n const dist = Math.hypot(\n connections[c].otherNodeX - slotPositions[s].x,\n connections[c].otherNodeY - slotPositions[s].y\n );\n distances.push({ connIdx: c, slotIdx: s, dist });\n }\n }\n\n // Sort by distance and greedily assign\n distances.sort((a, b) => a.dist - b.dist);\n\n for (const { connIdx, slotIdx } of distances) {\n if (assignment[connIdx] === -1 && !usedSlots.has(slotIdx)) {\n assignment[connIdx] = slotIdx;\n usedSlots.add(slotIdx);\n }\n }\n\n return assignment;\n}\n\n/**\n * Calculate anchor slot assignments based on actual path results\n * This uses the sides that were actually chosen by the routing algorithm\n */\nexport function calculateAnchorSlotsFromPaths(\n paths: CalculatedPath[],\n nodeMap: Map<string, PathNode>\n): Map<string, AnchorSlot> {\n const slots = new Map<string, AnchorSlot>();\n\n // Group connections by node and side\n const connectionsByNodeSide = new Map<\n string,\n Array<{\n relationshipId: string;\n isSource: boolean;\n otherNodeX: number;\n otherNodeY: number;\n }>\n >();\n\n for (const path of paths) {\n const sourceNode = nodeMap.get(path.sourceId);\n const targetNode = nodeMap.get(path.targetId);\n\n if (!sourceNode || !targetNode) continue;\n\n // Use the actual sides from the calculated path\n const sourceSide = path.sourcePoint.side;\n const targetSide = path.targetPoint.side;\n\n // Source connection\n const sourceKey = `${path.sourceId}:${sourceSide}`;\n if (!connectionsByNodeSide.has(sourceKey)) {\n connectionsByNodeSide.set(sourceKey, []);\n }\n connectionsByNodeSide.get(sourceKey)!.push({\n relationshipId: path.relationshipId,\n isSource: true,\n otherNodeX: targetNode.x + targetNode.width / 2,\n otherNodeY: targetNode.y + targetNode.height / 2,\n });\n\n // Target connection\n const targetKey = `${path.targetId}:${targetSide}`;\n if (!connectionsByNodeSide.has(targetKey)) {\n connectionsByNodeSide.set(targetKey, []);\n }\n connectionsByNodeSide.get(targetKey)!.push({\n relationshipId: path.relationshipId,\n isSource: false,\n otherNodeX: sourceNode.x + sourceNode.width / 2,\n otherNodeY: sourceNode.y + sourceNode.height / 2,\n });\n }\n\n // Assign slots for each node-side combination\n for (const [key, connections] of connectionsByNodeSide) {\n const [nodeId, side] = key.split(':') as [string, ConnectionSide];\n const node = nodeMap.get(nodeId);\n if (!node) continue;\n\n const totalSlots = connections.length;\n\n if (totalSlots === 1) {\n // Single connection - just assign slot 0\n const conn = connections[0];\n const slotKey = `${conn.relationshipId}-${conn.isSource ? 'source' : 'target'}`;\n slots.set(slotKey, {\n nodeId,\n side,\n relationshipId: conn.relationshipId,\n isSource: conn.isSource,\n slotIndex: 0,\n totalSlots: 1,\n });\n continue;\n }\n\n // Calculate the actual slot positions on the node edge\n const slotPositions = calculateSlotPositions(node, side, totalSlots);\n\n // Find optimal assignment: pair each connection with a slot position\n // to minimize total distance and avoid crossings\n const assignment = findOptimalSlotAssignment(connections, slotPositions);\n\n // Assign slots based on the optimal pairing\n assignment.forEach((slotIndex, connIndex) => {\n const conn = connections[connIndex];\n const slotKey = `${conn.relationshipId}-${conn.isSource ? 'source' : 'target'}`;\n slots.set(slotKey, {\n nodeId,\n side,\n relationshipId: conn.relationshipId,\n isSource: conn.isSource,\n slotIndex,\n totalSlots,\n });\n });\n }\n\n return slots;\n}\n","/**\n * Geometry Utilities\n *\n * Core geometric types and functions for path finding calculations.\n */\n\nimport { Point, PathNode } from '../models/path-finding.models';\n\n/**\n * Rectangle with computed bounds for efficient collision detection\n */\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n right: number;\n bottom: number;\n centerX: number;\n centerY: number;\n}\n\n/**\n * Clamp a value between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Create a Rect from a PathNode\n */\nexport function createRect(node: PathNode): Rect {\n return {\n x: node.x,\n y: node.y,\n width: node.width,\n height: node.height,\n right: node.x + node.width,\n bottom: node.y + node.height,\n centerX: node.x + node.width / 2,\n centerY: node.y + node.height / 2,\n };\n}\n\n/**\n * Create a padded Rect from a PathNode\n */\nexport function createPaddedRect(node: PathNode, padding: number): Rect {\n return {\n x: node.x - padding,\n y: node.y - padding,\n width: node.width + padding * 2,\n height: node.height + padding * 2,\n right: node.x + node.width + padding,\n bottom: node.y + node.height + padding,\n centerX: node.x + node.width / 2,\n centerY: node.y + node.height / 2,\n };\n}\n\n/**\n * Expand a Rect by padding amount on all sides\n */\nexport function expandRect(rect: Rect, padding: number): Rect {\n return {\n x: rect.x - padding,\n y: rect.y - padding,\n width: rect.width + padding * 2,\n height: rect.height + padding * 2,\n right: rect.right + padding,\n bottom: rect.bottom + padding,\n centerX: rect.centerX,\n centerY: rect.centerY,\n };\n}\n\n/**\n * Check if a line segment passes through rectangle interior (not just touches edge)\n * Used for obstacle collision detection in orthogonal routing\n */\nexport function linePassesThroughRect(p1: Point, p2: Point, rect: Rect): boolean {\n // Check bounding box overlap first\n const lineMinX = Math.min(p1.x, p2.x);\n const lineMaxX = Math.max(p1.x, p2.x);\n const lineMinY = Math.min(p1.y, p2.y);\n const lineMaxY = Math.max(p1.y, p2.y);\n\n // No overlap at all\n if (lineMaxX <= rect.x || lineMinX >= rect.right) return false;\n if (lineMaxY <= rect.y || lineMinY >= rect.bottom) return false;\n\n // For orthogonal lines, check if line passes through interior\n const isVertical = Math.abs(p1.x - p2.x) < 0.001;\n const isHorizontal = Math.abs(p1.y - p2.y) < 0.001;\n\n if (isVertical) {\n // Vertical line: passes through if x is strictly inside rect\n return p1.x > rect.x && p1.x < rect.right;\n }\n\n if (isHorizontal) {\n // Horizontal line: passes through if y is strictly inside rect\n return p1.y > rect.y && p1.y < rect.bottom;\n }\n\n // Diagonal line (shouldn't happen for orthogonal routing)\n return true;\n}\n","/**\n * Orthogonal Path Strategy\n *\n * Generates paths with right-angle turns only (Manhattan-style routing).\n * Supports obstacle avoidance with multiple routing strategies.\n */\n\nimport { Waypoint, ConnectionSide, PathNode } from '../models/path-finding.models';\nimport { PathStrategy, PathStrategyContext, PathStrategyResult, RouteCandidate } from './path-strategy.interface';\nimport { Rect, createRect, createPaddedRect, expandRect, linePassesThroughRect } from '../utils/geometry.utils';\nimport { simplifyPath, calculateRouteLength } from '../utils/path.utils';\nimport { getPreferredSide, getPaddedPoint, PaddedPoint, AnchorSlot } from '../utils/anchor.utils';\n\n/**\n * Orthogonal path strategy - routes paths with right-angle turns\n */\nexport class OrthogonalStrategy implements PathStrategy {\n calculatePath(context: PathStrategyContext): PathStrategyResult {\n const { source, target, relationship, allNodes, options, sourceSlot, targetSlot } = context;\n const padding = options.obstaclePadding;\n\n // Create rectangles for collision detection\n const sourceRect = createRect(source);\n const targetRect = createRect(target);\n\n // Get obstacles (all nodes except source and target, with padding)\n const obstacles = options.allowOverlap\n ? []\n : allNodes\n .filter((n) => n.id !== source.id && n.id !== target.id)\n .map((n) => createPaddedRect(n, padding));\n\n // If we have slots from a previous pass, force those sides to maintain consistency\n const forcedSourceSide = sourceSlot?.side ?? relationship.sourceAnchor;\n const forcedTargetSide = targetSlot?.side ?? relationship.targetAnchor;\n\n const bestRoute = this.findBestOrthogonalRoute(\n source,\n target,\n sourceRect,\n targetRect,\n obstacles,\n padding,\n forcedSourceSide,\n forcedTargetSide,\n options.cornerPadding,\n sourceSlot,\n targetSlot\n );\n\n return {\n sourcePoint: {\n side: bestRoute.sourceSide,\n x: bestRoute.waypoints[0].x,\n y: bestRoute.waypoints[0].y,\n },\n targetPoint: {\n side: bestRoute.targetSide,\n x: bestRoute.waypoints[bestRoute.waypoints.length - 1].x,\n y: bestRoute.waypoints[bestRoute.waypoints.length - 1].y,\n },\n waypoints: bestRoute.waypoints,\n };\n }\n\n /**\n * Find the best orthogonal route using padded-edge approach\n */\n private findBestOrthogonalRoute(\n sourceNode: PathNode,\n targetNode: PathNode,\n sourceRect: Rect,\n targetRect: Rect,\n obstacles: Rect[],\n padding: number,\n forcedSourceSide: ConnectionSide | undefined,\n forcedTargetSide: ConnectionSide | undefined,\n cornerPadding: number,\n sourceSlot?: AnchorSlot,\n targetSlot?: AnchorSlot\n ): RouteCandidate {\n const candidates: RouteCandidate[] = [];\n\n // Determine which sides to try\n const sourceSides: ConnectionSide[] = forcedSourceSide\n ? [forcedSourceSide]\n : ['top', 'right', 'bottom', 'left'];\n\n const targetSides: ConnectionSide[] = forcedTargetSide\n ? [forcedTargetSide]\n : ['top', 'right', 'bottom', 'left'];\n\n // Try all side combinations\n for (const sourceSide of sourceSides) {\n for (const targetSide of targetSides) {\n // Get padded points (at padding distance from node edge)\n const sourcePadded = getPaddedPoint(sourceNode, sourceSide, padding, cornerPadding, sourceSlot);\n const targetPadded = getPaddedPoint(targetNode, targetSide, padding, cornerPadding, targetSlot);\n\n // Find route between padded points\n const paddedRoute = this.findPaddedRoute(sourcePadded, targetPadded, sourceRect, targetRect, obstacles, padding);\n\n if (paddedRoute) {\n // Extend route to actual node edges\n const fullRoute = this.extendRouteToEdges(paddedRoute, sourcePadded, targetPadded);\n const length = calculateRouteLength(fullRoute);\n\n candidates.push({\n waypoints: fullRoute,\n length,\n sourceSide,\n targetSide,\n });\n }\n }\n }\n\n // Return the shortest valid route\n if (candidates.length > 0) {\n candidates.sort((a, b) => a.length - b.length);\n return candidates[0];\n }\n\n // Fallback: simple direct route\n const preferredSourceSide = forcedSourceSide || getPreferredSide(sourceNode, targetNode);\n const preferredTargetSide = forcedTargetSide || getPreferredSide(targetNode, sourceNode);\n\n const sourcePadded = getPaddedPoint(sourceNode, preferredSourceSide, padding, cornerPadding, sourceSlot);\n const targetPadded = getPaddedPoint(targetNode, preferredTargetSide, padding, cornerPadding, targetSlot);\n\n const fallbackRoute = this.createFallbackRoute(sourcePadded, targetPadded);\n const fullRoute = this.extendRouteToEdges(fallbackRoute, sourcePadded, targetPadded);\n\n return {\n waypoints: fullRoute,\n length: Infinity,\n sourceSide: preferredSourceSide,\n targetSide: preferredTargetSide,\n };\n }\n\n /**\n * Find route between padded points avoiding obstacles\n */\n private findPaddedRoute(\n source: PaddedPoint,\n target: PaddedPoint,\n sourceRect: Rect,\n targetRect: Rect,\n obstacles: Rect[],\n padding: number\n ): Waypoint[] | null {\n // Create padded obstacle rects for collision detection\n // Include source and target nodes as obstacles (paths shouldn't go through them)\n const paddedSourceRect = expandRect(sourceRect, padding);\n const paddedTargetRect = expandRect(targetRect, padding);\n const allObstacles = [...obstacles, paddedSourceRect, paddedTargetRect];\n\n // Try strategies in order of simplicity\n const strategies = [\n () => this.tryDirect(source, target, allObstacles),\n () => this.tryLShape(source, target, allObstacles),\n () => this.tryZShape(source, target, allObstacles),\n () => this.tryUShape(source, target, sourceRect, targetRect, allObstacles, padding),\n ];\n\n for (const strategy of strategies) {\n const route = strategy();\n if (route) {\n return simplifyPath(route);\n }\n }\n\n return null;\n }\n\n /**\n * Try direct route (straight line between padded points)\n */\n private tryDirect(source: PaddedPoint, target: PaddedPoint, obstacles: Rect[]): Waypoint[] | null {\n // Only works if horizontally or vertically aligned\n const isHorizontal = Math.abs(source.y - target.y) < 1;\n const isVertical = Math.abs(source.x - target.x) < 1;\n\n if (!isHorizontal && !isVertical) return null;\n\n const route: Waypoint[] = [\n { x: source.x, y: source.y },\n { x: target.x, y: target.y },\n ];\n\n if (this.isRouteValid(route, obstacles)) {\n return route;\n }\n\n return null;\n }\n\n /**\n * Try L-shaped route (one bend)\n */\n private tryLShape(source: PaddedPoint, target: PaddedPoint, obstacles: Rect[]): Waypoint[] | null {\n const isHorizontalSource = source.side === 'left' || source.side === 'right';\n const isHorizontalTarget = target.side === 'left' || target.side === 'right';\n\n // L-route only works when source and target are on different axis\n if (isHorizontalSource === isHorizontalTarget) return null;\n\n const routes: Waypoint[][] = [];\n\n if (isHorizontalSource) {\n // Source horizontal, target vertical: go horizontal first, then vertical\n routes.push([\n { x: source.x, y: source.y },\n { x: target.x, y: source.y },\n { x: target.x, y: target.y },\n ]);\n } else {\n // Source vertical, target horizontal: go vertical first, then horizontal\n routes.push([\n { x: source.x, y: source.y },\n { x: source.x, y: target.y },\n { x: target.x, y: target.y },\n ]);\n }\n\n for (const route of routes) {\n if (this.isRouteValid(route, obstacles)) {\n return route;\n }\n }\n\n return null;\n }\n\n /**\n * Try Z-shaped route (two bends)\n */\n private tryZShape(source: PaddedPoint, target: PaddedPoint, obstacles: Rect[]): Waypoint[] | null {\n const isHorizontalSource = source.side === 'left' || source.side === 'right';\n const isHorizontalTarget = target.side === 'left' || target.side === 'right';\n\n const routes: Waypoint[][] = [];\n\n if (isHorizontalSource && isHorizontalTarget) {\n // Both horizontal: route with vertical middle segment\n const midX = (source.x + target.x) / 2;\n routes.push([\n { x: source.x, y: source.y },\n { x: midX, y: source.y },\n { x: midX, y: target.y },\n { x: target.x, y: target.y },\n ]);\n } else if (!isHorizontalSource && !isHorizontalTarget) {\n // Both vertical: route with horizontal middle segment\n const midY = (source.y + target.y) / 2;\n routes.push([\n { x: source.x, y: source.y },\n { x: source.x, y: midY },\n { x: target.x, y: midY },\n { x: target.x, y: target.y },\n ]);\n }\n\n // Sort by length and return first valid\n routes.sort((a, b) => calculateRouteLength(a) - calculateRouteLength(b));\n\n for (const route of routes) {\n if (this.isRouteValid(route, obstacles)) {\n return route;\n }\n }\n\n return null;\n }\n\n /**\n * Try U-shaped route (goes around nodes)\n */\n private tryUShape(\n source: PaddedPoint,\n target: PaddedPoint,\n sourceRect: Rect,\n targetRect: Rect,\n obstacles: Rect[],\n padding: number\n ): Waypoint[] | null {\n const routes: Waypoint[][] = [];\n\n // Calculate bounds for going around\n const minX = Math.min(sourceRect.x, targetRect.x) - padding * 2;\n const maxX = Math.max(sourceRect.right, targetRect.right) + padding * 2;\n const minY = Math.min(sourceRect.y, targetRect.y) - padding * 2;\n const maxY = Math.max(sourceRect.bottom, targetRect.bottom) + padding * 2;\n\n // Route around top\n routes.push([\n { x: source.x, y: source.y },\n { x: source.x, y: minY },\n { x: target.x, y: minY },\n { x: target.x, y: target.y },\n ]);\n\n // Route around bottom\n routes.push([\n { x: source.x, y: source.y },\n { x: source.x, y: maxY },\n { x: target.x, y: maxY },\n { x: target.x, y: target.y },\n ]);\n\n // Route around left\n routes.push([\n { x: source.x, y: source.y },\n { x: minX, y: source.y },\n { x: minX, y: target.y },\n { x: target.x, y: target.y },\n ]);\n\n // Route around right\n routes.push([\n { x: source.x, y: source.y },\n { x: maxX, y: source.y },\n { x: maxX, y: target.y },\n { x: target.x, y: target.y },\n ]);\n\n // Sort by length and return first valid\n routes.sort((a, b) => calculateRouteLength(a) - calculateRouteLength(b));\n\n for (const route of routes) {\n if (this.isRouteValid(route, obstacles)) {\n return route;\n }\n }\n\n return null;\n }\n\n /**\n * Create fallback route when no valid route is found\n */\n private createFallbackRoute(source: PaddedPoint, target: PaddedPoint): Waypoint[] {\n const isHorizontalSource = source.side === 'left' || source.side === 'right';\n\n if (isHorizontalSource) {\n return [\n { x: source.x, y: source.y },\n { x: target.x, y: source.y },\n { x: target.x, y: target.y },\n ];\n } else {\n return [\n { x: source.x, y: source.y },\n { x: source.x, y: target.y },\n { x: target.x, y: target.y },\n ];\n }\n }\n\n /**\n * Extend route from padded points to actual node edges\n */\n private extendRouteToEdges(paddedRoute: Waypoint[], source: PaddedPoint, target: PaddedPoint): Waypoint[] {\n const result: Waypoint[] = [];\n\n // Add start point at node edge\n result.push({ x: source.nodeEdgeX, y: source.nodeEdgeY });\n\n // Add all waypoints from padded route\n for (const wp of paddedRoute) {\n result.push({ x: wp.x, y: wp.y });\n }\n\n // Add end point at node edge\n result.push({ x: target.nodeEdgeX, y: target.nodeEdgeY });\n\n return simplifyPath(result);\n }\n\n /**\n * Check if route is valid (doesn't pass through obstacles)\n */\n private isRouteValid(route: Waypoint[], obstacles: Rect[]): boolean {\n for (let i = 0; i < route.length - 1; i++) {\n const p1 = route[i];\n const p2 = route[i + 1];\n\n for (const obs of obstacles) {\n if (linePassesThroughRect(p1, p2, obs)) {\n return false;\n }\n }\n }\n return true;\n }\n}\n","/**\n * Bezier Path Strategy\n *\n * Generates smooth curved paths using cubic bezier curves.\n * Control points are positioned based on connection sides.\n */\n\nimport { Point, Waypoint, ConnectionPoint } from '../models/path-finding.models';\nimport { PathStrategy, PathStrategyContext, PathStrategyResult } from './path-strategy.interface';\nimport { getConnectionPoint } from '../utils/anchor.utils';\n\n/**\n * Bezier path strategy - creates smooth curved paths\n */\nexport class BezierStrategy implements PathStrategy {\n calculatePath(context: PathStrategyContext): PathStrategyResult {\n const { source, target, relationship, options, sourceSlot, targetSlot } = context;\n\n const sourcePoint = getConnectionPoint(\n source,\n target,\n relationship.sourceAnchor,\n options.cornerPadding,\n sourceSlot,\n options.anchorSpacing\n );\n\n const targetPoint = getConnectionPoint(\n target,\n source,\n relationship.targetAnchor,\n options.cornerPadding,\n targetSlot,\n options.anchorSpacing\n );\n\n const waypoints = this.calculateBezierPath(sourcePoint, targetPoint);\n\n return {\n sourcePoint,\n targetPoint,\n waypoints,\n };\n }\n\n /**\n * Calculate bezier path with control points\n */\n private calculateBezierPath(source: ConnectionPoint, target: ConnectionPoint): Waypoint[] {\n const controlDistance = Math.max(50, Math.hypot(target.x - source.x, target.y - source.y) * 0.3);\n\n const sourceControl = this.getControlPointForBezier(source, controlDistance);\n const targetControl = this.getControlPointForBezier(target, controlDistance);\n\n return [\n { x: source.x, y: source.y },\n { x: sourceControl.x, y: sourceControl.y, isControlPoint: true },\n { x: targetControl.x, y: targetControl.y, isControlPoint: true },\n { x: target.x, y: target.y },\n ];\n }\n\n /**\n * Get control point position based on connection side\n */\n private getControlPointForBezier(connection: ConnectionPoint, distance: number): Point {\n switch (connection.side) {\n case 'top':\n return { x: connection.x, y: connection.y - distance };\n case 'bottom':\n return { x: connection.x, y: connection.y + distance };\n case 'left':\n return { x: connection.x - distance, y: connection.y };\n case 'right':\n return { x: connection.x + distance, y: connection.y };\n }\n }\n}\n","/**\n * Straight Path Strategy\n *\n * Generates direct line paths between nodes.\n * Simple and fast, but may overlap obstacles.\n */\n\nimport { Waypoint } from '../models/path-finding.models';\nimport { PathStrategy, PathStrategyContext, PathStrategyResult } from './path-strategy.interface';\nimport { getConnectionPoint } from '../utils/anchor.utils';\n\n/**\n * Straight path strategy - creates direct line paths\n */\nexport class StraightStrategy implements PathStrategy {\n calculatePath(context: PathStrategyContext): PathStrategyResult {\n const { source, target, relationship, options, sourceSlot, targetSlot } = context;\n\n const sourcePoint = getConnectionPoint(\n source,\n target,\n relationship.sourceAnchor,\n options.cornerPadding,\n sourceSlot,\n options.anchorSpacing\n );\n\n const targetPoint = getConnectionPoint(\n target,\n source,\n relationship.targetAnchor,\n options.cornerPadding,\n targetSlot,\n options.anchorSpacing\n );\n\n const waypoints: Waypoint[] = [\n { x: sourcePoint.x, y: sourcePoint.y },\n { x: targetPoint.x, y: targetPoint.y },\n ];\n\n return {\n sourcePoint,\n targetPoint,\n waypoints,\n };\n }\n}\n","import { Injectable } from '@angular/core';\r\nimport {\r\n PathNode,\r\n PathRelationship,\r\n PathFindingOptions,\r\n PathFindingInput,\r\n PathFindingResult,\r\n CalculatedPath,\r\n DEFAULT_PATH_FINDING_OPTIONS,\r\n} from '../models/path-finding.models';\r\nimport { calculateMidpoint, calculatePathLength } from '../utils/path.utils';\r\nimport { AnchorSlot, calculateAnchorSlotsFromPaths } from '../utils/anchor.utils';\r\nimport { PathStrategy, PathStrategyContext } from '../strategies/path-strategy.interface';\r\nimport { OrthogonalStrategy } from '../strategies/orthogonal.strategy';\r\nimport { BezierStrategy } from '../strategies/bezier.strategy';\r\nimport { StraightStrategy } from '../strategies/straight.strategy';\r\n\r\n/**\r\n * Path Finding Service\r\n *\r\n * Calculates obstacle-aware paths between nodes using smart routing.\r\n * Automatically selects optimal connection sides to find shortest valid paths.\r\n *\r\n * Uses strategy pattern for different path types:\r\n * - Orthogonal: Right-angle turns with obstacle avoidance\r\n * - Bezier: Smooth curved paths\r\n * - Straight: Direct line paths\r\n */\r\n@Injectable()\r\nexport class PathFindingService {\r\n private readonly strategies: Record<string, PathStrategy> = {\r\n orthogonal: new OrthogonalStrategy(),\r\n bezier: new BezierStrategy(),\r\n straight: new StraightStrategy(),\r\n };\r\n\r\n /**\r\n * Calculate paths for all relationships\r\n */\r\n calculatePaths(input: PathFindingInput): PathFindingResult {\r\n const options = { ...DEFAULT_PATH_FINDING_OPTIONS, ...input.options };\r\n const nodeMap = new Map<string, PathNode>();\r\n\r\n for (const node of input.nodes) {\r\n nodeMap.set(node.id, node);\r\n }\r\n\r\n // First pass: calculate paths without anchor spreading to determine actual sides\r\n const initialPaths: CalculatedPath[] = [];\r\n\r\n for (const relationship of input.relationships) {\r\n const sourceNode = nodeMap.get(relationship.sourceId);\r\n const targetNode = nodeMap.get(relationship.targetId);\r\n\r\n if (!sourceNode || !targetNode) {\r\n console.warn(\r\n `PathFindingService: Relationship \"${relationship.id}\" references unknown node`\r\n );\r\n continue;\r\n }\r\n\r\n const path = this.calculatePath(\r\n sourceNode,\r\n targetNode,\r\n relationship,\r\n input.nodes,\r\n options,\r\n undefined,\r\n undefined\r\n );\r\n\r\n initialPaths.push(path);\r\n }\r\n\r\n // If anchor spreading is disabled, return initial paths\r\n if (!options.spreadAnchors) {\r\n return { paths: initialPaths };\r\n }\r\n\r\n // Second pass: calculate anchor slots based on actual sides used, then recalculate paths\r\n const anchorSlots = calculateAnchorSlotsFromPaths(initialPaths, nodeMap);\r\n\r\n const paths: CalculatedPath[] = [];\r\n\r\n for (const relationship of input.relationships) {\r\n const sourceNode = nodeMap.get(relationship.sourceId);\r\n const targetNode = nodeMap.get(relationship.targetId);\r\n\r\n if (!sourceNode || !targetNode) {\r\n continue;\r\n }\r\n\r\n const sourceSlot = anchorSlots.get(`${relationship.id}-source`);\r\n const targetSlot = anchorSlots.get(`${relationship.id}-target`);\r\n\r\n const path = this.calculatePath(\r\n sourceNode,\r\n targetNode,\r\n relationship,\r\n input.nodes,\r\n options,\r\n sourceSlot,\r\n targetSlot\r\n );\r\n\r\n paths.push(path);\r\n }\r\n\r\n return { paths };\r\n }\r\n\r\n /**\r\n * Calculate a single path between two nodes\r\n */\r\n private calculatePath(\r\n source: PathNode,\r\n target: PathNode,\r\n relationship: PathRelationship,\r\n allNodes: PathNode[],\r\n options: Required<PathFindingOptions>,\r\n sourceSlot?: AnchorSlot,\r\n targetSlot?: AnchorSlot\r\n ): CalculatedPath {\r\n const strategy = this.strategies[options.pathType];\r\n\r\n const context: PathStrategyContext = {\r\n source,\r\n target,\r\n relationship,\r\n allNodes,\r\n options,\r\n sourceSlot,\r\n targetSlot,\r\n };\r\n\r\n const result = strategy.calculatePath(context);\r\n const midpoint = calculateMidpoint(result.waypoints);\r\n const length = calculatePathLength(result.waypoints);\r\n\r\n return {\r\n relationshipId: relationship.id,\r\n sourceId: relationship.sourceId,\r\n targetId: relationship.targetId,\r\n sourcePoint: result.sourcePoint,\r\n targetPoint: result.targetPoint,\r\n waypoints: result.waypoints,\r\n midpoint,\r\n length,\r\n pathType: options.pathType,\r\n };\r\n }\r\n\r\n /**\r\n * Recalculate paths (convenience method)\r\n */\r\n recalculatePaths(input: PathFindingInput): PathFindingResult {\r\n return this.calculatePaths(input);\r\n }\r\n\r\n /**\r\n * Calculate a single path (convenience method)\r\n */\r\n calculateSinglePath(\r\n source: PathNode,\r\n target: PathNode,\r\n relationship: PathRelationship,\r\n obstacles: PathNode[],\r\n options?: PathFindingOptions\r\n ): CalculatedPath {\r\n const fullOptions = { ...DEFAULT_PATH_FINDING_OPTIONS, ...options };\r\n return this.calculatePath(\r\n source,\r\n target,\r\n relationship,\r\n obstacles,\r\n fullOptions,\r\n undefined,\r\n undefined\r\n );\r\n }\r\n}\r\n","// Models - Types\nexport type {\n PathType,\n ConnectionSide,\n Point,\n Rectangle,\n PathNode,\n PathRelationship,\n ConnectionPoint,\n Waypoint,\n CalculatedPath,\n PathFindingOptions,\n PathFindingInput,\n PathFindingResult,\n} from './lib/models/path-finding.models';\n\n// Models - Values\nexport { DEFAULT_PATH_FINDING_OPTIONS } from './lib/models/path-finding.models';\n\n// Service\nexport { PathFindingService } from './lib/services/path-finding.service';\n\n// Utilities - Geometry\nexport type { Rect } from './lib/utils/geometry.utils';\nexport {\n clamp,\n createRect,\n createPaddedRect,\n expandRect,\n linePassesThroughRect,\n} from './lib/utils/geometry.utils';\n\n// Utilities - Path\nexport {\n calculateRouteLength,\n calculatePathLength,\n calculateMidpoint,\n simplifyPath,\n} from './lib/utils/path.utils';\n\n// Utilities - Anchor\nexport type { AnchorSlot, PaddedPoint } from './lib/utils/anchor.utils';\nexport {\n getPreferredSide,\n getConnectionPoint,\n getPointOnSide,\n getPaddedPoint,\n calculateSlotPositions,\n findOptimalSlotAssignment,\n calculateAnchorSlotsFromPaths,\n} from './lib/utils/anchor.utils';\n\n// Strategies - Interface\nexport type {\n PathStrategyResult,\n PathStrategyContext,\n RouteCandidate,\n PathStrategy,\n} from './lib/strategies/path-strategy.interface';\n\n// Strategies - Implementations\nexport { OrthogonalStrategy } from './lib/strategies/orthogonal.strategy';\nexport { BezierStrategy } from './lib/strategies/bezier.strategy';\nexport { StraightStrategy } from './lib/strategies/straight.strategy';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,465 @@
1
+ import * as i0 from '@angular/core';
2
+
3
+ /**
4
+ * Path Finding Models
5
+ *
6
+ * Types and interfaces for obstacle-aware path routing between nodes.
7
+ */
8
+ /**
9
+ * Type of path to generate
10
+ * - orthogonal: Right-angle turns only (Manhattan-style)
11
+ * - bezier: Smooth curved paths
12
+ * - straight: Direct line (may overlap obstacles)
13
+ */
14
+ type PathType = 'orthogonal' | 'bezier' | 'straight';
15
+ /**
16
+ * Side of a node where a connection point is located
17
+ */
18
+ type ConnectionSide = 'top' | 'right' | 'bottom' | 'left';
19
+ /**
20
+ * A point in 2D space
21
+ */
22
+ interface Point {
23
+ x: number;
24
+ y: number;
25
+ }
26
+ /**
27
+ * A rectangle representing a node's bounds
28
+ */
29
+ interface Rectangle {
30
+ x: number;
31
+ y: number;
32
+ width: number;
33
+ height: number;
34
+ }
35
+ /**
36
+ * A node with position and dimensions for path finding
37
+ * Used as an obstacle when routing paths
38
+ */
39
+ interface PathNode {
40
+ /** Unique identifier */
41
+ id: string;
42
+ /** X coordinate (top-left corner) */
43
+ x: number;
44
+ /** Y coordinate (top-left corner) */
45
+ y: number;
46
+ /** Width of the node */
47
+ width: number;
48
+ /** Height of the node */
49
+ height: number;
50
+ }
51
+ /**
52
+ * A relationship/edge between two nodes that needs a path
53
+ */
54
+ interface PathRelationship {
55
+ /** Unique identifier for this relationship */
56
+ id: string;
57
+ /** ID of the source node */
58
+ sourceId: string;
59
+ /** ID of the target node */
60
+ targetId: string;
61
+ /** Optional: force connection from specific side of source */
62
+ sourceAnchor?: ConnectionSide;
63
+ /** Optional: force connection to specific side of target */
64
+ targetAnchor?: ConnectionSide;
65
+ }
66
+ /**
67
+ * A connection point on a node's edge
68
+ */
69
+ interface ConnectionPoint {
70
+ /** The side of the node */
71
+ side: ConnectionSide;
72
+ /** X coordinate of the connection point */
73
+ x: number;
74
+ /** Y coordinate of the connection point */
75
+ y: number;
76
+ }
77
+ /**
78
+ * A waypoint along a path
79
+ */
80
+ interface Waypoint extends Point {
81
+ /** Optional: indicates if this is a control point for bezier curves */
82
+ isControlPoint?: boolean;
83
+ }
84
+ /**
85
+ * A calculated path between two nodes
86
+ */
87
+ interface CalculatedPath {
88
+ /** The relationship ID this path corresponds to */
89
+ relationshipId: string;
90
+ /** Source node ID */
91
+ sourceId: string;
92
+ /** Target node ID */
93
+ targetId: string;
94
+ /** Connection point on source node */
95
+ sourcePoint: ConnectionPoint;
96
+ /** Connection point on target node */
97
+ targetPoint: ConnectionPoint;
98
+ /** Ordered list of waypoints forming the path */
99
+ waypoints: Waypoint[];
100
+ /** The midpoint of the path (useful for labels/pills) */
101
+ midpoint: Point;
102
+ /** Total length of the path */
103
+ length: number;
104
+ /** Type of path */
105
+ pathType: PathType;
106
+ }
107
+ /**
108
+ * Options for path finding
109
+ */
110
+ interface PathFindingOptions {
111
+ /** Type of path to generate */
112
+ pathType?: PathType;
113
+ /** Padding around obstacles when routing */
114
+ obstaclePadding?: number;
115
+ /** Minimum distance from node corners for connection points */
116
+ cornerPadding?: number;
117
+ /** Minimum spacing between connection points on same side */
118
+ connectionSpacing?: number;
119
+ /** Whether to allow paths to pass through other nodes */
120
+ allowOverlap?: boolean;
121
+ /** Whether to spread anchor points when multiple edges connect to the same side */
122
+ spreadAnchors?: boolean;
123
+ /** Spacing between spread anchor points (when spreadAnchors is enabled) */
124
+ anchorSpacing?: number;
125
+ }
126
+ /**
127
+ * Default path finding options
128
+ */
129
+ declare const DEFAULT_PATH_FINDING_OPTIONS: Required<PathFindingOptions>;
130
+ /**
131
+ * Input for path finding calculation
132
+ */
133
+ interface PathFindingInput {
134
+ /** All nodes (used as obstacles) */
135
+ nodes: PathNode[];
136
+ /** Relationships to calculate paths for */
137
+ relationships: PathRelationship[];
138
+ /** Path finding options */
139
+ options?: PathFindingOptions;
140
+ }
141
+ /**
142
+ * Result of path finding calculation
143
+ */
144
+ interface PathFindingResult {
145
+ /** Calculated paths for each relationship */
146
+ paths: CalculatedPath[];
147
+ }
148
+
149
+ /**
150
+ * Path Finding Service
151
+ *
152
+ * Calculates obstacle-aware paths between nodes using smart routing.
153
+ * Automatically selects optimal connection sides to find shortest valid paths.
154
+ *
155
+ * Uses strategy pattern for different path types:
156
+ * - Orthogonal: Right-angle turns with obstacle avoidance
157
+ * - Bezier: Smooth curved paths
158
+ * - Straight: Direct line paths
159
+ */
160
+ declare class PathFindingService {
161
+ private readonly strategies;
162
+ /**
163
+ * Calculate paths for all relationships
164
+ */
165
+ calculatePaths(input: PathFindingInput): PathFindingResult;
166
+ /**
167
+ * Calculate a single path between two nodes
168
+ */
169
+ private calculatePath;
170
+ /**
171
+ * Recalculate paths (convenience method)
172
+ */
173
+ recalculatePaths(input: PathFindingInput): PathFindingResult;
174
+ /**
175
+ * Calculate a single path (convenience method)
176
+ */
177
+ calculateSinglePath(source: PathNode, target: PathNode, relationship: PathRelationship, obstacles: PathNode[], options?: PathFindingOptions): CalculatedPath;
178
+ static ɵfac: i0.ɵɵFactoryDeclaration<PathFindingService, never>;
179
+ static ɵprov: i0.ɵɵInjectableDeclaration<PathFindingService>;
180
+ }
181
+
182
+ /**
183
+ * Geometry Utilities
184
+ *
185
+ * Core geometric types and functions for path finding calculations.
186
+ */
187
+
188
+ /**
189
+ * Rectangle with computed bounds for efficient collision detection
190
+ */
191
+ interface Rect {
192
+ x: number;
193
+ y: number;
194
+ width: number;
195
+ height: number;
196
+ right: number;
197
+ bottom: number;
198
+ centerX: number;
199
+ centerY: number;
200
+ }
201
+ /**
202
+ * Clamp a value between min and max
203
+ */
204
+ declare function clamp(value: number, min: number, max: number): number;
205
+ /**
206
+ * Create a Rect from a PathNode
207
+ */
208
+ declare function createRect(node: PathNode): Rect;
209
+ /**
210
+ * Create a padded Rect from a PathNode
211
+ */
212
+ declare function createPaddedRect(node: PathNode, padding: number): Rect;
213
+ /**
214
+ * Expand a Rect by padding amount on all sides
215
+ */
216
+ declare function expandRect(rect: Rect, padding: number): Rect;
217
+ /**
218
+ * Check if a line segment passes through rectangle interior (not just touches edge)
219
+ * Used for obstacle collision detection in orthogonal routing
220
+ */
221
+ declare function linePassesThroughRect(p1: Point, p2: Point, rect: Rect): boolean;
222
+
223
+ /**
224
+ * Path Utilities
225
+ *
226
+ * Functions for path manipulation, simplification, and measurement.
227
+ */
228
+
229
+ /**
230
+ * Calculate the length of a route using Manhattan distance (orthogonal segments)
231
+ * Used for comparing route candidates
232
+ */
233
+ declare function calculateRouteLength(points: Point[]): number;
234
+ /**
235
+ * Calculate total path length using Euclidean distance
236
+ * Excludes control points for bezier curves
237
+ */
238
+ declare function calculatePathLength(waypoints: Waypoint[]): number;
239
+ /**
240
+ * Calculate the midpoint of a path
241
+ * Returns the point at half the total path length
242
+ */
243
+ declare function calculateMidpoint(waypoints: Waypoint[]): Point;
244
+ /**
245
+ * Simplify path by removing collinear points
246
+ * This reduces redundant waypoints while preserving path shape
247
+ */
248
+ declare function simplifyPath(waypoints: Waypoint[]): Waypoint[];
249
+
250
+ /**
251
+ * Anchor Utilities
252
+ *
253
+ * Functions for calculating connection points and anchor slot assignments.
254
+ */
255
+
256
+ /**
257
+ * Anchor slot assignment for spreading multiple connections on the same side
258
+ */
259
+ interface AnchorSlot {
260
+ nodeId: string;
261
+ side: ConnectionSide;
262
+ relationshipId: string;
263
+ isSource: boolean;
264
+ slotIndex: number;
265
+ totalSlots: number;
266
+ }
267
+ /**
268
+ * Padded connection point - sits at padding distance from node edge
269
+ */
270
+ interface PaddedPoint {
271
+ x: number;
272
+ y: number;
273
+ side: ConnectionSide;
274
+ nodeEdgeX: number;
275
+ nodeEdgeY: number;
276
+ }
277
+ /**
278
+ * Get preferred connection side based on relative position of nodes
279
+ */
280
+ declare function getPreferredSide(from: PathNode, to: PathNode): ConnectionSide;
281
+ /**
282
+ * Get connection point on a node
283
+ */
284
+ declare function getConnectionPoint(node: PathNode, targetNode: PathNode, forcedAnchor: ConnectionSide | undefined, cornerPadding: number, slot?: AnchorSlot, anchorSpacing?: number): ConnectionPoint;
285
+ /**
286
+ * Get point on a specific side of a node
287
+ * Uses even distribution when multiple slots are on the same side
288
+ */
289
+ declare function getPointOnSide(node: PathNode, side: ConnectionSide, cornerPadding: number, slot?: AnchorSlot, _anchorSpacing?: number): Point;
290
+ /**
291
+ * Get a padded point - sits at padding distance from node edge
292
+ * Uses even distribution when multiple slots are on the same side
293
+ */
294
+ declare function getPaddedPoint(node: PathNode, side: ConnectionSide, padding: number, cornerPadding: number, slot?: AnchorSlot): PaddedPoint;
295
+ /**
296
+ * Calculate actual slot positions on a node edge
297
+ * Uses even distribution across the available edge space
298
+ */
299
+ declare function calculateSlotPositions(node: PathNode, side: ConnectionSide, totalSlots: number, cornerPadding?: number): Array<{
300
+ x: number;
301
+ y: number;
302
+ }>;
303
+ /**
304
+ * Find optimal slot assignment to minimize crossings
305
+ * Returns an array where assignment[connIndex] = slotIndex
306
+ */
307
+ declare function findOptimalSlotAssignment(connections: Array<{
308
+ otherNodeX: number;
309
+ otherNodeY: number;
310
+ relationshipId: string;
311
+ isSource: boolean;
312
+ }>, slotPositions: Array<{
313
+ x: number;
314
+ y: number;
315
+ }>): number[];
316
+ /**
317
+ * Calculate anchor slot assignments based on actual path results
318
+ * This uses the sides that were actually chosen by the routing algorithm
319
+ */
320
+ declare function calculateAnchorSlotsFromPaths(paths: CalculatedPath[], nodeMap: Map<string, PathNode>): Map<string, AnchorSlot>;
321
+
322
+ /**
323
+ * Path Strategy Interface
324
+ *
325
+ * Base interface for path generation strategies.
326
+ * Each strategy implements a different path type (orthogonal, bezier, straight).
327
+ */
328
+
329
+ /**
330
+ * Result from a path strategy calculation
331
+ */
332
+ interface PathStrategyResult {
333
+ /** Connection point on source node */
334
+ sourcePoint: ConnectionPoint;
335
+ /** Connection point on target node */
336
+ targetPoint: ConnectionPoint;
337
+ /** Ordered list of waypoints forming the path */
338
+ waypoints: Waypoint[];
339
+ }
340
+ /**
341
+ * Context passed to path strategies
342
+ */
343
+ interface PathStrategyContext {
344
+ /** Source node */
345
+ source: PathNode;
346
+ /** Target node */
347
+ target: PathNode;
348
+ /** Relationship being routed */
349
+ relationship: PathRelationship;
350
+ /** All nodes (for obstacle detection) */
351
+ allNodes: PathNode[];
352
+ /** Path finding options */
353
+ options: Required<PathFindingOptions>;
354
+ /** Optional source anchor slot for spreading */
355
+ sourceSlot?: AnchorSlot;
356
+ /** Optional target anchor slot for spreading */
357
+ targetSlot?: AnchorSlot;
358
+ }
359
+ /**
360
+ * A candidate route with metadata for comparison
361
+ */
362
+ interface RouteCandidate {
363
+ waypoints: Waypoint[];
364
+ length: number;
365
+ sourceSide: ConnectionSide;
366
+ targetSide: ConnectionSide;
367
+ }
368
+ /**
369
+ * Interface for path generation strategies
370
+ */
371
+ interface PathStrategy {
372
+ /**
373
+ * Calculate a path between source and target nodes
374
+ */
375
+ calculatePath(context: PathStrategyContext): PathStrategyResult;
376
+ }
377
+
378
+ /**
379
+ * Orthogonal Path Strategy
380
+ *
381
+ * Generates paths with right-angle turns only (Manhattan-style routing).
382
+ * Supports obstacle avoidance with multiple routing strategies.
383
+ */
384
+
385
+ /**
386
+ * Orthogonal path strategy - routes paths with right-angle turns
387
+ */
388
+ declare class OrthogonalStrategy implements PathStrategy {
389
+ calculatePath(context: PathStrategyContext): PathStrategyResult;
390
+ /**
391
+ * Find the best orthogonal route using padded-edge approach
392
+ */
393
+ private findBestOrthogonalRoute;
394
+ /**
395
+ * Find route between padded points avoiding obstacles
396
+ */
397
+ private findPaddedRoute;
398
+ /**
399
+ * Try direct route (straight line between padded points)
400
+ */
401
+ private tryDirect;
402
+ /**
403
+ * Try L-shaped route (one bend)
404
+ */
405
+ private tryLShape;
406
+ /**
407
+ * Try Z-shaped route (two bends)
408
+ */
409
+ private tryZShape;
410
+ /**
411
+ * Try U-shaped route (goes around nodes)
412
+ */
413
+ private tryUShape;
414
+ /**
415
+ * Create fallback route when no valid route is found
416
+ */
417
+ private createFallbackRoute;
418
+ /**
419
+ * Extend route from padded points to actual node edges
420
+ */
421
+ private extendRouteToEdges;
422
+ /**
423
+ * Check if route is valid (doesn't pass through obstacles)
424
+ */
425
+ private isRouteValid;
426
+ }
427
+
428
+ /**
429
+ * Bezier Path Strategy
430
+ *
431
+ * Generates smooth curved paths using cubic bezier curves.
432
+ * Control points are positioned based on connection sides.
433
+ */
434
+
435
+ /**
436
+ * Bezier path strategy - creates smooth curved paths
437
+ */
438
+ declare class BezierStrategy implements PathStrategy {
439
+ calculatePath(context: PathStrategyContext): PathStrategyResult;
440
+ /**
441
+ * Calculate bezier path with control points
442
+ */
443
+ private calculateBezierPath;
444
+ /**
445
+ * Get control point position based on connection side
446
+ */
447
+ private getControlPointForBezier;
448
+ }
449
+
450
+ /**
451
+ * Straight Path Strategy
452
+ *
453
+ * Generates direct line paths between nodes.
454
+ * Simple and fast, but may overlap obstacles.
455
+ */
456
+
457
+ /**
458
+ * Straight path strategy - creates direct line paths
459
+ */
460
+ declare class StraightStrategy implements PathStrategy {
461
+ calculatePath(context: PathStrategyContext): PathStrategyResult;
462
+ }
463
+
464
+ export { BezierStrategy, DEFAULT_PATH_FINDING_OPTIONS, OrthogonalStrategy, PathFindingService, StraightStrategy, calculateAnchorSlotsFromPaths, calculateMidpoint, calculatePathLength, calculateRouteLength, calculateSlotPositions, clamp, createPaddedRect, createRect, expandRect, findOptimalSlotAssignment, getConnectionPoint, getPaddedPoint, getPointOnSide, getPreferredSide, linePassesThroughRect, simplifyPath };
465
+ export type { AnchorSlot, CalculatedPath, ConnectionPoint, ConnectionSide, PaddedPoint, PathFindingInput, PathFindingOptions, PathFindingResult, PathNode, PathRelationship, PathStrategy, PathStrategyContext, PathStrategyResult, PathType, Point, Rect, Rectangle, RouteCandidate, Waypoint };