refactor(nodes): only use node internals

This commit is contained in:
moklick
2021-11-18 13:01:11 +01:00
parent f0e79c634a
commit 0974aa5732
21 changed files with 171 additions and 151 deletions
+39 -27
View File
@@ -42,7 +42,6 @@ const createStore = () =>
width: 0,
height: 0,
transform: [0, 0, 1],
nodes: [],
edges: [],
onNodesChange: null,
onEdgesChange: null,
@@ -87,28 +86,29 @@ const createStore = () =>
setNodes: (nodes: Node[]) => {
const nodeInternals = createNodeInternals(nodes, get().nodeInternals);
set({ nodes, nodeInternals });
set({ nodeInternals });
},
setEdges: (edges: Edge[]) => {
set({ edges });
},
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => {
const { onNodesChange, nodes, transform, nodeInternals } = get();
const { onNodesChange, transform, nodeInternals } = get();
const nodesToChange: NodeChange[] = updates.reduce<NodeChange[]>((res, update) => {
const node = nodes.find((n) => n.id === update.id);
const node = nodeInternals.get(update.id);
if (node) {
const dimensions = getDimensions(update.nodeElement);
const doUpdate =
const doUpdate = !!(
dimensions.width &&
dimensions.height &&
(node.width !== dimensions.width || node.height !== dimensions.height || update.forceUpdate);
(node.width !== dimensions.width || node.height !== dimensions.height || update.forceUpdate)
);
if (doUpdate) {
const handleBounds = getHandleBounds(update.nodeElement, transform[2]);
nodeInternals.set(node.id, {
...nodeInternals.get(node.id),
...node,
handleBounds,
...dimensions,
});
@@ -127,17 +127,19 @@ const createStore = () =>
set({ nodeInternals: new Map(nodeInternals) });
onNodesChange?.(nodesToChange);
if (nodesToChange?.length > 0) {
onNodesChange?.(nodesToChange);
}
},
updateNodePosition: ({ id, diff, dragging }: NodeDiffUpdate) => {
const { onNodesChange, nodes, nodeExtent, nodeInternals } = get();
const { onNodesChange, nodeExtent, nodeInternals } = get();
if (onNodesChange) {
const matchingNodes = nodes.filter((n) => !!(n.selected || n.id === id));
const nodes = Array.from(nodeInternals);
const matchingNodes = nodes.filter(([_, n]) => !!(n.selected || n.id === id));
if (matchingNodes?.length) {
onNodesChange(
matchingNodes?.map((node) => {
matchingNodes?.map(([_, node]) => {
const change: NodeDimensionChange = {
id: node.id,
type: 'dimensions',
@@ -190,7 +192,7 @@ const createStore = () =>
});
},
updateUserSelection: (mousePos: XYPosition) => {
const { userSelectionRect, nodes, edges, transform, onNodesChange, onEdgesChange } = get();
const { userSelectionRect, nodeInternals, edges, transform, onNodesChange, onEdgesChange } = get();
const startX = userSelectionRect.startX ?? 0;
const startY = userSelectionRect.startY ?? 0;
@@ -202,6 +204,8 @@ const createStore = () =>
height: Math.abs(mousePos.y - startY),
};
// @TODO: work with nodeInternals instead of converting it to an array
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
const selectedNodes = getNodesInside(nodes, nextUserSelectRect, transform, false, true);
const selectedEdgeIds = getConnectedEdges(selectedNodes, edges).map((e) => e.id);
const selectedNodeIds = selectedNodes.map((n) => n.id);
@@ -218,7 +222,9 @@ const createStore = () =>
});
},
unsetUserSelection: () => {
const { userSelectionRect, nodes } = get();
const { userSelectionRect, nodeInternals } = get();
// @TODO: work with nodeInternals instead of converting it to an array
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
const selectedNodes = nodes.filter((node) => node.selected);
const stateUpdate = {
@@ -240,8 +246,9 @@ const createStore = () =>
set(stateUpdate);
},
addSelectedElements: (selectedElementsArr: Array<Node | Edge>) => {
const { multiSelectionActive, onNodesChange, onEdgesChange, nodes, edges } = get();
const { multiSelectionActive, onNodesChange, onEdgesChange, nodeInternals, edges } = get();
// @TODO: work with nodeInternals instead of converting it to an array
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
let changedNodes;
let changedEdges;
@@ -266,7 +273,9 @@ const createStore = () =>
}
},
unselectNodesAndEdges: () => {
const { nodes, edges, onNodesChange, onEdgesChange } = get();
const { nodeInternals, edges, onNodesChange, onEdgesChange } = get();
// @TODO: work with nodeInternals instead of converting it to an array
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
const nodesToUnselect = nodes.map((n) => {
n.selected = false;
@@ -308,8 +317,9 @@ const createStore = () =>
},
resetSelectedElements: () => {
const { nodes, edges, onNodesChange, onEdgesChange } = get();
const { nodeInternals, edges, onNodesChange, onEdgesChange } = get();
// @TODO: work with nodeInternals instead of converting it to an array
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
const nodesToUnselect = nodes.filter((e) => e.selected).map(createNodeOrEdgeSelectionChange(false));
const edgesToUnselect = edges.filter((e) => e.selected).map(createNodeOrEdgeSelectionChange(false));
@@ -320,16 +330,18 @@ const createStore = () =>
onEdgesChange?.(edgesToUnselect as EdgeChange[]);
}
},
setNodeExtent: (nodeExtent: CoordinateExtent) =>
setNodeExtent: (nodeExtent: CoordinateExtent) => {
const { nodeInternals } = get();
nodeInternals.forEach((node) => {
node.positionAbsolute = clampPosition(node.position, nodeExtent);
});
set({
nodeExtent,
nodes: get().nodes.map((node) => {
return {
...node,
position: clampPosition(node.position, nodeExtent),
};
}),
}),
nodeInternals: new Map(nodeInternals),
});
},
unsetNodesSelection: () => set({ nodesSelectionActive: false }),
updateTransform: (transform: Transform) => set({ transform }),
updateSize: (size: Dimensions) => set({ width: size.width || 500, height: size.height || 500 }),
+9 -5
View File
@@ -39,11 +39,11 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
const z = node.zIndex ? node.zIndex : node.dragging || node.selected ? 1000 : 0;
const internals: NodeInternalsItem = {
...nodeInternals.get(node.id),
id: node.id,
width: node.width || null,
height: node.height || null,
position: node.position,
positionAbsolute: node.position,
...node,
positionAbsolute: {
x: node.position.x,
y: node.position.y,
},
z,
};
if (node.parentNode) {
@@ -56,6 +56,10 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
nodes.forEach((node) => {
const updatedInternals: NodeInternalsItem = nextNodeInternals.get(node.id)!;
if (node.parentNode && !nextNodeInternals.has(node.parentNode)) {
throw new Error(`Parent node ${node.parentNode} not found`);
}
if (node.parentNode || parentNodes[node.id]) {
let startingZ = updatedInternals.z || 0;