UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

143 lines (125 loc) 4.08 kB
import type { RouterDefinition } from './index' export interface ErRouterOptions { min?: number offset?: number | 'center' direction?: 'T' | 'B' | 'L' | 'R' | 'H' | 'V' } export const er: RouterDefinition<ErRouterOptions> = ( vertices, options, edgeView, ) => { const offsetRaw = options.offset || 32 const min = options.min == null ? 16 : options.min let offset = 0 let direction = options.direction const sourceBBox = edgeView.sourceBBox const targetBBox = edgeView.targetBBox const sourcePoint = sourceBBox.getCenter() const targetPoint = targetBBox.getCenter() if (typeof offsetRaw === 'number') { offset = offsetRaw } if (direction == null) { let dx = targetBBox.left - sourceBBox.right let dy = targetBBox.top - sourceBBox.bottom if (dx >= 0 && dy >= 0) { direction = dx >= dy ? 'L' : 'T' } else if (dx <= 0 && dy >= 0) { dx = sourceBBox.left - targetBBox.right if (dx >= 0) { direction = dx >= dy ? 'R' : 'T' } else { direction = 'T' } } else if (dx >= 0 && dy <= 0) { dy = sourceBBox.top - targetBBox.bottom if (dy >= 0) { direction = dx >= dy ? 'L' : 'B' } else { direction = 'L' } } else { dx = sourceBBox.left - targetBBox.right dy = sourceBBox.top - targetBBox.bottom if (dx >= 0 && dy >= 0) { direction = dx >= dy ? 'R' : 'B' } else if (dx <= 0 && dy >= 0) { direction = 'B' } else if (dx >= 0 && dy <= 0) { direction = 'R' } else { direction = Math.abs(dx) > Math.abs(dy) ? 'R' : 'B' } } } if (direction === 'H') { direction = targetPoint.x - sourcePoint.x >= 0 ? 'L' : 'R' } else if (direction === 'V') { direction = targetPoint.y - sourcePoint.y >= 0 ? 'T' : 'B' } if (offsetRaw === 'center') { if (direction === 'L') { offset = (targetBBox.left - sourceBBox.right) / 2 } else if (direction === 'R') { offset = (sourceBBox.left - targetBBox.right) / 2 } else if (direction === 'T') { offset = (targetBBox.top - sourceBBox.bottom) / 2 } else if (direction === 'B') { offset = (sourceBBox.top - targetBBox.bottom) / 2 } } let coord: 'x' | 'y' let dim: 'width' | 'height' let factor const horizontal = direction === 'L' || direction === 'R' if (horizontal) { if (targetPoint.y === sourcePoint.y) { return [...vertices] } factor = direction === 'L' ? 1 : -1 coord = 'x' dim = 'width' } else { if (targetPoint.x === sourcePoint.x) { return [...vertices] } factor = direction === 'T' ? 1 : -1 coord = 'y' dim = 'height' } const source = sourcePoint.clone() const target = targetPoint.clone() source[coord] += factor * (sourceBBox[dim] / 2 + offset) target[coord] -= factor * (targetBBox[dim] / 2 + offset) if (horizontal) { const sourceX = source.x const targetX = target.x const sourceDelta = sourceBBox.width / 2 + min const targetDelta = targetBBox.width / 2 + min if (targetPoint.x > sourcePoint.x) { if (targetX <= sourceX) { source.x = Math.max(targetX, sourcePoint.x + sourceDelta) target.x = Math.min(sourceX, targetPoint.x - targetDelta) } } else if (targetX >= sourceX) { source.x = Math.min(targetX, sourcePoint.x - sourceDelta) target.x = Math.max(sourceX, targetPoint.x + targetDelta) } } else { const sourceY = source.y const targetY = target.y const sourceDelta = sourceBBox.height / 2 + min const targetDelta = targetBBox.height / 2 + min if (targetPoint.y > sourcePoint.y) { if (targetY <= sourceY) { source.y = Math.max(targetY, sourcePoint.y + sourceDelta) target.y = Math.min(sourceY, targetPoint.y - targetDelta) } } else if (targetY >= sourceY) { source.y = Math.min(targetY, sourcePoint.y - sourceDelta) target.y = Math.max(sourceY, targetPoint.y + targetDelta) } } return [source.toJSON(), ...vertices, target.toJSON()] }