fix(perf): improve flattenNodes
This commit is contained in:
+77
-9
@@ -38,6 +38,50 @@ const createNodeOrEdgeSelectionChange = (isSelected: boolean) => (item: Node | E
|
|||||||
isSelected,
|
isSelected,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const findNodeById = (id: string, nodes: Node[]): Node | null => {
|
||||||
|
let res = null;
|
||||||
|
|
||||||
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
|
const n = nodes[i];
|
||||||
|
|
||||||
|
if (n.id === id) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.childNodes) {
|
||||||
|
res = findNodeById(id, n.childNodes);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findNodes = (condition: (node: Node) => boolean, nodes: Node[]): Node[] => {
|
||||||
|
let res = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
|
const n = nodes[i];
|
||||||
|
|
||||||
|
if (condition(n)) {
|
||||||
|
res.push(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.childNodes) {
|
||||||
|
const matches = findNodes(condition, n.childNodes);
|
||||||
|
|
||||||
|
for (let j = 0; j < matches.length; j++) {
|
||||||
|
res.push(matches[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
const createStore = () =>
|
const createStore = () =>
|
||||||
create<ReactFlowState>((set, get) => ({
|
create<ReactFlowState>((set, get) => ({
|
||||||
width: 0,
|
width: 0,
|
||||||
@@ -96,6 +140,7 @@ const createStore = () =>
|
|||||||
|
|
||||||
setNodes: (propNodes: Node[]) => {
|
setNodes: (propNodes: Node[]) => {
|
||||||
const { nodes } = get();
|
const { nodes } = get();
|
||||||
|
|
||||||
const nextNodes = propNodes.map((propNode: Node) => {
|
const nextNodes = propNodes.map((propNode: Node) => {
|
||||||
const storeNode = nodes.find((node) => node.id === propNode.id);
|
const storeNode = nodes.find((node) => node.id === propNode.id);
|
||||||
|
|
||||||
@@ -124,10 +169,10 @@ const createStore = () =>
|
|||||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => {
|
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => {
|
||||||
const { onNodesChange, nodes, transform } = get();
|
const { onNodesChange, nodes, transform } = get();
|
||||||
|
|
||||||
const initialChanges: NodeChange[] = [];
|
const nodesToChange: NodeChange[] = updates.reduce<NodeChange[]>((res, update) => {
|
||||||
const nodesToChange: NodeChange[] = flattenNodes(nodes).reduce((res, node) => {
|
const node = findNodeById(update.id, nodes);
|
||||||
const update = updates.find((u) => u.id === node.id);
|
|
||||||
if (update) {
|
if (node) {
|
||||||
const dimensions = getDimensions(update.nodeElement);
|
const dimensions = getDimensions(update.nodeElement);
|
||||||
const doUpdate =
|
const doUpdate =
|
||||||
dimensions.width &&
|
dimensions.width &&
|
||||||
@@ -147,7 +192,31 @@ const createStore = () =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}, initialChanges);
|
}, []);
|
||||||
|
|
||||||
|
// const nodesToChange: NodeChange[] = flattenNodes(nodes).reduce((res, node) => {
|
||||||
|
// const update = updates.find((u) => u.id === node.id);
|
||||||
|
// if (update) {
|
||||||
|
// const dimensions = getDimensions(update.nodeElement);
|
||||||
|
// const doUpdate =
|
||||||
|
// dimensions.width &&
|
||||||
|
// dimensions.height &&
|
||||||
|
// (node.width !== dimensions.width || node.height !== dimensions.height || update.forceUpdate);
|
||||||
|
|
||||||
|
// if (doUpdate) {
|
||||||
|
// const handleBounds = getHandleBounds(update.nodeElement, transform[2]);
|
||||||
|
// const change = {
|
||||||
|
// id: node.id,
|
||||||
|
// type: 'dimensions',
|
||||||
|
// dimensions,
|
||||||
|
// handleBounds,
|
||||||
|
// } as NodeChange;
|
||||||
|
// res.push(change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return res;
|
||||||
|
// }, initialChanges);
|
||||||
|
|
||||||
onNodesChange?.(nodesToChange);
|
onNodesChange?.(nodesToChange);
|
||||||
},
|
},
|
||||||
@@ -155,12 +224,11 @@ const createStore = () =>
|
|||||||
const { onNodesChange, nodes, nodeExtent } = get();
|
const { onNodesChange, nodes, nodeExtent } = get();
|
||||||
|
|
||||||
if (onNodesChange) {
|
if (onNodesChange) {
|
||||||
const matchingNodes = flattenNodes(nodes).filter((n) => n.id === id || n.isSelected);
|
const matchingNodes = flattenNodes(findNodes((n) => n.id === id || !!n.isSelected, nodes));
|
||||||
const matchingChildNodes = flattenNodes(matchingNodes); //.filter(n => !!n.childNodes).reduce<Node[]>((result, node) => result.concat(node.childNodes!), []));
|
|
||||||
|
|
||||||
if (matchingChildNodes?.length) {
|
if (matchingNodes?.length) {
|
||||||
onNodesChange(
|
onNodesChange(
|
||||||
matchingChildNodes.map((n) => {
|
matchingNodes.map((n) => {
|
||||||
const change: NodePositionChange = {
|
const change: NodePositionChange = {
|
||||||
id: n.id,
|
id: n.id,
|
||||||
type: 'position',
|
type: 'position',
|
||||||
|
|||||||
+24
-8
@@ -343,12 +343,28 @@ export function applyEdgeChanges(changes: EdgeChange[], edges: Edge[]): Edge[] {
|
|||||||
return applyChanges(changes, edges) as Edge[];
|
return applyChanges(changes, edges) as Edge[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function flattenNodes(nodes: Node[] | undefined): Node[] {
|
function flat(arr: Node[], target: Node[]) {
|
||||||
if (!nodes) {
|
arr.forEach(function (el) {
|
||||||
return [];
|
if (el.childNodes) {
|
||||||
}
|
flat(el.childNodes, target);
|
||||||
|
} else {
|
||||||
return nodes.reduce<Node[]>((result, node) => {
|
target.push(el);
|
||||||
return result.concat([node, ...flattenNodes(node.childNodes)]);
|
}
|
||||||
}, []);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flattenNodes(nodes: Node[]): Node[] {
|
||||||
|
const flattened: Node[] = [];
|
||||||
|
flat(nodes, flattened);
|
||||||
|
return flattened;
|
||||||
|
|
||||||
|
// return nodes.reduce<Node[]>((result, node) => {
|
||||||
|
// result.push(node);
|
||||||
|
|
||||||
|
// if (node.childNodes) {
|
||||||
|
// result.push(...flattenNodes(node.childNodes));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return result;
|
||||||
|
// }, []);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user