refactor(core): cleanup connection line component (#1470)

This commit is contained in:
Braks
2024-06-13 00:04:51 +02:00
parent d658c1d357
commit d429394f42
@@ -1,6 +1,5 @@
import type { DefineComponent } from 'vue' import { computed, defineComponent, h, inject } from 'vue'
import { defineComponent, h, inject } from 'vue' import type { HandleElement } from '../../types'
import type { ConnectionLineProps } from '../../types'
import { ConnectionLineType, ConnectionMode, Position } from '../../types' import { ConnectionLineType, ConnectionMode, Position } from '../../types'
import { getHandlePosition, getMarkerId } from '../../utils' import { getHandlePosition, getMarkerId } from '../../utils'
import { useVueFlow } from '../../composables' import { useVueFlow } from '../../composables'
@@ -32,16 +31,29 @@ const ConnectionLine = defineComponent({
findNode, findNode,
} = useVueFlow() } = useVueFlow()
const connectionLineComponent = inject(Slots)?.['connection-line'] as DefineComponent<ConnectionLineProps> | undefined const connectionLineComponent = inject(Slots)?.['connection-line']
const fromNode = computed(() => findNode(connectionStartHandle.value?.nodeId))
const toNode = computed(() => findNode(connectionEndHandle.value?.nodeId) ?? null)
const toXY = computed(() => {
return {
x: (connectionPosition.value.x - viewport.value.x) / viewport.value.zoom,
y: (connectionPosition.value.y - viewport.value.y) / viewport.value.zoom,
}
})
const markerStart = computed(() =>
connectionLineOptions.value.markerStart ? `url(#${getMarkerId(connectionLineOptions.value.markerStart, id)})` : '',
)
const markerEnd = computed(() =>
connectionLineOptions.value.markerEnd ? `url(#${getMarkerId(connectionLineOptions.value.markerEnd, id)})` : '',
)
return () => { return () => {
if (!connectionStartHandle.value) { if (!fromNode.value || !connectionStartHandle.value) {
return null
}
const fromNode = findNode(connectionStartHandle.value.nodeId)
if (!fromNode) {
return null return null
} }
@@ -49,12 +61,7 @@ const ConnectionLine = defineComponent({
const handleType = connectionStartHandle.value.type const handleType = connectionStartHandle.value.type
const targetNode = (connectionEndHandle.value && findNode(connectionEndHandle.value.nodeId)) || null const fromHandleBounds = fromNode.value.handleBounds
const toX = (connectionPosition.value.x - viewport.value.x) / viewport.value.zoom
const toY = (connectionPosition.value.y - viewport.value.y) / viewport.value.zoom
const fromHandleBounds = fromNode.handleBounds
let handleBounds = fromHandleBounds?.[handleType] let handleBounds = fromHandleBounds?.[handleType]
if (connectionMode.value === ConnectionMode.Loose) { if (connectionMode.value === ConnectionMode.Loose) {
@@ -69,24 +76,28 @@ const ConnectionLine = defineComponent({
const fromPosition = fromHandle?.position || Position.Top const fromPosition = fromHandle?.position || Position.Top
const { x: fromX, y: fromY } = getHandlePosition( const { x: fromX, y: fromY } = getHandlePosition(
fromPosition, fromPosition,
{ ...fromNode.dimensions, ...fromNode.computedPosition }, { ...fromNode.value.dimensions, ...fromNode.value.computedPosition },
fromHandle, fromHandle,
) )
// todo: this is a bit of a mess, we should refactor this let toHandle: HandleElement | null = null
const toHandle = if (toNode.value && connectionEndHandle.value?.handleId) {
(targetNode && // if connection mode is strict, we only look for handles of the opposite type
connectionEndHandle.value?.handleId && if (connectionMode.value === ConnectionMode.Strict) {
((connectionMode.value === ConnectionMode.Strict toHandle =
? targetNode.handleBounds[handleType === 'source' ? 'target' : 'source']?.find( toNode.value.handleBounds[handleType === 'source' ? 'target' : 'source']?.find(
(d) => d.id === connectionEndHandle.value?.handleId, (d) => d.id === connectionEndHandle.value?.handleId,
) ) || null
: [...(targetNode.handleBounds.source || []), ...(targetNode.handleBounds.target || [])]?.find( } else {
(d) => d.id === connectionEndHandle.value?.handleId, // if connection mode is loose, look for the handle in both source and target bounds
)) || toHandle =
targetNode.handleBounds[handleType ?? 'target']?.[0])) || [...(toNode.value.handleBounds.source || []), ...(toNode.value.handleBounds.target || [])]?.find(
null (d) => d.id === connectionEndHandle.value?.handleId,
) || null
}
}
// we assume the target position is opposite to the source position
const toPosition = fromPosition ? oppositePosition[fromPosition] : null const toPosition = fromPosition ? oppositePosition[fromPosition] : null
if (!fromPosition || !toPosition) { if (!fromPosition || !toPosition) {
@@ -101,13 +112,12 @@ const ConnectionLine = defineComponent({
sourceX: fromX, sourceX: fromX,
sourceY: fromY, sourceY: fromY,
sourcePosition: fromPosition, sourcePosition: fromPosition,
targetX: toX, targetX: toXY.value.x,
targetY: toY, targetY: toXY.value.y,
targetPosition: toPosition, targetPosition: toPosition,
} }
if (type === ConnectionLineType.Bezier) { if (type === ConnectionLineType.Bezier) {
// we assume the destination position is opposite to the source position
;[dAttr] = getBezierPath(pathParams) ;[dAttr] = getBezierPath(pathParams)
} else if (type === ConnectionLineType.Step) { } else if (type === ConnectionLineType.Step) {
;[dAttr] = getSmoothStepPath({ ;[dAttr] = getSmoothStepPath({
@@ -119,7 +129,7 @@ const ConnectionLine = defineComponent({
} else if (type === ConnectionLineType.SimpleBezier) { } else if (type === ConnectionLineType.SimpleBezier) {
;[dAttr] = getSimpleBezierPath(pathParams) ;[dAttr] = getSimpleBezierPath(pathParams)
} else { } else {
dAttr = `M${fromX},${fromY} ${toX},${toY}` dAttr = `M${fromX},${fromY} ${toXY.value.x},${toXY.value.y}`
} }
return h( return h(
@@ -133,15 +143,15 @@ const ConnectionLine = defineComponent({
sourceX: fromX, sourceX: fromX,
sourceY: fromY, sourceY: fromY,
sourcePosition: fromPosition, sourcePosition: fromPosition,
targetX: toX, targetX: toXY.value.x,
targetY: toY, targetY: toXY.value.y,
targetPosition: toPosition, targetPosition: toPosition,
sourceNode: fromNode, sourceNode: fromNode.value,
sourceHandle: fromHandle, sourceHandle: fromHandle,
targetNode, targetNode: toNode.value,
targetHandle: toHandle, targetHandle: toHandle,
markerEnd: `url(#${getMarkerId(connectionLineOptions.value.markerEnd, id)})`, markerEnd: markerEnd.value,
markerStart: `url(#${getMarkerId(connectionLineOptions.value.markerStart, id)})`, markerStart: markerStart.value,
connectionStatus: connectionStatus.value, connectionStatus: connectionStatus.value,
}) })
: h('path', { : h('path', {
@@ -151,8 +161,8 @@ const ConnectionLine = defineComponent({
...connectionLineStyle.value, ...connectionLineStyle.value,
...connectionLineOptions.value.style, ...connectionLineOptions.value.style,
}, },
'marker-end': `url(#${getMarkerId(connectionLineOptions.value.markerEnd, id)})`, 'marker-end': markerEnd.value,
'marker-start': `url(#${getMarkerId(connectionLineOptions.value.markerStart, id)})`, 'marker-start': markerStart.value,
}), }),
), ),
) )