I built a demo application using react flow. When I build a huge graph or when I zoom in and then add a node, I want the node to the visible and in the centre of the page, instead, it is added outside the view area. How can I fix this?
When I add a new node, I want it inside the view port (preferably in the centre)
With so little information/code, I'm going to have to make quite a few assumptions with my answer.
You can use the React Flow useStoreApi()
hook to get the basic information that you need (height, width, transformX, transformY, and zoomLevel) about the viewport in order to calculate the current center. Once you have that, it's just a little math to figure out the x and y placement of the new node(s).
For example:
...
const { addNodes } = useReactFlow();
const store = useStoreApi();
const onClick = useCallback(() => {
// Get the basic info about the viewport
const {
height,
width,
transform: [transformX, transformY, zoomLevel]
} = store.getState();
const zoomMultiplier = 1 / zoomLevel;
// Figure out the center of the current viewport
const centerX = -transformX * zoomMultiplier + (width * zoomMultiplier) / 2;
const centerY =
-transformY * zoomMultiplier + (height * zoomMultiplier) / 2;
// Add offsets for the height/width of the new node
// (Assuming that you don't have to calculate this as well
const nodeWidthOffset = NODE_WIDTH / 2;
const nodeHeightOffset = NODE_HEIGHT / 2;
// Standard addition of node with desired x and y
// copy and pasted from the React Flow examples
const id = `${++nodeId}`;
const newNode = {
id,
position: {
x: centerX - nodeWidthOffset + currentOverlapOffset,
y: centerY - nodeHeightOffset + currentOverlapOffset
},
data: {
label: `Node ${id}`
}
};
addNodes(newNode);
// Bonus, purely for example's sake (so multiple new nodes don't appear directly on top of each other)
currentOverlapOffset += OVERLAP_OFFSET; // May want to handle this a bit better
}, [addNodes, store]);
...
Working Example: https://codesandbox.io/s/broken-snowflake-qhc7x9?file=/App.js