diff --git a/example/src/Overview/index.tsx b/example/src/Overview/index.tsx
index ce8e774d..8da8a372 100644
--- a/example/src/Overview/index.tsx
+++ b/example/src/Overview/index.tsx
@@ -141,7 +141,7 @@ const initialEdges: Edge[] = [
];
const connectionLineStyle: CSSProperties = { stroke: '#ddd' };
-const snapGrid: SnapGrid = [16, 16];
+const snapGrid: SnapGrid = [25, 25];
const nodeStrokeColor = (n: Node): string => {
if (n.style?.background) return n.style.background as string;
@@ -203,7 +203,7 @@ const OverviewFlow = () => {
>
-
+
);
};
diff --git a/src/hooks/useDrag/index.ts b/src/hooks/useDrag/index.ts
index 8f0d6011..01f1c48c 100644
--- a/src/hooks/useDrag/index.ts
+++ b/src/hooks/useDrag/index.ts
@@ -4,8 +4,8 @@ import { select } from 'd3-selection';
import { useStoreApi } from '../../store';
import { pointToRendererPoint } from '../../utils/graph';
-import { NodeDragItem, NodeDragHandler, XYPosition } from '../../types';
-import { getDragItems, getEventHandlerParams, getParentNodePosition, hasSelector, updatePosition } from './utils';
+import { NodeDragItem, NodeDragHandler } from '../../types';
+import { getDragItems, getEventHandlerParams, hasSelector, updatePosition } from './utils';
import { handleNodeClick } from '../../components/Nodes/utils';
export type UseDragEvent = D3DragEvent;
@@ -40,7 +40,6 @@ function useDrag({
const store = useStoreApi();
const dragItems = useRef();
const lastPos = useRef<{ x: number | null; y: number | null }>({ x: null, y: null });
- const parentPos = useRef({ x: 0, y: 0 });
// returns the pointer position projected to the RF coordinate system
const getPointerPosition = useCallback(({ sourceEvent }: UseDragEvent) => {
@@ -49,9 +48,6 @@ function useDrag({
const y = sourceEvent.touches ? sourceEvent.touches[0].clientY : sourceEvent.clientY;
const pointerPos = pointToRendererPoint({ x, y }, transform, snapToGrid, snapGrid);
- pointerPos.x -= parentPos.current.x;
- pointerPos.y -= parentPos.current.y;
-
return pointerPos;
}, []);
@@ -65,7 +61,6 @@ function useDrag({
const dragHandler = drag()
.on('start', (event: UseDragEvent) => {
const { nodeInternals, multiSelectionActive, unselectNodesAndEdges } = store.getState();
- parentPos.current = getParentNodePosition(nodeInternals, nodeId);
if (!selectNodesOnDrag && !multiSelectionActive && nodeId) {
if (!nodeInternals.get(nodeId)?.selected) {
diff --git a/src/hooks/useDrag/utils.ts b/src/hooks/useDrag/utils.ts
index 8e5fb117..480be034 100644
--- a/src/hooks/useDrag/utils.ts
+++ b/src/hooks/useDrag/utils.ts
@@ -21,16 +21,6 @@ export function isParentSelected(node: Node, nodeInternals: NodeInternals): bool
return isParentSelected(parentNode, nodeInternals);
}
-export function getParentNodePosition(nodeInternals: NodeInternals, nodeId?: string): XYPosition {
- const parentNodeId = nodeId ? nodeInternals.get(nodeId)?.parentNode : null;
- const parentNode = parentNodeId ? nodeInternals.get(parentNodeId) : null;
-
- return {
- x: parentNode?.positionAbsolute?.x || 0,
- y: parentNode?.positionAbsolute?.y || 0,
- };
-}
-
export function hasSelector(target: Element, selector: string, nodeRef: RefObject): boolean {
let current = target;
@@ -49,10 +39,10 @@ export function getDragItems(nodeInternals: NodeInternals, mousePos: XYPosition,
.filter((n) => (n.selected || n.id === nodeId) && (!n.parentNode || !isParentSelected(n, nodeInternals)))
.map((n) => ({
id: n.id,
- position: n.position,
+ position: n.positionAbsolute || { x: 0, y: 0 },
distance: {
- x: mousePos.x - n.position.x,
- y: mousePos.y - n.position.y,
+ x: mousePos.x - (n.positionAbsolute?.x ?? 0),
+ y: mousePos.y - (n.positionAbsolute?.y ?? 0),
},
delta: {
x: 0,
@@ -72,16 +62,19 @@ export function updatePosition(
nodeExtent?: CoordinateExtent
): NodeDragItem {
let currentExtent = dragItem.extent || nodeExtent;
- let nextPosition = { x: mousePos.x - dragItem.distance.x, y: mousePos.y - dragItem.distance.y };
+ const nextPosition = { x: mousePos.x - dragItem.distance.x, y: mousePos.y - dragItem.distance.y };
if (dragItem.extent === 'parent') {
if (dragItem.parentNode && dragItem.width && dragItem.height) {
const parent = nodeInternals.get(dragItem.parentNode);
currentExtent =
- parent?.width && parent?.height
+ parent?.positionAbsolute && parent?.width && parent?.height
? [
- [0, 0],
- [parent.width - dragItem.width, parent.height - dragItem.height],
+ [parent.positionAbsolute.x, parent.positionAbsolute.y],
+ [
+ parent.positionAbsolute.x + parent.width - dragItem.width,
+ parent.positionAbsolute.y + parent.height - dragItem.height,
+ ],
]
: currentExtent;
} else {
@@ -93,13 +86,7 @@ export function updatePosition(
}
}
- nextPosition = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition;
-
- dragItem.delta = {
- x: nextPosition.x - dragItem.position.x,
- y: nextPosition.y - dragItem.position.y,
- };
- dragItem.position = nextPosition;
+ dragItem.position = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition;
return dragItem;
}
@@ -121,11 +108,6 @@ export function getEventHandlerParams({
return {
...node,
- position: n.position,
- positionAbsolute: {
- x: (node.positionAbsolute?.x || 0) + n.delta.x,
- y: (node.positionAbsolute?.y || 0) + n.delta.y,
- },
};
});
diff --git a/src/store/index.ts b/src/store/index.ts
index cfcd63b8..ccfdfecd 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -99,7 +99,16 @@ const createStore = () =>
};
if (positionChanged) {
+ change.positionAbsolute = node.position;
change.position = node.position;
+
+ if (node.parentNode) {
+ const parentNode = nodeInternals.get(node.parentNode);
+ change.position = {
+ x: change.position.x - (parentNode?.positionAbsolute?.x ?? 0),
+ y: change.position.y - (parentNode?.positionAbsolute?.y ?? 0),
+ };
+ }
}
return change;
diff --git a/src/types/changes.ts b/src/types/changes.ts
index b5eddaf6..498261ba 100644
--- a/src/types/changes.ts
+++ b/src/types/changes.ts
@@ -12,6 +12,7 @@ export type NodePositionChange = {
id: string;
type: 'position';
position?: XYPosition;
+ positionAbsolute?: XYPosition;
dragging?: boolean;
};
diff --git a/src/types/nodes.ts b/src/types/nodes.ts
index d73b0c97..ae0bb6f7 100644
--- a/src/types/nodes.ts
+++ b/src/types/nodes.ts
@@ -115,8 +115,6 @@ export type NodeDragItem = {
position: XYPosition;
// distance from the mouse cursor to the node when start dragging
distance: XYPosition;
- // delta to previous position
- delta: XYPosition;
width?: number | null;
height?: number | null;
extent?: 'parent' | CoordinateExtent;
diff --git a/src/utils/changes.ts b/src/utils/changes.ts
index de0771c1..76bc716e 100644
--- a/src/utils/changes.ts
+++ b/src/utils/changes.ts
@@ -67,6 +67,10 @@ function applyChanges(changes: any[], elements: any[]): any[] {
updateItem.position = currentChange.position;
}
+ if (typeof currentChange.positionAbsolute !== 'undefined') {
+ updateItem.positionAbsolute = currentChange.positionAbsolute;
+ }
+
if (typeof currentChange.dragging !== 'undefined') {
updateItem.dragging = currentChange.dragging;
}