From 122f72274220824f745f812b285fcb9639fa82fa Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 4 Sep 2024 17:07:00 +0200 Subject: [PATCH] chore(store): cleanup --- examples/react/src/examples/Subflow/index.tsx | 18 ++-- packages/system/src/utils/general.ts | 18 ++++ packages/system/src/utils/store.ts | 89 +++++++++---------- 3 files changed, 68 insertions(+), 57 deletions(-) diff --git a/examples/react/src/examples/Subflow/index.tsx b/examples/react/src/examples/Subflow/index.tsx index 7130c1b1..0f59a97e 100644 --- a/examples/react/src/examples/Subflow/index.tsx +++ b/examples/react/src/examples/Subflow/index.tsx @@ -15,6 +15,7 @@ import { Panel, useUpdateNodeInternals, ReactFlowProvider, + CoordinateExtent, } from '@xyflow/react'; import DebugNode from './DebugNode'; @@ -162,6 +163,11 @@ const nodeTypes = { default: DebugNode, }; +const nodeExtent: CoordinateExtent = [ + [0, 0], + [1000, 1000], +]; + const Subflow = () => { const [rfInstance, setRfInstance] = useState(null); const updateNodeInternals = useUpdateNodeInternals(); @@ -231,10 +237,7 @@ const Subflow = () => { nodeTypes={nodeTypes} fitView nodeOrigin={[0, 0]} - nodeExtent={[ - [0, 0], - [1000, 1000], - ]} + nodeExtent={nodeExtent} > @@ -254,12 +257,7 @@ const Subflow = () => { }; export default () => ( - + ); diff --git a/packages/system/src/utils/general.ts b/packages/system/src/utils/general.ts index aa20c958..533c83ee 100644 --- a/packages/system/src/utils/general.ts +++ b/packages/system/src/utils/general.ts @@ -25,6 +25,24 @@ export const clampPosition = ( y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0)), }); +export function clampPositionToParent( + childPosition: XYPosition, + childDimensions: Dimensions, + parent: InternalNodeBase +) { + const { width: parentWidth, height: parentHeight } = getNodeDimensions(parent); + const { x: parentX, y: parentY } = parent.internals.positionAbsolute; + + return clampPosition( + childPosition, + [ + [parentX, parentY], + [parentX + parentWidth, parentY + parentHeight], + ], + childDimensions + ); +} + /** * Calculates the velocity of panning when the mouse is close to the edge of the canvas * @internal diff --git a/packages/system/src/utils/store.ts b/packages/system/src/utils/store.ts index debe5d1d..fc1e14c1 100644 --- a/packages/system/src/utils/store.ts +++ b/packages/system/src/utils/store.ts @@ -1,4 +1,4 @@ -import { Dimensions, infiniteExtent } from '..'; +import { infiniteExtent } from '..'; import { NodeBase, CoordinateExtent, @@ -20,6 +20,7 @@ import { import { getDimensions, getHandleBounds } from './dom'; import { clampPosition, + clampPositionToParent, getBoundsOfRects, getNodeDimensions, isCoordinateExtent, @@ -64,7 +65,7 @@ export function updateAbsolutePositions( continue; } - updateChildPosition(node, nodeLookup, parentLookup, _options); + updateChildNode(node, nodeLookup, parentLookup, _options); } } @@ -83,21 +84,21 @@ export function adoptUserNodes( options?: UpdateNodesOptions ) { const _options = mergeObjects(adoptUserNodesDefaultOptions, options); - const tmpLookup = new Map(nodeLookup); + const selectedNodeZ: number = _options?.elevateNodesOnSelect ? 1000 : 0; + nodeLookup.clear(); parentLookup.clear(); - const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0; - for (const userNode of nodes) { let internalNode = tmpLookup.get(userNode.id); + if (_options.checkEquality && userNode === internalNode?.internals.userNode) { nodeLookup.set(userNode.id, internalNode); } else { - const positionOrigin = getNodePositionWithOrigin(userNode, _options.nodeOrigin); + const positionWithOrigin = getNodePositionWithOrigin(userNode, _options.nodeOrigin); const extent = isCoordinateExtent(userNode.extent) ? userNode.extent : _options.nodeExtent; - const positionAbsolute = clampPosition(positionOrigin, extent, getNodeDimensions(userNode)); + const clampedPosition = clampPosition(positionWithOrigin, extent, getNodeDimensions(userNode)); internalNode = { ..._options.defaults, @@ -107,30 +108,50 @@ export function adoptUserNodes( height: userNode.measured?.height, }, internals: { - positionAbsolute, + positionAbsolute: clampedPosition, // if user re-initializes the node or removes `measured` for whatever reason, we reset the handleBounds so that the node gets re-measured handleBounds: !userNode.measured ? undefined : internalNode?.internals.handleBounds, z: calculateZ(userNode, selectedNodeZ), userNode, }, }; + nodeLookup.set(userNode.id, internalNode); } if (userNode.parentId) { - updateChildPosition(internalNode, nodeLookup, parentLookup, options); + updateChildNode(internalNode, nodeLookup, parentLookup, options); } } } -function updateChildPosition( +function updateParentLookup( + node: InternalNodeBase, + parentLookup: ParentLookup> +) { + if (!node.parentId) { + return; + } + + const childNodes = parentLookup.get(node.parentId); + + if (childNodes) { + childNodes.set(node.id, node); + } else { + parentLookup.set(node.parentId, new Map([[node.id, node]])); + } +} + +/** + * Updates positionAbsolute and zIndex of a child node and the parentLookup. + */ +function updateChildNode( node: InternalNodeBase, nodeLookup: NodeLookup>, parentLookup: ParentLookup>, options?: UpdateNodesOptions ) { - const _options = mergeObjects(defaultOptions, options); - + const { elevateNodesOnSelect, nodeOrigin } = mergeObjects(defaultOptions, options); const parentId = node.parentId!; const parentNode = nodeLookup.get(parentId); @@ -141,48 +162,22 @@ function updateChildPosition( return; } - // update the parentLookup - const childNodes = parentLookup.get(parentId); - if (childNodes) { - childNodes.set(node.id, node); - } else { - parentLookup.set(parentId, new Map([[node.id, node]])); - } + updateParentLookup(node, parentLookup); - const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0; - - const { x, y, z } = calculateChildXYZ(node, parentNode, _options.nodeOrigin!, selectedNodeZ); - - const currPosition = node.internals.positionAbsolute; - const positionChanged = x !== currPosition.x || y !== currPosition.y; + const selectedNodeZ = elevateNodesOnSelect ? 1000 : 0; + const { x, y, z } = calculateChildXYZ(node, parentNode, nodeOrigin, selectedNodeZ); + const { positionAbsolute } = node.internals; + const positionChanged = x !== positionAbsolute.x || y !== positionAbsolute.y; if (positionChanged || z !== node.internals.z) { node.internals = { ...node.internals, - positionAbsolute: positionChanged ? { x, y } : currPosition, + positionAbsolute: positionChanged ? { x, y } : positionAbsolute, z, }; } } -function clampPositionToParent( - childPosition: XYPosition, - childDimensions: Dimensions, - parent: InternalNodeBase -) { - const parentDimensions = getNodeDimensions(parent); - const parentPosition = parent.internals.positionAbsolute; - - return clampPosition( - childPosition, - [ - [parentPosition.x, parentPosition.y], - [parentPosition.x + parentDimensions.width, parentPosition.y + parentDimensions.height], - ], - childDimensions - ); -} - function calculateZ(node: NodeBase, selectedNodeZ: number) { return (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0); } @@ -193,14 +188,14 @@ function calculateChildXYZ( nodeOrigin: NodeOrigin, selectedNodeZ: number ) { - const parentPosition = parentNode.internals.positionAbsolute; + const { x: parentX, y: parentY } = parentNode.internals.positionAbsolute; const childDimensions = getNodeDimensions(childNode); const positionWithOrigin = getNodePositionWithOrigin(childNode, nodeOrigin); const clampedPosition = isCoordinateExtent(childNode.extent) ? clampPosition(positionWithOrigin, childNode.extent, childDimensions) : positionWithOrigin; - let absolutePosition = { x: parentPosition.x + clampedPosition.x, y: parentPosition.y + clampedPosition.y }; + let absolutePosition = { x: parentX + clampedPosition.x, y: parentY + clampedPosition.y }; if (childNode.extent === 'parent') { absolutePosition = clampPositionToParent(absolutePosition, childDimensions, parentNode); @@ -365,7 +360,7 @@ export function updateNodeInternals( }, }; if (node.parentId) { - updateChildPosition(node, nodeLookup, parentLookup, { nodeOrigin }); + updateChildNode(node, nodeLookup, parentLookup, { nodeOrigin }); } updatedInternals = true;