From 17f2517ab4cdfc4399ab0d5ca574b8fc890bba4a Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Wed, 20 Oct 2021 09:23:00 +0200 Subject: [PATCH] fix: too many re-render on edges and nodes --- examples/EdgeTypes/EdgeTypesExample.vue | 4 +- src/components/Edges/Edge.vue | 84 ++++++--------------- src/components/Nodes/Node.vue | 42 ++++------- src/container/EdgeRenderer/EdgeRenderer.vue | 16 ++-- src/container/EdgeRenderer/utils.ts | 11 +-- src/container/Flow/Flow.vue | 2 - src/container/NodeRenderer/NodeRenderer.vue | 7 +- 7 files changed, 57 insertions(+), 109 deletions(-) diff --git a/examples/EdgeTypes/EdgeTypesExample.vue b/examples/EdgeTypes/EdgeTypesExample.vue index d08d50cf..24cdd844 100644 --- a/examples/EdgeTypes/EdgeTypesExample.vue +++ b/examples/EdgeTypes/EdgeTypesExample.vue @@ -17,14 +17,14 @@ const onConnect = (params: Connection | Edge) => (elements.value = addEdge(param diff --git a/src/components/Edges/Edge.vue b/src/components/Edges/Edge.vue index 5e7e61bc..35685c53 100644 --- a/src/components/Edges/Edge.vue +++ b/src/components/Edges/Edge.vue @@ -2,7 +2,7 @@ import EdgeAnchor from './EdgeAnchor.vue' import { getEdgePositions, getHandle, getSourceTargetNodes, isEdgeVisible } from '~/container/EdgeRenderer/utils' import { isEdge } from '~/utils/graph' -import { ConnectionMode, Dimensions, Edge, EdgeType, Elements, Position, Transform } from '~/types' +import { ConnectionMode, Dimensions, Edge, EdgeType, Position, Transform } from '~/types' import { onMouseDown } from '~/components/Handle/utils' import { Hooks, Store } from '~/context' @@ -12,18 +12,11 @@ interface EdgeProps { nodes: ReturnType dimensions: Dimensions transform: Transform - selectedElements?: Elements - elementsSelectable?: boolean - onlyRenderVisibleElements?: boolean - connectionMode?: ConnectionMode markerEndId?: string edgeUpdaterRadius?: number } -const props = withDefaults(defineProps(), { - elementsSelectable: true, - onlyRenderVisibleElements: false, -}) +const props = withDefaults(defineProps(), {}) const store = inject(Store)! const hooks = inject(Hooks)! @@ -32,72 +25,48 @@ hooks.connect.on((connection) => { hooks.edgeUpdate.trigger({ edge: props.edge, connection }) }) -if (!props.nodes.value.sourceNode) { +if (!props.nodes.sourceNode) { console.warn(`couldn't create edge for source id: ${props.edge.source}; edge id: ${props.edge.id}`) } -if (!props.nodes.value.targetNode) { +if (!props.nodes.targetNode) { console.warn(`couldn't create edge for target id: ${props.edge.target}; edge id: ${props.edge.id}`) } // when connection type is loose we can define all handles as sources const targetNodeHandles = - props.connectionMode === ConnectionMode.Strict - ? props.nodes.value.targetNode?.__rf.handleBounds.target - : props.nodes.value.targetNode?.__rf.handleBounds.target || props.nodes.value.targetNode?.__rf.handleBounds.source + store.connectionMode === ConnectionMode.Strict + ? props.nodes.targetNode?.__rf.handleBounds.target + : props.nodes.targetNode?.__rf.handleBounds.target || props.nodes.targetNode?.__rf.handleBounds.source const sourceHandle = - props.nodes.value.sourceNode && - getHandle(props.nodes.value.sourceNode.__rf.handleBounds.source, props.edge.sourceHandle || null) + props.nodes.sourceNode && getHandle(props.nodes.sourceNode.__rf.handleBounds.source, props.edge.sourceHandle || null) const targetHandle = getHandle(targetNodeHandles, props.edge.targetHandle || null) const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom const targetPosition = targetHandle ? targetHandle.position : Position.Top -const isSelected = computed(() => props.selectedElements?.some((elm) => isEdge(elm) && elm.id === props.edge.id) || false) - -const edgeElement = computed(() => { - const el: Edge = { - id: props.edge.id || '', - source: props.edge.source, - target: props.edge.target, - type: props.edge.type, - } - - if (props.edge.sourceHandle) { - el.sourceHandle = props.edge.sourceHandle - } - - if (props.edge.targetHandle) { - el.targetHandle = props.edge.targetHandle - } - - if (typeof props.edge.data !== 'undefined') { - el.data = props.edge.data - } - - return el -}) +const isSelected = store.selectedElements?.some((elm) => isEdge(elm) && elm.id === props.edge.id) || false const onEdgeClick = (event: MouseEvent) => { - if (props.elementsSelectable) { + if (store.elementsSelectable) { store.unsetNodesSelection() - store.addSelectedElements([edgeElement.value]) + store.addSelectedElements([props.edge]) } - hooks.edgeClick.trigger({ event, edge: edgeElement.value }) + hooks.edgeClick.trigger({ event, edge: props.edge }) } const onEdgeContextMenu = (event: MouseEvent) => hooks.edgeContextMenu.trigger({ event, - edge: edgeElement.value, + edge: props.edge, }) -const onEdgeMouseEnter = (event: MouseEvent) => hooks.edgeMouseEnter.trigger({ event, edge: edgeElement.value }) +const onEdgeMouseEnter = (event: MouseEvent) => hooks.edgeMouseEnter.trigger({ event, edge: props.edge }) -const onEdgeMouseMove = (event: MouseEvent) => hooks.edgeMouseMove.trigger({ event, edge: edgeElement.value }) +const onEdgeMouseMove = (event: MouseEvent) => hooks.edgeMouseMove.trigger({ event, edge: props.edge }) -const onEdgeMouseLeave = (event: MouseEvent) => hooks.edgeMouseLeave.trigger({ event, edge: edgeElement.value }) +const onEdgeMouseLeave = (event: MouseEvent) => hooks.edgeMouseLeave.trigger({ event, edge: props.edge }) const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => { const nodeId = isSourceHandle ? props.edge.target : props.edge.source @@ -105,7 +74,7 @@ const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => { const isValidConnection = () => true const isTarget = isSourceHandle - hooks.edgeUpdateStart.trigger({ event, edge: edgeElement.value }) + hooks.edgeUpdateStart.trigger({ event, edge: props.edge }) handleId && onMouseDown(event, store, hooks, handleId, nodeId, isTarget, isValidConnection, isSourceHandle ? 'target' : 'source') } @@ -121,18 +90,8 @@ const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => { const updating = ref(false) const onEdgeUpdaterMouseEnter = () => (updating.value = true) const onEdgeUpdaterMouseOut = () => (updating.value = false) -const edgePos = computed(() => - getEdgePositions( - props.nodes.value.sourceNode, - sourceHandle, - sourcePosition, - props.nodes.value.targetNode, - targetHandle, - targetPosition, - ), -) const isVisible = ({ sourceX, sourceY, targetX, targetY }: ReturnType) => { - return props.onlyRenderVisibleElements + return store.onlyRenderVisibleElements ? isEdgeVisible({ sourcePos: { x: sourceX, y: sourceY }, targetPos: { x: targetX, y: targetY }, @@ -142,6 +101,9 @@ const isVisible = ({ sourceX, sourceY, targetX, targetY }: ReturnType + getEdgePositions(props.nodes.sourceNode, sourceHandle, sourcePosition, props.nodes.targetNode, targetHandle, targetPosition), +) const visible = computed(() => !props.edge.isHidden && isVisible(edgePos.value))