regression(nodes,edges): use computed to get current node/edge

This commit is contained in:
Braks
2022-04-04 21:42:48 +02:00
parent 202773144f
commit a5a918a39b
2 changed files with 68 additions and 65 deletions
+34 -34
View File
@@ -12,35 +12,35 @@ interface EdgeWrapper {
const props = defineProps<EdgeWrapper>()
const { store } = useVueFlow()
const edge = store.getEdge(props.id)
if (!edge) throw new Error(`Edge with ${props.id} not found!`)
const edge = computed(() => store.getEdge(props.id)!)
if (!edge.value) throw new Error(`Edge with ${props.id} not found!`)
const updating = ref(false)
const { onMouseDown } = useHandle()
const { onMouseDown } = useHandle()
const onEdgeClick = (event: MouseEvent) => {
const data = { event, edge }
const data = { event, edge: edge.value }
if (props.selectable) {
store.nodesSelectionActive = false
store.addSelectedEdges([edge])
store.addSelectedEdges([edge.value])
}
store.hooks.edgeClick.trigger(data)
}
const onEdgeContextMenu = (event: MouseEvent) => store.hooks.edgeContextMenu.trigger({ event, edge })
const onDoubleClick = (event: MouseEvent) => store.hooks.edgeDoubleClick.trigger({ event, edge })
const onEdgeMouseEnter = (event: MouseEvent) => store.hooks.edgeMouseEnter.trigger({ event, edge })
const onEdgeMouseMove = (event: MouseEvent) => store.hooks.edgeMouseMove.trigger({ event, edge })
const onEdgeMouseLeave = (event: MouseEvent) => store.hooks.edgeMouseLeave.trigger({ event, edge })
const onEdgeContextMenu = (event: MouseEvent) => store.hooks.edgeContextMenu.trigger({ event, edge: edge.value })
const onDoubleClick = (event: MouseEvent) => store.hooks.edgeDoubleClick.trigger({ event, edge: edge.value })
const onEdgeMouseEnter = (event: MouseEvent) => store.hooks.edgeMouseEnter.trigger({ event, edge: edge.value })
const onEdgeMouseMove = (event: MouseEvent) => store.hooks.edgeMouseMove.trigger({ event, edge: edge.value })
const onEdgeMouseLeave = (event: MouseEvent) => store.hooks.edgeMouseLeave.trigger({ event, edge: edge.value })
const onEdgeUpdaterMouseEnter = () => (updating.value = true)
const onEdgeUpdaterMouseOut = () => (updating.value = false)
const onEdgeUpdaterSourceMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, true)
const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, false)
const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
const nodeId = isSourceHandle ? edge.target : edge.source
const handleId = (isSourceHandle ? edge.targetHandle : edge.sourceHandle) ?? ''
const nodeId = isSourceHandle ? edge.value.target : edge.value.source
const handleId = (isSourceHandle ? edge.value.targetHandle : edge.value.sourceHandle) ?? ''
store.hooks.edgeUpdateStart.trigger({ event, edge })
store.hooks.edgeUpdateStart.trigger({ event, edge: edge.value })
onMouseDown(
event,
handleId,
@@ -48,22 +48,22 @@ const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
isSourceHandle,
undefined,
isSourceHandle ? 'target' : 'source',
(connection) => store.hooks.edgeUpdate.trigger({ edge, connection }),
() => store.hooks.edgeUpdateEnd.trigger({ event, edge }),
(connection) => store.hooks.edgeUpdate.trigger({ edge: edge.value, connection }),
() => store.hooks.edgeUpdateEnd.trigger({ event, edge: edge.value }),
)
}
// when connection type is loose we can define all handles as sources
const targetNodeHandles = computed(() =>
store.connectionMode === ConnectionMode.Strict
? edge.targetNode.handleBounds.target
: edge.targetNode.handleBounds.target ?? edge.targetNode.handleBounds.source,
? edge.value.targetNode.handleBounds.target
: edge.value.targetNode.handleBounds.target ?? edge.value.targetNode.handleBounds.source,
)
const sourceHandle = controlledComputed(
() => edge.sourceNode.handleBounds,
() => getHandle(edge.sourceNode.handleBounds.source, edge.sourceHandle),
() => edge.value.sourceNode.handleBounds,
() => getHandle(edge.value.sourceNode.handleBounds.source, edge.value.sourceHandle),
)
const targetHandle = computed(() => getHandle(targetNodeHandles.value, edge.targetHandle))
const targetHandle = computed(() => getHandle(targetNodeHandles.value, edge.value.targetHandle))
const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom))
const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top))
const edgeUpdaterRadius = computed(() => store.edgeUpdaterRadius)
@@ -73,32 +73,32 @@ onMounted(() => {
[
sourcePosition,
targetPosition,
() => edge.sourceNode.position,
() => edge.targetNode.position,
() => edge.sourceNode.computedPosition,
() => edge.targetNode.computedPosition,
() => edge.sourceNode.dimensions,
() => edge.targetNode.dimensions,
() => edge.value.sourceNode.position,
() => edge.value.targetNode.position,
() => edge.value.sourceNode.computedPosition,
() => edge.value.targetNode.computedPosition,
() => edge.value.sourceNode.dimensions,
() => edge.value.targetNode.dimensions,
],
() => {
const { sourceX, sourceY, targetY, targetX } = getEdgePositions(
edge.sourceNode,
edge.value.sourceNode,
sourceHandle.value,
sourcePosition.value,
edge.targetNode,
edge.value.targetNode,
targetHandle.value,
targetPosition.value,
)
if (edge.sourceX !== sourceX) edge.sourceX = sourceX
if (edge.sourceY !== sourceY) edge.sourceY = sourceY
if (edge.targetX !== targetX) edge.targetX = targetX
if (edge.targetY !== targetY) edge.targetY = targetY
if (edge.value.sourceX !== sourceX) edge.value.sourceX = sourceX
if (edge.value.sourceY !== sourceY) edge.value.sourceY = sourceY
if (edge.value.targetX !== targetX) edge.value.targetX = targetX
if (edge.value.targetY !== targetY) edge.value.targetY = targetY
},
{ immediate: true, deep: true },
)
})
const name = ref(edge.type ?? 'default')
const name = ref(edge.value.type ?? 'default')
const type = computed(() => {
let edgeType = store.getEdgeTypes[name.value]
if (typeof edgeType === 'string') edgeType = resolveComponent(name.value, false) as EdgeComponent
@@ -106,7 +106,7 @@ const type = computed(() => {
const slot = useSlots()?.[name.value]?.({})
if (!slot || !slot[0].key?.toString().includes(name.value)) {
console.warn(`Node type "${edge.type}" not found and no slot detected. Using fallback type "default".`)
console.warn(`Node type "${edge.value.type}" not found and no slot detected. Using fallback type "default".`)
name.value = 'default'
return store.getEdgeTypes.default
}
+34 -31
View File
@@ -15,71 +15,74 @@ interface NodeWrapperProps {
const props = defineProps<NodeWrapperProps>()
const { store } = useVueFlow()
const node = store.getNode(props.id)
if (!node) throw new Error(`Node with ${props.id} not found!`)
const node = computed(() => store.getNode(props.id)!)
if (!node.value) throw new Error(`Node with ${props.id} not found!`)
provide(NodeId, props.id)
const nodeElement = templateRef<HTMLDivElement>('node-element', null)
const onMouseEnterHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseEnter.trigger({ event, node }))
const onMouseMoveHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseMove.trigger({ event, node }))
const onMouseLeaveHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseLeave.trigger({ event, node }))
const onMouseEnterHandler = () =>
node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseEnter.trigger({ event, node: node.value }))
const onMouseMoveHandler = () =>
node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseMove.trigger({ event, node: node.value }))
const onMouseLeaveHandler = () =>
node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseLeave.trigger({ event, node: node.value }))
const onContextMenuHandler = () => (event: MouseEvent) =>
store.hooks.nodeContextMenu.trigger({
event,
node,
node: node.value,
})
const onDoubleClick = () => (event: MouseEvent) => store.hooks.nodeDoubleClick.trigger({ event, node })
const onDoubleClick = () => (event: MouseEvent) => store.hooks.nodeDoubleClick.trigger({ event, node: node.value })
const onSelectNodeHandler = (event: MouseEvent) => {
if (!props.draggable) {
if (props.selectable) {
store.nodesSelectionActive = false
if (!node.selected) store.addSelectedNodes([node])
if (!node.value.selected) store.addSelectedNodes([node.value])
}
store.hooks.nodeClick.trigger({ event, node })
store.hooks.nodeClick.trigger({ event, node: node.value })
}
}
const onDragStart: DraggableEventListener = ({ event }) => {
store.addSelectedNodes([])
store.hooks.nodeDragStart.trigger({ event, node })
store.hooks.nodeDragStart.trigger({ event, node: node.value })
if (store.selectNodesOnDrag && props.selectable) {
store.nodesSelectionActive = false
if (!node.selected) store.addSelectedNodes([node])
} else if (!store.selectNodesOnDrag && !node.selected && props.selectable) {
if (!node.value.selected) store.addSelectedNodes([node.value])
} else if (!store.selectNodesOnDrag && !node.value.selected && props.selectable) {
store.nodesSelectionActive = false
store.addSelectedNodes([])
}
}
const onDrag: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => {
nextTick(() => store.updateNodePosition({ id: node.id, diff: { x: deltaX, y: deltaY }, dragging: true }))
store.hooks.nodeDrag.trigger({ event, node })
nextTick(() => store.updateNodePosition({ id: node.value.id, diff: { x: deltaX, y: deltaY }, dragging: true }))
store.hooks.nodeDrag.trigger({ event, node: node.value })
}
const onDragStop: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => {
// onDragStop also gets called when user just clicks on a node.
// Because of that we set dragging to true inside the onDrag handler and handle the click here
if (!node.dragging) {
if (props.selectable && !store.selectNodesOnDrag && !node.selected) {
store.addSelectedNodes([node])
if (!node.value.dragging) {
if (props.selectable && !store.selectNodesOnDrag && !node.value.selected) {
store.addSelectedNodes([node.value])
}
store.hooks.nodeClick.trigger({ event, node })
store.hooks.nodeClick.trigger({ event, node: node.value })
return
}
store.updateNodePosition({ id: node.id, diff: { x: deltaX, y: deltaY }, dragging: false })
store.hooks.nodeDragStop.trigger({ event, node })
store.updateNodePosition({ id: node.value.id, diff: { x: deltaX, y: deltaY }, dragging: false })
store.hooks.nodeDragStop.trigger({ event, node: node.value })
}
onMounted(() => {
useResizeObserver(nodeElement, () =>
store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value, forceUpdate: true }]),
store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value, forceUpdate: true }]),
)
watch([() => node.type, () => node.sourcePosition, () => node.targetPosition], () =>
nextTick(() => store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value }])),
watch([() => node.value.type, () => node.value.sourcePosition, () => node.value.targetPosition], () =>
nextTick(() => store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value }])),
)
store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value }])
store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value }])
})
const scale = controlledComputed(
@@ -88,24 +91,24 @@ const scale = controlledComputed(
)
watch(
[() => node.position, () => store.getNode(node.parentNode!)],
[() => node.value.position, () => store.getNode(node.value.parentNode!)],
([pos, parent]) => {
const xyzPos = {
...pos,
z: node.dragging || node.selected ? 1000 : node.computedPosition.z,
z: node.value.dragging || node.value.selected ? 1000 : node.value.computedPosition.z,
}
if (parent) {
node.computedPosition = getXYZPos(parent, xyzPos)
node.value.computedPosition = getXYZPos(parent, xyzPos)
} else {
node.computedPosition = xyzPos
node.value.computedPosition = xyzPos
}
},
{ deep: true },
)
store.updateNodePosition({ id: node.id, diff: { x: 0, y: 0 } })
store.updateNodePosition({ id: node.value.id, diff: { x: 0, y: 0 } })
const name = ref(node.type ?? 'default')
const name = ref(node.value.type ?? 'default')
const type = computed(() => {
let nodeType = store.getNodeTypes[name.value]
if (typeof nodeType === 'string') nodeType = resolveComponent(name.value, false) as NodeComponent
@@ -113,7 +116,7 @@ const type = computed(() => {
const slot = useSlots()?.[name.value]?.({})
if (!slot || !slot[0].key?.toString().includes(name.value)) {
console.warn(`Node type "${node.type}" not found and no slot detected. Using fallback type "default".`)
console.warn(`Node type "${node.value.type}" not found and no slot detected. Using fallback type "default".`)
name.value = 'default'
return store.getNodeTypes.default
}