UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

73 lines (61 loc) 1.89 kB
import { Ellipse, type Rectangle } from '../../geometry' import type { PortLayoutCommonArgs, PortLayoutDefinition } from './index' import { toResult } from './util' export interface EllipseArgs extends PortLayoutCommonArgs { start?: number step?: number compensateRotate?: boolean /** * delta radius */ dr?: number } export const ellipse: PortLayoutDefinition<EllipseArgs> = ( portsPositionArgs, elemBBox, groupPositionArgs, ) => { const startAngle = groupPositionArgs.start || 0 const stepAngle = groupPositionArgs.step || 20 return ellipseLayout( portsPositionArgs, elemBBox, startAngle, (index, count) => (index + 0.5 - count / 2) * stepAngle, ) } export const ellipseSpread: PortLayoutDefinition<EllipseArgs> = ( portsPositionArgs, elemBBox, groupPositionArgs, ) => { const startAngle = groupPositionArgs.start || 0 const stepAngle = groupPositionArgs.step || 360 / portsPositionArgs.length return ellipseLayout(portsPositionArgs, elemBBox, startAngle, (index) => { return index * stepAngle }) } function ellipseLayout( portsPositionArgs: EllipseArgs[], elemBBox: Rectangle, startAngle: number, stepFn: (index: number, count: number) => number, ) { const center = elemBBox.getCenter() const start = elemBBox.getTopCenter() const ratio = elemBBox.width / elemBBox.height const ellipse = Ellipse.fromRect(elemBBox) const count = portsPositionArgs.length return portsPositionArgs.map((item, index) => { const angle = startAngle + stepFn(index, count) const p = start.clone().rotate(-angle, center).scale(ratio, 1, center) const theta = item.compensateRotate ? -ellipse.tangentTheta(p) : 0 if (item.dx || item.dy) { p.translate(item.dx || 0, item.dy || 0) } if (item.dr) { p.move(center, item.dr) } return toResult(p.round(), theta, item) }) }