refactor(wrapnode): put update node logic in action
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
import { HandleElement, Position } from '../../types';
|
||||||
|
import { getDimensions } from '../../utils';
|
||||||
|
|
||||||
|
export const getHandleBounds = (
|
||||||
|
selector: string,
|
||||||
|
nodeElement: HTMLDivElement,
|
||||||
|
parentBounds: ClientRect | DOMRect,
|
||||||
|
k: number
|
||||||
|
): HandleElement[] | null => {
|
||||||
|
const handles = nodeElement.querySelectorAll(selector);
|
||||||
|
|
||||||
|
if (!handles || !handles.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlesArray = Array.from(handles) as HTMLDivElement[];
|
||||||
|
|
||||||
|
return handlesArray.map(
|
||||||
|
(handle): HandleElement => {
|
||||||
|
const bounds = handle.getBoundingClientRect();
|
||||||
|
const dimensions = getDimensions(handle);
|
||||||
|
const nodeIdAttr = handle.getAttribute('data-nodeid');
|
||||||
|
const handlePosition = (handle.getAttribute('data-handlepos') as unknown) as Position;
|
||||||
|
const nodeIdSplitted = nodeIdAttr ? nodeIdAttr.split('__') : null;
|
||||||
|
|
||||||
|
let handleId = null;
|
||||||
|
|
||||||
|
if (nodeIdSplitted) {
|
||||||
|
handleId = (nodeIdSplitted.length ? nodeIdSplitted[1] : nodeIdSplitted) as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: handleId,
|
||||||
|
position: handlePosition,
|
||||||
|
x: (bounds.left - parentBounds.left) * (1 / k),
|
||||||
|
y: (bounds.top - parentBounds.top) * (1 / k),
|
||||||
|
...dimensions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -3,58 +3,9 @@ import { DraggableCore } from 'react-draggable';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { ResizeObserver } from 'resize-observer';
|
import { ResizeObserver } from 'resize-observer';
|
||||||
|
|
||||||
import { getDimensions } from '../../utils';
|
|
||||||
import { Provider } from '../../contexts/NodeIdContext';
|
import { Provider } from '../../contexts/NodeIdContext';
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
import {
|
import { Node, XYPosition, Transform, ElementId, NodeComponentProps, WrapNodeProps } from '../../types';
|
||||||
Node,
|
|
||||||
XYPosition,
|
|
||||||
HandleElement,
|
|
||||||
Position,
|
|
||||||
Transform,
|
|
||||||
ElementId,
|
|
||||||
NodeComponentProps,
|
|
||||||
WrapNodeProps,
|
|
||||||
} from '../../types';
|
|
||||||
|
|
||||||
const getHandleBounds = (
|
|
||||||
selector: string,
|
|
||||||
nodeElement: HTMLDivElement,
|
|
||||||
parentBounds: ClientRect | DOMRect,
|
|
||||||
k: number
|
|
||||||
): HandleElement[] | null => {
|
|
||||||
const handles = nodeElement.querySelectorAll(selector);
|
|
||||||
|
|
||||||
if (!handles || !handles.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlesArray = Array.from(handles) as HTMLDivElement[];
|
|
||||||
|
|
||||||
return handlesArray.map(
|
|
||||||
(handle): HandleElement => {
|
|
||||||
const bounds = handle.getBoundingClientRect();
|
|
||||||
const dimensions = getDimensions(handle);
|
|
||||||
const nodeIdAttr = handle.getAttribute('data-nodeid');
|
|
||||||
const handlePosition = (handle.getAttribute('data-handlepos') as unknown) as Position;
|
|
||||||
const nodeIdSplitted = nodeIdAttr ? nodeIdAttr.split('__') : null;
|
|
||||||
|
|
||||||
let handleId = null;
|
|
||||||
|
|
||||||
if (nodeIdSplitted) {
|
|
||||||
handleId = (nodeIdSplitted.length ? nodeIdSplitted[1] : nodeIdSplitted) as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: handleId,
|
|
||||||
position: handlePosition,
|
|
||||||
x: (bounds.left - parentBounds.left) * (1 / k),
|
|
||||||
y: (bounds.top - parentBounds.top) * (1 / k),
|
|
||||||
...dimensions,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onStart = (
|
const onStart = (
|
||||||
evt: MouseEvent,
|
evt: MouseEvent,
|
||||||
@@ -153,14 +104,7 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeState = store.getState();
|
store.dispatch.updateNodeDimensions({ id, nodeElement: nodeElement.current });
|
||||||
const bounds = nodeElement.current.getBoundingClientRect();
|
|
||||||
const dimensions = getDimensions(nodeElement.current);
|
|
||||||
const handleBounds = {
|
|
||||||
source: getHandleBounds('.source', nodeElement.current, bounds, storeState.transform[2]),
|
|
||||||
target: getHandleBounds('.target', nodeElement.current, bounds, storeState.transform[2]),
|
|
||||||
};
|
|
||||||
store.dispatch.updateNodeData({ id, ...dimensions, handleBounds });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
+16
-11
@@ -2,6 +2,9 @@ import { createStore, Action, action } from 'easy-peasy';
|
|||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { Selection as D3Selection, ZoomBehavior } from 'd3';
|
import { Selection as D3Selection, ZoomBehavior } from 'd3';
|
||||||
|
|
||||||
|
import { getDimensions } from '../utils';
|
||||||
|
import { getHandleBounds } from '../components/Nodes/utils';
|
||||||
|
|
||||||
import { getNodesInside, getConnectedEdges, getRectOfNodes } from '../utils/graph';
|
import { getNodesInside, getConnectedEdges, getRectOfNodes } from '../utils/graph';
|
||||||
import {
|
import {
|
||||||
ElementId,
|
ElementId,
|
||||||
@@ -14,7 +17,6 @@ import {
|
|||||||
XYPosition,
|
XYPosition,
|
||||||
OnConnectFunc,
|
OnConnectFunc,
|
||||||
SelectionRect,
|
SelectionRect,
|
||||||
HandleElement,
|
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
type TransformXYK = {
|
type TransformXYK = {
|
||||||
@@ -28,14 +30,9 @@ type NodePosUpdate = {
|
|||||||
pos: XYPosition;
|
pos: XYPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
type NodeUpdate = {
|
type NodeDimensionUpdate = {
|
||||||
id: ElementId;
|
id: ElementId;
|
||||||
width: number;
|
nodeElement: HTMLDivElement;
|
||||||
height: number;
|
|
||||||
handleBounds: {
|
|
||||||
source: HandleElement[] | null;
|
|
||||||
target: HandleElement[] | null;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type SelectionUpdate = {
|
type SelectionUpdate = {
|
||||||
@@ -86,7 +83,7 @@ export interface StoreModel {
|
|||||||
|
|
||||||
setEdges: Action<StoreModel, Edge[]>;
|
setEdges: Action<StoreModel, Edge[]>;
|
||||||
|
|
||||||
updateNodeData: Action<StoreModel, NodeUpdate>;
|
updateNodeDimensions: Action<StoreModel, NodeDimensionUpdate>;
|
||||||
|
|
||||||
updateNodePos: Action<StoreModel, NodePosUpdate>;
|
updateNodePos: Action<StoreModel, NodePosUpdate>;
|
||||||
|
|
||||||
@@ -152,12 +149,20 @@ const storeModel: StoreModel = {
|
|||||||
state.edges = edges;
|
state.edges = edges;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateNodeData: action((state, { id, ...data }) => {
|
updateNodeDimensions: action((state, { id, nodeElement }) => {
|
||||||
|
const bounds = nodeElement.getBoundingClientRect();
|
||||||
|
const dimensions = getDimensions(nodeElement);
|
||||||
|
const handleBounds = {
|
||||||
|
source: getHandleBounds('.source', nodeElement, bounds, state.transform[2]),
|
||||||
|
target: getHandleBounds('.target', nodeElement, bounds, state.transform[2]),
|
||||||
|
};
|
||||||
|
|
||||||
state.nodes.forEach(n => {
|
state.nodes.forEach(n => {
|
||||||
if (n.id === id) {
|
if (n.id === id) {
|
||||||
n.__rg = {
|
n.__rg = {
|
||||||
...n.__rg,
|
...n.__rg,
|
||||||
...data,
|
...dimensions,
|
||||||
|
handleBounds,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user