From 091d6bac68fd21f5db7ce1e6d48828bc4c33adfd Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 4 Sep 2024 12:51:43 +0200 Subject: [PATCH] refactor(getNodesBounds): use system/getNodesBounds for hook --- packages/react/src/hooks/useReactFlow.ts | 27 ++--------------- .../svelte/src/lib/hooks/useSvelteFlow.ts | 30 ++----------------- packages/system/src/utils/graph.ts | 28 ++++++++++++----- 3 files changed, 26 insertions(+), 59 deletions(-) diff --git a/packages/react/src/hooks/useReactFlow.ts b/packages/react/src/hooks/useReactFlow.ts index aeb68834..c4d81e2d 100644 --- a/packages/react/src/hooks/useReactFlow.ts +++ b/packages/react/src/hooks/useReactFlow.ts @@ -1,15 +1,12 @@ import { useMemo } from 'react'; import { - boxToRect, EdgeRemoveChange, evaluateAbsolutePosition, - getBoundsOfBoxes, getElementsToRemove, + getNodesBounds, getOverlappingArea, - isInternalNodeBase, isRectObject, NodeRemoveChange, - nodeToBox, nodeToRect, type Rect, } from '@xyflow/system'; @@ -235,28 +232,8 @@ export function useReactFlow { - if (nodes.length === 0) { - return { x: 0, y: 0, width: 0, height: 0 }; - } - const { nodeLookup, nodeOrigin } = store.getState(); - - const box = nodes.reduce( - (currBox, node) => { - const internalNode = - typeof node === 'string' - ? nodeLookup.get(node) - : !isInternalNodeBase(node) - ? nodeLookup.get(node.id) - : node; - - const nodeBox = internalNode ? nodeToBox(internalNode, nodeOrigin) : { x: 0, y: 0, x2: 0, y2: 0 }; - return getBoundsOfBoxes(currBox, nodeBox); - }, - { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity } - ); - - return boxToRect(box); + return getNodesBounds(nodes, { nodeLookup, nodeOrigin }); }, getHandleConnections: ({ type, id, nodeId }) => Array.from( diff --git a/packages/svelte/src/lib/hooks/useSvelteFlow.ts b/packages/svelte/src/lib/hooks/useSvelteFlow.ts index 3ee50ea0..6ee27fb2 100644 --- a/packages/svelte/src/lib/hooks/useSvelteFlow.ts +++ b/packages/svelte/src/lib/hooks/useSvelteFlow.ts @@ -14,13 +14,10 @@ import { getViewportForBounds, getElementsToRemove, rendererPointToPoint, - nodeToBox, - getBoundsOfBoxes, - boxToRect, - isInternalNodeBase, evaluateAbsolutePosition, type HandleType, - type HandleConnection + type HandleConnection, + getNodesBounds } from '@xyflow/system'; import { useStore } from '$lib/store'; @@ -555,31 +552,10 @@ export function useSvelteFlow(): { nodes.update((nds) => nds); }, getNodesBounds: (nodes) => { - if (nodes.length === 0) { - return { x: 0, y: 0, width: 0, height: 0 }; - } - const _nodeLookup = get(nodeLookup); const _nodeOrigin = get(nodeOrigin); - const box = nodes.reduce( - (currBox, node) => { - const internalNode = - typeof node === 'string' - ? _nodeLookup.get(node) - : !isInternalNodeBase(node) - ? _nodeLookup.get(node.id) - : node; - - const nodeBox = internalNode - ? nodeToBox(internalNode, _nodeOrigin) - : { x: 0, y: 0, x2: 0, y2: 0 }; - return getBoundsOfBoxes(currBox, nodeBox); - }, - { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity } - ); - - return boxToRect(box); + return getNodesBounds(nodes, { nodeLookup: _nodeLookup, nodeOrigin: _nodeOrigin }); }, getHandleConnections: ({ type, id, nodeId }) => Array.from( diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts index 7efde2e3..25c60d03 100644 --- a/packages/system/src/utils/graph.ts +++ b/packages/system/src/utils/graph.ts @@ -118,23 +118,26 @@ export const getNodePositionWithOrigin = (node: NodeBase, nodeOrigin: NodeOrigin }; }; -export type GetNodesBoundsParams = { +export type GetNodesBoundsParams = { nodeOrigin?: NodeOrigin; + nodeLookup?: NodeLookup>; }; /** * Determines a bounding box that contains all given nodes in an array - * @deprecated This function yields erronous results for subflows. Use getNodesBounds from useReactFlow/useSvelteFlow hook instead. * @public * @remarks Useful when combined with {@link getViewportForBounds} to calculate the correct transform to fit the given nodes in a viewport. * @param nodes - Nodes to calculate the bounds for * @param params.nodeOrigin - Origin of the nodes: [0, 0] - top left, [0.5, 0.5] - center * @returns Bounding box enclosing all nodes */ -export const getNodesBounds = (nodes: NodeBase[], params: GetNodesBoundsParams = { nodeOrigin: [0, 0] }): Rect => { - if (process.env.NODE_ENV === 'development') { +export const getNodesBounds = ( + nodes: (NodeType | InternalNodeBase | string)[], + params: GetNodesBoundsParams = { nodeOrigin: [0, 0], nodeLookup: undefined } +): Rect => { + if (process.env.NODE_ENV === 'development' && !params.nodeLookup) { console.warn( - '[DEPRECATED] `getNodesBounds` is deprecated because it yields erronous results for subflows. Use `getNodesBounds` from useReactFlow/useSvelteFlow hook instead.' + 'Please use `getNodesBounds` from useReactFlow/useSvelteFlow hook to ensure correct values for sub flows.' ); } @@ -143,8 +146,19 @@ export const getNodesBounds = (nodes: NodeBase[], params: GetNodesBoundsParams = } const box = nodes.reduce( - (currBox, node) => { - const nodeBox = nodeToBox(node, params.nodeOrigin); + (currBox, nodeOrId) => { + const isId = typeof nodeOrId === 'string'; + let currentNode = !params.nodeLookup && !isId ? nodeOrId : undefined; + + if (params.nodeLookup) { + currentNode = isId + ? params.nodeLookup.get(nodeOrId) + : !isInternalNodeBase(nodeOrId) + ? params.nodeLookup.get(nodeOrId.id) + : nodeOrId; + } + + const nodeBox = currentNode ? nodeToBox(currentNode, params.nodeOrigin) : { x: 0, y: 0, x2: 0, y2: 0 }; return getBoundsOfBoxes(currBox, nodeBox); }, { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity }