fix(selection): keep node positions when extent is reached closes
This commit is contained in:
@@ -254,9 +254,10 @@ export function calcNextPosition<NodeType extends NodeBase>(
|
||||
];
|
||||
}
|
||||
|
||||
const positionAbsolute = currentExtent
|
||||
? clampPosition(nextPosition, currentExtent as CoordinateExtent)
|
||||
: nextPosition;
|
||||
const positionAbsolute =
|
||||
currentExtent && currentExtent !== 'parent'
|
||||
? clampPosition(nextPosition, currentExtent as CoordinateExtent)
|
||||
: nextPosition;
|
||||
|
||||
return {
|
||||
position: {
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { drag } from 'd3-drag';
|
||||
import { select } from 'd3-selection';
|
||||
|
||||
import { calcAutoPan, getEventPosition, getPointerPosition, calcNextPosition, snapPosition } from '../utils';
|
||||
import {
|
||||
calcAutoPan,
|
||||
getEventPosition,
|
||||
getPointerPosition,
|
||||
calcNextPosition,
|
||||
snapPosition,
|
||||
getRectOfNodes,
|
||||
rectToBox,
|
||||
} from '../utils';
|
||||
import { getDragItems, getEventHandlerParams, hasSelector, wrapSelectionDragFunc } from './utils';
|
||||
import type {
|
||||
NodeBase,
|
||||
@@ -18,6 +26,7 @@ import type {
|
||||
OnNodeDrag,
|
||||
OnSelectionDrag,
|
||||
UpdateNodePositions,
|
||||
Box,
|
||||
} from '../types';
|
||||
|
||||
export type OnDrag = (event: MouseEvent, dragItems: NodeDragItem[], node: NodeBase, nodes: NodeBase[]) => void;
|
||||
@@ -105,6 +114,12 @@ export function XYDrag({
|
||||
lastPos = { x, y };
|
||||
|
||||
let hasChange = false;
|
||||
let nodesBox: Box = { x: 0, y: 0, x2: 0, y2: 0 };
|
||||
|
||||
if (dragItems.length > 1 && nodeExtent) {
|
||||
const rect = getRectOfNodes(dragItems as unknown as NodeBase[], nodeOrigin);
|
||||
nodesBox = rectToBox(rect);
|
||||
}
|
||||
|
||||
dragItems = dragItems.map((n) => {
|
||||
let nextPosition = { x: x - n.distance.x, y: y - n.distance.y };
|
||||
@@ -113,9 +128,24 @@ export function XYDrag({
|
||||
nextPosition = snapPosition(nextPosition, snapGrid);
|
||||
}
|
||||
|
||||
const updatedPos = calcNextPosition(n, nextPosition, nodes, nodeExtent, nodeOrigin, onError);
|
||||
// if there is selection with multiple nodes and a node extent is set, we need to adjust the node extent for each node
|
||||
// based on its position so that the node stays at it's position relative to the selection.
|
||||
const adjustedNodeExtent: CoordinateExtent = [
|
||||
[nodeExtent[0][0], nodeExtent[0][1]],
|
||||
[nodeExtent[1][0], nodeExtent[1][1]],
|
||||
];
|
||||
|
||||
// we want to make sure that we only fire a change event when there is a changes
|
||||
if (dragItems.length > 1 && nodeExtent && !n.extent) {
|
||||
adjustedNodeExtent[0][0] = n.positionAbsolute.x - nodesBox.x + nodeExtent[0][0];
|
||||
adjustedNodeExtent[1][0] = n.positionAbsolute.x + (n.width ?? 0) - nodesBox.x2 + nodeExtent[1][0];
|
||||
|
||||
adjustedNodeExtent[0][1] = n.positionAbsolute.y - nodesBox.y + nodeExtent[0][1];
|
||||
adjustedNodeExtent[1][1] = n.positionAbsolute.y + (n.height ?? 0) - nodesBox.y2 + nodeExtent[1][1];
|
||||
}
|
||||
|
||||
const updatedPos = calcNextPosition(n, nextPosition, nodes, adjustedNodeExtent, nodeOrigin, onError);
|
||||
|
||||
// we want to make sure that we only fire a change event when there is a change
|
||||
hasChange = hasChange || n.position.x !== updatedPos.position.x || n.position.y !== updatedPos.position.y;
|
||||
|
||||
n.position = updatedPos.position;
|
||||
|
||||
Reference in New Issue
Block a user