diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 9b83293c..8b366ce1 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -8,6 +8,7 @@ - fix `OnNodeDrag` type - do not use fallback handle if a specific id is being used - fix `defaultEdgeOptions` markers not being applied +- fix `getNodesBounds` and add second param for passing options ## 12.0.0-next.7 diff --git a/packages/react/src/additional-components/MiniMap/MiniMap.tsx b/packages/react/src/additional-components/MiniMap/MiniMap.tsx index 34a66fa1..cd3f64ae 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMap.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMap.tsx @@ -25,7 +25,8 @@ const selector = (s: ReactFlowState) => { return { viewBB, - boundingRect: s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, s.nodeOrigin), viewBB) : viewBB, + boundingRect: + s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, { nodeOrigin: s.nodeOrigin }), viewBB) : viewBB, rfId: s.rfId, nodeOrigin: s.nodeOrigin, panZoom: s.panZoom, diff --git a/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx b/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx index a681d6f3..0ecc8185 100644 --- a/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx +++ b/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx @@ -73,7 +73,7 @@ export function NodeToolbar({ return null; } - const nodeRect: Rect = getNodesBounds(nodes, nodeOrigin); + const nodeRect: Rect = getNodesBounds(nodes, { nodeOrigin }); const zIndex: number = Math.max(...nodes.map((node) => (node[internalsSymbol]?.z || 1) + 1)); const wrapperStyle: CSSProperties = { diff --git a/packages/react/src/components/NodesSelection/index.tsx b/packages/react/src/components/NodesSelection/index.tsx index f8aeb77c..d3ed7a06 100644 --- a/packages/react/src/components/NodesSelection/index.tsx +++ b/packages/react/src/components/NodesSelection/index.tsx @@ -22,7 +22,7 @@ export type NodesSelectionProps = { const selector = (s: ReactFlowState) => { const selectedNodes = s.nodes.filter((n) => n.selected); - const { width, height, x, y } = getNodesBounds(selectedNodes, s.nodeOrigin); + const { width, height, x, y } = getNodesBounds(selectedNodes, { nodeOrigin: s.nodeOrigin }); return { width, diff --git a/packages/react/src/store/initialState.ts b/packages/react/src/store/initialState.ts index 109899d6..aace0bb4 100644 --- a/packages/react/src/store/initialState.ts +++ b/packages/react/src/store/initialState.ts @@ -38,7 +38,8 @@ const getInitialState = ({ if (fitView && width && height) { const nodesWithDimensions = nextNodes.filter((node) => node.width && node.height); - const bounds = getNodesBounds(nodesWithDimensions, [0, 0]); + // @todo users nodeOrigin should be used here + const bounds = getNodesBounds(nodesWithDimensions, { nodeOrigin: [0, 0] }); const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1); transform = [x, y, zoom]; } diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 4bdc8461..b534df65 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -13,6 +13,7 @@ - Edge label has a default background and is clickable - do not use fallback handle if a specific id is being used - use correct id for `` data-id attribute +- fix `getNodesBounds` and add second param for passing options ## 0.0.34 diff --git a/packages/svelte/src/lib/plugins/NodeToolbar/NodeToolbar.svelte b/packages/svelte/src/lib/plugins/NodeToolbar/NodeToolbar.svelte index fab6ce2d..ca6dba1f 100644 --- a/packages/svelte/src/lib/plugins/NodeToolbar/NodeToolbar.svelte +++ b/packages/svelte/src/lib/plugins/NodeToolbar/NodeToolbar.svelte @@ -58,7 +58,7 @@ height: toolbarNode.computed?.height ?? toolbarNode.height ?? 0 }; } else if (toolbarNodes.length > 1) { - nodeRect = getNodesBounds(toolbarNodes, $nodeOrigin); + nodeRect = getNodesBounds(toolbarNodes, { nodeOrigin: $nodeOrigin }); } if (nodeRect) { diff --git a/packages/svelte/src/lib/store/initial-store.ts b/packages/svelte/src/lib/store/initial-store.ts index fedaa364..6c18c877 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -92,7 +92,8 @@ export const getInitialStore = ({ if (fitView && width && height) { const nodesWithDimensions = nextNodes.filter((node) => node.width && node.height); - const bounds = getNodesBounds(nodesWithDimensions, [0, 0]); + // @todo users nodeOrigin should be used here + const bounds = getNodesBounds(nodesWithDimensions, { nodeOrigin: [0, 0] }); viewport = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1); } diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts index 9dd23a1c..6407d1a1 100644 --- a/packages/system/src/utils/graph.ts +++ b/packages/system/src/utils/graph.ts @@ -102,11 +102,13 @@ export const getIncomers = { +): { position: XYPosition; positionAbsolute: XYPosition } => { if (!node) { return { - x: 0, - y: 0, + position: { + x: 0, + y: 0, + }, positionAbsolute: { x: 0, y: 0, @@ -123,7 +125,7 @@ export const getNodePositionWithOrigin = ( }; return { - ...position, + position, positionAbsolute: node.computed?.positionAbsolute ? { x: node.computed.positionAbsolute.x - offsetX, @@ -133,27 +135,35 @@ export const getNodePositionWithOrigin = ( }; }; +export type GetNodesBoundsParams = { + nodeOrigin?: NodeOrigin; + useRelativePosition?: boolean; +}; + /** * Determines a bounding box that contains all given nodes in an array * @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 nodeOrigin - Origin of the nodes: [0, 0] - top left, [0.5, 0.5] - center + * @param params.nodeOrigin - Origin of the nodes: [0, 0] - top left, [0.5, 0.5] - center + * @param params.useRelativePosition - Whether to use the relative or absolute node positions * @returns Bounding box enclosing all nodes */ -export const getNodesBounds = (nodes: NodeBase[], nodeOrigin: NodeOrigin = [0, 0]): Rect => { +export const getNodesBounds = ( + nodes: NodeBase[], + params: GetNodesBoundsParams = { nodeOrigin: [0, 0], useRelativePosition: false } +): Rect => { if (nodes.length === 0) { return { x: 0, y: 0, width: 0, height: 0 }; } const box = nodes.reduce( (currBox, node) => { - const { x, y } = getNodePositionWithOrigin(node, node.origin || nodeOrigin); + const nodePos = getNodePositionWithOrigin(node, node.origin || params.nodeOrigin); return getBoundsOfBoxes( currBox, rectToBox({ - x, - y, + ...nodePos[params.useRelativePosition ? 'position' : 'positionAbsolute'], width: node.computed?.width ?? node.width ?? 0, height: node.computed?.height ?? node.height ?? 0, }) @@ -239,7 +249,7 @@ export function fitView, Options exte }); if (filteredNodes.length > 0) { - const bounds = getNodesBounds(filteredNodes, nodeOrigin); + const bounds = getNodesBounds(filteredNodes, { nodeOrigin }); const viewport = getViewportForBounds( bounds, diff --git a/packages/system/src/utils/store.ts b/packages/system/src/utils/store.ts index 8efb84c2..51cb1329 100644 --- a/packages/system/src/utils/store.ts +++ b/packages/system/src/utils/store.ts @@ -136,7 +136,7 @@ function calculateXYZPosition( } const parentNode = nodeLookup.get(node.parentNode)!; - const parentNodePosition = getNodePositionWithOrigin(parentNode, parentNode?.origin || nodeOrigin); + const { position: parentNodePosition } = getNodePositionWithOrigin(parentNode, parentNode?.origin || nodeOrigin); return calculateXYZPosition( parentNode, diff --git a/packages/system/src/xydrag/XYDrag.ts b/packages/system/src/xydrag/XYDrag.ts index b2e8af9f..ffd19f37 100644 --- a/packages/system/src/xydrag/XYDrag.ts +++ b/packages/system/src/xydrag/XYDrag.ts @@ -120,7 +120,7 @@ export function XYDrag voi let nodesBox: Box = { x: 0, y: 0, x2: 0, y2: 0 }; if (dragItems.length > 1 && nodeExtent) { - const rect = getNodesBounds(dragItems as unknown as NodeBase[], nodeOrigin); + const rect = getNodesBounds(dragItems as unknown as NodeBase[], { nodeOrigin }); nodesBox = rectToBox(rect); }