fix(getNodesBounds): use absolute position by default, add options param
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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 `<Handle />` data-id attribute
|
||||
- fix `getNodesBounds` and add second param for passing options
|
||||
|
||||
## 0.0.34
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,11 +102,13 @@ export const getIncomers = <NodeType extends NodeBase = NodeBase, EdgeType exten
|
||||
export const getNodePositionWithOrigin = (
|
||||
node: NodeBase | undefined,
|
||||
nodeOrigin: NodeOrigin = [0, 0]
|
||||
): XYPosition & { positionAbsolute: XYPosition } => {
|
||||
): { 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<Params extends FitViewParamsBase<NodeBase>, Options exte
|
||||
});
|
||||
|
||||
if (filteredNodes.length > 0) {
|
||||
const bounds = getNodesBounds(filteredNodes, nodeOrigin);
|
||||
const bounds = getNodesBounds(filteredNodes, { nodeOrigin });
|
||||
|
||||
const viewport = getViewportForBounds(
|
||||
bounds,
|
||||
|
||||
@@ -136,7 +136,7 @@ function calculateXYZPosition<NodeType extends NodeBase>(
|
||||
}
|
||||
|
||||
const parentNode = nodeLookup.get(node.parentNode)!;
|
||||
const parentNodePosition = getNodePositionWithOrigin(parentNode, parentNode?.origin || nodeOrigin);
|
||||
const { position: parentNodePosition } = getNodePositionWithOrigin(parentNode, parentNode?.origin || nodeOrigin);
|
||||
|
||||
return calculateXYZPosition(
|
||||
parentNode,
|
||||
|
||||
@@ -120,7 +120,7 @@ export function XYDrag<OnNodeDrag extends (e: any, nodes: any, node: any) => 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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user