refactor(core): make it possible to batch changes
This commit is contained in:
@@ -57,6 +57,7 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
|||||||
nodeElement: entry.target as HTMLDivElement,
|
nodeElement: entry.target as HTMLDivElement,
|
||||||
forceUpdate: true,
|
forceUpdate: true,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
updateNodeDimensions(updates);
|
updateNodeDimensions(updates);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,12 @@ const createRFStore = () =>
|
|||||||
onNodesChange?.(changes);
|
onNodesChange?.(changes);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged = true, dragging = false) => {
|
updateNodePositions: (
|
||||||
|
nodeDragItems: NodeDragItem[] | Node[],
|
||||||
|
positionChanged = true,
|
||||||
|
dragging = false,
|
||||||
|
applyChanges = true
|
||||||
|
) => {
|
||||||
const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin } = get();
|
const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin } = get();
|
||||||
|
|
||||||
if (hasDefaultNodes || onNodesChange) {
|
if (hasDefaultNodes || onNodesChange) {
|
||||||
@@ -128,9 +133,15 @@ const createRFStore = () =>
|
|||||||
set({ nodeInternals: nextNodeInternals });
|
set({ nodeInternals: nextNodeInternals });
|
||||||
}
|
}
|
||||||
|
|
||||||
onNodesChange?.(changes);
|
if (applyChanges) {
|
||||||
|
onNodesChange?.(changes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
addSelectedNodes: (selectedNodeIds: string[]) => {
|
addSelectedNodes: (selectedNodeIds: string[]) => {
|
||||||
const { multiSelectionActive, nodeInternals, edges } = get();
|
const { multiSelectionActive, nodeInternals, edges } = get();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export type NodeDimensionChange = {
|
|||||||
id: string;
|
id: string;
|
||||||
type: 'dimensions';
|
type: 'dimensions';
|
||||||
dimensions: Dimensions;
|
dimensions: Dimensions;
|
||||||
|
updateStyle?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodePositionChange = {
|
export type NodePositionChange = {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { MouseEvent as ReactMouseEvent, ComponentType, MemoExoticComponent
|
|||||||
import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3';
|
import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3';
|
||||||
|
|
||||||
import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils';
|
import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils';
|
||||||
import type { NodeChange, EdgeChange } from './changes';
|
import type { NodeChange, EdgeChange, NodePositionChange } from './changes';
|
||||||
import type {
|
import type {
|
||||||
Node,
|
Node,
|
||||||
NodeInternals,
|
NodeInternals,
|
||||||
@@ -215,7 +215,12 @@ export type ReactFlowActions = {
|
|||||||
setEdges: (edges: Edge[]) => void;
|
setEdges: (edges: Edge[]) => void;
|
||||||
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => void;
|
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => void;
|
||||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged: boolean, dragging: boolean) => void;
|
updateNodePositions: (
|
||||||
|
nodeDragItems: NodeDragItem[] | Node[],
|
||||||
|
positionChanged: boolean,
|
||||||
|
dragging: boolean,
|
||||||
|
applyChanges?: boolean
|
||||||
|
) => NodePositionChange[] | null;
|
||||||
resetSelectedElements: () => void;
|
resetSelectedElements: () => void;
|
||||||
unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
|
unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
|
||||||
addSelectedNodes: (nodeIds: string[]) => void;
|
addSelectedNodes: (nodeIds: string[]) => void;
|
||||||
|
|||||||
@@ -50,58 +50,63 @@ function applyChanges(changes: any[], elements: any[]): any[] {
|
|||||||
const initElements: any[] = changes.filter((c) => c.type === 'add').map((c) => c.item);
|
const initElements: any[] = changes.filter((c) => c.type === 'add').map((c) => c.item);
|
||||||
|
|
||||||
return elements.reduce((res: any[], item: any) => {
|
return elements.reduce((res: any[], item: any) => {
|
||||||
const currentChange = changes.find((c) => c.id === item.id);
|
const currentChanges = changes.filter((c) => c.id === item.id);
|
||||||
|
|
||||||
if (currentChange) {
|
if (currentChanges.length === 0) {
|
||||||
switch (currentChange.type) {
|
res.push(item);
|
||||||
case 'select': {
|
return res;
|
||||||
res.push({ ...item, selected: currentChange.selected });
|
}
|
||||||
return res;
|
|
||||||
}
|
|
||||||
case 'position': {
|
|
||||||
const updateItem = { ...item };
|
|
||||||
|
|
||||||
if (typeof currentChange.position !== 'undefined') {
|
const updateItem = { ...item };
|
||||||
updateItem.position = currentChange.position;
|
|
||||||
|
for (const currentChange of currentChanges) {
|
||||||
|
if (currentChange) {
|
||||||
|
switch (currentChange.type) {
|
||||||
|
case 'select': {
|
||||||
|
updateItem.selected = currentChange.selected;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case 'position': {
|
||||||
|
if (typeof currentChange.position !== 'undefined') {
|
||||||
|
updateItem.position = currentChange.position;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof currentChange.positionAbsolute !== 'undefined') {
|
if (typeof currentChange.positionAbsolute !== 'undefined') {
|
||||||
updateItem.positionAbsolute = currentChange.positionAbsolute;
|
updateItem.positionAbsolute = currentChange.positionAbsolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof currentChange.dragging !== 'undefined') {
|
||||||
|
updateItem.dragging = currentChange.dragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateItem.expandParent) {
|
||||||
|
handleParentExpand(res, updateItem);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case 'dimensions': {
|
||||||
|
if (typeof currentChange.dimensions !== 'undefined') {
|
||||||
|
updateItem.width = currentChange.dimensions.width;
|
||||||
|
updateItem.height = currentChange.dimensions.height;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof currentChange.dragging !== 'undefined') {
|
if (typeof currentChange.updateStyle !== 'undefined') {
|
||||||
updateItem.dragging = currentChange.dragging;
|
updateItem.style = { ...(updateItem.style || {}), ...currentChange.dimensions };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateItem.expandParent) {
|
||||||
|
handleParentExpand(res, updateItem);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case 'remove': {
|
||||||
if (updateItem.expandParent) {
|
return res;
|
||||||
handleParentExpand(res, updateItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.push(updateItem);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
case 'dimensions': {
|
|
||||||
const updateItem = { ...item };
|
|
||||||
|
|
||||||
if (typeof currentChange.dimensions !== 'undefined') {
|
|
||||||
updateItem.width = currentChange.dimensions.width;
|
|
||||||
updateItem.height = currentChange.dimensions.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateItem.expandParent) {
|
|
||||||
handleParentExpand(res, updateItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.push(updateItem);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
case 'remove': {
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.push(item);
|
res.push(updateItem);
|
||||||
return res;
|
return res;
|
||||||
}, initElements);
|
}, initElements);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user