fix(subflows): adjust positions before call fit view closes #2737
This commit is contained in:
@@ -22,7 +22,6 @@ const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
|||||||
const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
||||||
|
|
||||||
const defaultViewport = { x: 0, y: 0, zoom: 1.5 };
|
const defaultViewport = { x: 0, y: 0, zoom: 1.5 };
|
||||||
|
|
||||||
const initialNodes: Node[] = [
|
const initialNodes: Node[] = [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { createStore } from 'zustand';
|
|||||||
import { clampPosition, getDimensions, internalsSymbol } from '../utils';
|
import { clampPosition, getDimensions, internalsSymbol } from '../utils';
|
||||||
import { applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
|
import { applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
|
||||||
import { getHandleBounds } from '../components/Nodes/utils';
|
import { getHandleBounds } from '../components/Nodes/utils';
|
||||||
import { createNodeInternals, fitView, updateNodesAndEdgesSelections } from './utils';
|
import { createNodeInternals, fitView, updateAbsoluteNodePositions, updateNodesAndEdgesSelections } from './utils';
|
||||||
import initialState from './initialState';
|
import initialState from './initialState';
|
||||||
import type {
|
import type {
|
||||||
ReactFlowState,
|
ReactFlowState,
|
||||||
@@ -99,6 +99,8 @@ const createRFStore = () =>
|
|||||||
return res;
|
return res;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
updateAbsoluteNodePositions(nodeInternals, nodeOrigin);
|
||||||
|
|
||||||
const nextFitViewOnInitDone =
|
const nextFitViewOnInitDone =
|
||||||
fitViewOnInitDone ||
|
fitViewOnInitDone ||
|
||||||
(fitViewOnInit && !fitViewOnInitDone && fitView(get, { initial: true, ...fitViewOnInitOptions }));
|
(fitViewOnInit && !fitViewOnInitDone && fitView(get, { initial: true, ...fitViewOnInitOptions }));
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ type ParentNodes = Record<string, boolean>;
|
|||||||
function calculateXYZPosition(
|
function calculateXYZPosition(
|
||||||
node: Node,
|
node: Node,
|
||||||
nodeInternals: NodeInternals,
|
nodeInternals: NodeInternals,
|
||||||
parentNodes: ParentNodes,
|
|
||||||
result: XYZPosition,
|
result: XYZPosition,
|
||||||
nodeOrigin: NodeOrigin
|
nodeOrigin: NodeOrigin
|
||||||
): XYZPosition {
|
): XYZPosition {
|
||||||
@@ -33,7 +32,6 @@ function calculateXYZPosition(
|
|||||||
return calculateXYZPosition(
|
return calculateXYZPosition(
|
||||||
parentNode,
|
parentNode,
|
||||||
nodeInternals,
|
nodeInternals,
|
||||||
parentNodes,
|
|
||||||
{
|
{
|
||||||
x: (result.x ?? 0) + parentNodePosition.x,
|
x: (result.x ?? 0) + parentNodePosition.x,
|
||||||
y: (result.y ?? 0) + parentNodePosition.y,
|
y: (result.y ?? 0) + parentNodePosition.y,
|
||||||
@@ -43,6 +41,41 @@ function calculateXYZPosition(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateAbsoluteNodePositions(
|
||||||
|
nodeInternals: NodeInternals,
|
||||||
|
nodeOrigin: NodeOrigin,
|
||||||
|
parentNodes?: ParentNodes
|
||||||
|
) {
|
||||||
|
nodeInternals.forEach((node) => {
|
||||||
|
if (node.parentNode && !nodeInternals.has(node.parentNode)) {
|
||||||
|
throw new Error(`Parent node ${node.parentNode} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.parentNode || parentNodes?.[node.id]) {
|
||||||
|
const { x, y, z } = calculateXYZPosition(
|
||||||
|
node,
|
||||||
|
nodeInternals,
|
||||||
|
{
|
||||||
|
...node.position,
|
||||||
|
z: node[internalsSymbol]?.z ?? 0,
|
||||||
|
},
|
||||||
|
nodeOrigin
|
||||||
|
);
|
||||||
|
|
||||||
|
node.positionAbsolute = {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
};
|
||||||
|
|
||||||
|
node[internalsSymbol]!.z = z;
|
||||||
|
|
||||||
|
if (parentNodes?.[node.id]) {
|
||||||
|
node[internalsSymbol]!.isParent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function createNodeInternals(
|
export function createNodeInternals(
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
nodeInternals: NodeInternals,
|
nodeInternals: NodeInternals,
|
||||||
@@ -83,35 +116,7 @@ export function createNodeInternals(
|
|||||||
nextNodeInternals.set(node.id, internals);
|
nextNodeInternals.set(node.id, internals);
|
||||||
});
|
});
|
||||||
|
|
||||||
nextNodeInternals.forEach((node) => {
|
updateAbsoluteNodePositions(nextNodeInternals, nodeOrigin, parentNodes);
|
||||||
if (node.parentNode && !nextNodeInternals.has(node.parentNode)) {
|
|
||||||
throw new Error(`Parent node ${node.parentNode} not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.parentNode || parentNodes[node.id]) {
|
|
||||||
const { x, y, z } = calculateXYZPosition(
|
|
||||||
node,
|
|
||||||
nextNodeInternals,
|
|
||||||
parentNodes,
|
|
||||||
{
|
|
||||||
...node.position,
|
|
||||||
z: node[internalsSymbol]?.z ?? 0,
|
|
||||||
},
|
|
||||||
nodeOrigin
|
|
||||||
);
|
|
||||||
|
|
||||||
node.positionAbsolute = {
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
};
|
|
||||||
|
|
||||||
node[internalsSymbol]!.z = z;
|
|
||||||
|
|
||||||
if (parentNodes[node.id]) {
|
|
||||||
node[internalsSymbol]!.isParent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return nextNodeInternals;
|
return nextNodeInternals;
|
||||||
}
|
}
|
||||||
@@ -142,6 +147,7 @@ export function fitView(get: StoreApi<ReactFlowState>['getState'], options: Inte
|
|||||||
|
|
||||||
if (nodes.length > 0 && nodesInitialized) {
|
if (nodes.length > 0 && nodesInitialized) {
|
||||||
const bounds = getRectOfNodes(nodes, nodeOrigin);
|
const bounds = getRectOfNodes(nodes, nodeOrigin);
|
||||||
|
|
||||||
const [x, y, zoom] = getTransformForBounds(
|
const [x, y, zoom] = getTransformForBounds(
|
||||||
bounds,
|
bounds,
|
||||||
width,
|
width,
|
||||||
|
|||||||
Reference in New Issue
Block a user