UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

92 lines (78 loc) 2.08 kB
import { Point, type PointLike } from '../../geometry' import type { Edge, Node, TerminalCellData } from '../../model' import type { EdgeView, NodeView } from '../../view' import type { ConnectionStrategyDefinition } from './index' export function toPercentage(value: number, max: number) { if (max === 0) { return '0%' } return `${Math.round((value / max) * 100)}%` } export function pin(relative: boolean) { const strategy = (terminal, view, magnet, coords) => { return view.isEdgeElement(magnet) ? pinEdgeTerminal(relative, terminal, view as EdgeView, magnet, coords) : pinNodeTerminal(relative, terminal, view as NodeView, magnet, coords) } return strategy } export function pinNodeTerminal( relative: boolean, data: TerminalCellData, view: NodeView, magnet: Element, coords: PointLike, ) { const node = view.cell as Node const angle = node.getAngle() const bbox = view.getUnrotatedBBoxOfElement(magnet as SVGElement) const center = node.getBBox().getCenter() const pos = Point.create(coords).rotate(angle, center) let dx: number | string = pos.x - bbox.x let dy: number | string = pos.y - bbox.y if (relative) { dx = toPercentage(dx, bbox.width) dy = toPercentage(dy, bbox.height) } data.anchor = { name: 'topLeft', args: { dx, dy, rotate: true, }, } return data } export function pinEdgeTerminal( relative: boolean, end: TerminalCellData, view: EdgeView, magnet: Element, coords: PointLike, ) { const connection = view.getConnection() if (!connection) { return end } const length = connection.closestPointLength(coords) if (relative) { const totalLength = connection.length() end.anchor = { name: 'ratio', args: { ratio: length / totalLength, }, } } else { end.anchor = { name: 'length', args: { length, }, } } return end } export const pinRelative: ConnectionStrategyDefinition = pin(true) export const pinAbsolute: ConnectionStrategyDefinition = pin(false)