Skip to Content
ExamplesEdges

Simple Floating Edges

This is a simplified version of the Floating Edges example. It’s not as flexible as the floating edges example, but the edges stick to the top, right, bottom or left side of the nodes. You can find the implementation details in the utils.js file.

import type { InternalNode } from '@xyflow/vue'; import { Position } from '@xyflow/vue'; function getNodeCenter(node: InternalNode) { return { x: node.internals.positionAbsolute.x + (node.measured.width ?? 0) / 2, y: node.internals.positionAbsolute.y + (node.measured.height ?? 0) / 2, }; } function getHandleCoordsByPosition(node: InternalNode, handlePosition: Position): [number, number] { // all handles are type source, so we look them up in handleBounds.source const handle = node.internals.handleBounds?.source?.find((h) => h.position === handlePosition); if (!handle) { return [0, 0]; } let offsetX = (handle.width ?? 0) / 2; let offsetY = (handle.height ?? 0) / 2; // the calculated handle position has its origin top-left, so shift by the handle size on the far sides // to keep the edge's markerEnd visible switch (handlePosition) { case Position.Left: offsetX = 0; break; case Position.Right: offsetX = handle.width ?? 0; break; case Position.Top: offsetY = 0; break; case Position.Bottom: offsetY = handle.height ?? 0; break; } const x = node.internals.positionAbsolute.x + handle.x + offsetX; const y = node.internals.positionAbsolute.y + handle.y + offsetY; return [x, y]; } function getParams(nodeA: InternalNode, nodeB: InternalNode): [number, number, Position] { const centerA = getNodeCenter(nodeA); const centerB = getNodeCenter(nodeB); const horizontalDiff = Math.abs(centerA.x - centerB.x); const verticalDiff = Math.abs(centerA.y - centerB.y); let position: Position; // pick the handle side based on the bigger center-to-center difference if (horizontalDiff > verticalDiff) { position = centerA.x > centerB.x ? Position.Left : Position.Right; } else { position = centerA.y > centerB.y ? Position.Top : Position.Bottom; } const [x, y] = getHandleCoordsByPosition(nodeA, position); return [x, y, position]; } // returns the params (sx, sy, tx, ty, sourcePos, targetPos) needed to draw a simple floating edge export function getEdgeParams(source: InternalNode, target: InternalNode) { const [sx, sy, sourcePos] = getParams(source, target); const [tx, ty, targetPos] = getParams(target, source); return { sx, sy, tx, ty, sourcePos, targetPos }; }
Last updated on