@antv/x6
Version:
JavaScript diagramming library that uses SVG and HTML for rendering
114 lines (97 loc) • 3.07 kB
text/typescript
import type { EdgeView } from '../../view'
import type { AttrDefinition, AttrSetFunction, QualifyFunction } from './index'
const isEdgeView: QualifyFunction = (val, { view }) => {
return view.cell.isEdge()
}
export const connection: AttrDefinition = {
qualify: isEdgeView,
set(val, args) {
const view = args.view as EdgeView
const reverse = ((val as any).reverse || false) as boolean
const stubs = ((val as any).stubs || 0) as number
let d
if (Number.isFinite(stubs) && stubs !== 0) {
if (!reverse) {
let offset
if (stubs < 0) {
const len = view.getConnectionLength() || 0
offset = (len + stubs) / 2
} else {
offset = stubs
}
const path = view.getConnection()
if (path) {
const sourceParts = path.divideAtLength(offset)
const targetParts = path.divideAtLength(-offset)
if (sourceParts && targetParts) {
d = `${sourceParts[0].serialize()} ${targetParts[1].serialize()}`
}
}
} else {
let offset
let length
const len = view.getConnectionLength() || 0
if (stubs < 0) {
offset = (len + stubs) / 2
length = -stubs
} else {
offset = stubs
length = len - stubs * 2
}
const path = view.getConnection()
d = path
?.divideAtLength(offset)?.[1]
?.divideAtLength(length)?.[0]
?.serialize()
}
}
return { d: d || view.getConnectionPathData() }
},
}
export const atConnectionLengthKeepGradient: AttrDefinition = {
qualify: isEdgeView,
set: atConnectionWrapper('getTangentAtLength', { rotate: true }),
}
export const atConnectionLengthIgnoreGradient: AttrDefinition = {
qualify: isEdgeView,
set: atConnectionWrapper('getTangentAtLength', { rotate: false }),
}
export const atConnectionRatioKeepGradient: AttrDefinition = {
qualify: isEdgeView,
set: atConnectionWrapper('getTangentAtRatio', { rotate: true }),
}
export const atConnectionRatioIgnoreGradient: AttrDefinition = {
qualify: isEdgeView,
set: atConnectionWrapper('getTangentAtRatio', { rotate: false }),
}
// aliases
// -------
export const atConnectionLength = atConnectionLengthKeepGradient
export const atConnectionRatio = atConnectionRatioKeepGradient
// utils
// -----
function atConnectionWrapper(
method: 'getTangentAtLength' | 'getTangentAtRatio',
options: { rotate: boolean },
): AttrSetFunction {
const zeroVector = { x: 1, y: 0 }
return (value, args) => {
let p
let angle
const view = args.view as EdgeView
const tangent = view[method](Number(value))
if (tangent) {
angle = options.rotate ? tangent.vector().vectorAngle(zeroVector) : 0
p = tangent.start
} else {
p = (view as any).path.start
angle = 0
}
if (angle === 0 || Number.isNaN(angle)) {
return { transform: `translate(${p.x},${p.y})` }
}
return {
transform: `translate(${p.x},${p.y}) rotate(${angle})`,
}
}
}