diff --git a/ui/src/components/features/PlatformTopology.tsx b/ui/src/components/features/PlatformTopology.tsx index 5e8c032..7d7f762 100644 --- a/ui/src/components/features/PlatformTopology.tsx +++ b/ui/src/components/features/PlatformTopology.tsx @@ -168,12 +168,26 @@ function nodeCoords(col: number, row: number, rows: number) { } } -/** Curved path — arcs upward for backward (orchestration) flows */ -function flowPath(x1: number, y1: number, x2: number, y2: number, backward = false) { +/** Curved path — route edges to avoid dangling stubs over intermediate nodes */ +function flowPath( + x1: number, y1: number, x2: number, y2: number, + opts: { backward?: boolean; sameCol?: boolean } = {}, +) { + const { backward = false, sameCol = false } = opts if (backward || x2 < x1 - 2) { const arcY = Math.min(y1, y2) - 14 return `M ${x1} ${y1} C ${x1} ${arcY}, ${x2} ${arcY}, ${x2} ${y2}` } + if (sameCol) { + const cx = (x1 + x2) / 2 + return `M ${x1} ${y1} C ${cx} ${y1}, ${cx} ${y2}, ${x2} ${y2}` + } + const span = x2 - x1 + const dy = Math.abs(y2 - y1) + if (span > 16 && dy > 4) { + const dipY = Math.max(y1, y2) + Math.min(12, 6 + span * 0.08) + return `M ${x1} ${y1} C ${x1 + span * 0.2} ${dipY}, ${x2 - span * 0.2} ${dipY}, ${x2} ${y2}` + } const mx = (x1 + x2) / 2 return `M ${x1} ${y1} C ${mx} ${y1}, ${mx} ${y2}, ${x2} ${y2}` } @@ -339,7 +353,7 @@ export function PlatformTopology({ workload, animations, selectedNodeId, onNodeC const backward = edge.kind === 'orchestration' && pb.col < pa.col const fromX = backward ? a.inX + (a.outX - a.inX) * 0.15 : a.outX const toX = backward ? b.outX - (b.outX - b.inX) * 0.15 : b.inX - const d = flowPath(fromX, a.y, toX, b.y, backward) + const d = flowPath(fromX, a.y, toX, b.y, { backward, sameCol: pa.col === pb.col }) const live = edgesLive const dur = 1.8 + (i % 5) * 0.35 return (