Skip to content

Commit

Permalink
[DataGridPro] Improve treeData and rowGrouping performance (#8990)
Browse files Browse the repository at this point in the history
  • Loading branch information
MBilalShafi authored May 17, 2023
1 parent 52330d2 commit df2113b
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export const addFooterRows = ({
};

insertNodeInTree({
previousTree: null,
node: footerNode,
tree: newGroupingParams.tree,
treeDepths: newGroupingParams.treeDepths,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export const useGridRowGroupingPreProcessors = (

if (params.updates.type === 'full') {
return createRowTree({
previousTree: params.previousTree,
nodes: params.updates.rows.map(getRowTreeBuilderNode),
defaultGroupingExpansionDepth: props.defaultGroupingExpansionDepth,
isGroupExpandedByDefault: props.isGroupExpandedByDefault,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function addPinnedRow({
isAutoGenerated,
};

insertNodeInTree({ node, tree, treeDepths });
insertNodeInTree({ previousTree: null, node, tree, treeDepths });

if (!isAutoGenerated) {
dataRowIdToModelLookup[rowId] = rowModel!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export const useGridTreeDataPreProcessors = (

if (params.updates.type === 'full') {
return createRowTree({
previousTree: params.previousTree,
nodes: params.updates.rows.map(getRowTreeBuilderNode),
defaultGroupingExpansionDepth: props.defaultGroupingExpansionDepth,
isGroupExpandedByDefault: props.isGroupExpandedByDefault,
Expand Down
10 changes: 10 additions & 0 deletions packages/grid/x-data-grid-pro/src/utils/tree/createRowTree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 0,
previousTree: null,
});

expect(getGroupExpansion(response.tree)).to.deep.equal([
Expand Down Expand Up @@ -57,6 +58,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 1,
previousTree: null,
});

expect(getGroupExpansion(response.tree)).to.deep.equal([
Expand All @@ -81,6 +83,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 1,
previousTree: null,
});

expect(getGroupExpansion(response.tree)).to.deep.equal([
Expand Down Expand Up @@ -113,6 +116,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: -1,
previousTree: null,
});

expect(getGroupExpansion(response.tree)).to.deep.equal([
Expand All @@ -139,6 +143,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 0,
previousTree: null,
});

expect((response.tree[GRID_ROOT_GROUP_ID] as GridGroupNode).children).includes(0);
Expand All @@ -162,6 +167,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 0,
previousTree: null,
});

expect((response.tree[0] as GridGroupNode).children).to.includes(
Expand Down Expand Up @@ -192,6 +198,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 0,
previousTree: null,
});

expect(response.tree[0].parent).to.equal('auto-generated-row-null/A');
Expand Down Expand Up @@ -221,6 +228,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: -1,
previousTree: null,
});

// The tree created looks like this:
Expand Down Expand Up @@ -252,6 +260,7 @@ describe('createRowTree', () => {
{ id: 0, path: [{ key: 'A', field: null }] },
],
defaultGroupingExpansionDepth: 0,
previousTree: null,
});

expect((response.tree[GRID_ROOT_GROUP_ID] as GridGroupNode).children).includes(0);
Expand Down Expand Up @@ -292,6 +301,7 @@ describe('createRowTree', () => {
},
],
defaultGroupingExpansionDepth: 0,
previousTree: null,
});

expect(response.treeDepths).to.deep.equal({ 0: 1, 1: 1, 2: 2 });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { GridRowId, GridTreeNode, GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
import { GridRowId, GridTreeNode, GRID_ROOT_GROUP_ID, GridRowTreeConfig } from '@mui/x-data-grid';
import { buildRootGroup, GridRowTreeCreationValue } from '@mui/x-data-grid/internals';
import { RowTreeBuilderNode, GridTreePathDuplicateHandler } from './models';
import { insertDataRowInTree } from './insertDataRowInTree';
import { DataGridProProps } from '../../models/dataGridProProps';

interface CreateRowTreeParams {
previousTree: GridRowTreeConfig | null;
nodes: RowTreeBuilderNode[];
defaultGroupingExpansionDepth: number;
isGroupExpandedByDefault?: DataGridProProps['isGroupExpandedByDefault'];
Expand All @@ -28,6 +29,7 @@ export const createRowTree = (params: CreateRowTreeParams): GridRowTreeCreationV

insertDataRowInTree({
tree,
previousTree: params.previousTree,
id: node.id,
path: node.path,
onDuplicatePath: params.onDuplicatePath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ interface InsertDataRowInTreeParams {
* - `tree[nodeId].children.push(newNodeId)` => invalid
*/
tree: GridRowTreeConfig;
/**
* Previous tree instance for comparison.
*/
previousTree: GridRowTreeConfig | null;
/**
* Amount of nodes at each depth of the tree.
* This object can be mutated.
Expand Down Expand Up @@ -65,6 +69,7 @@ export const insertDataRowInTree = ({
id,
path,
updatedGroupsManager,
previousTree,
tree,
treeDepths,
onDuplicatePath,
Expand Down Expand Up @@ -99,6 +104,7 @@ export const insertDataRowInTree = ({

insertNodeInTree({
node: leafNode,
previousTree,
tree,
treeDepths,
});
Expand All @@ -116,6 +122,7 @@ export const insertDataRowInTree = ({

updateGroupNodeIdAndAutoGenerated({
tree,
previousTree,
treeDepths,
node: existingNodeWithPartialPath,
updatedNode: {
Expand Down Expand Up @@ -158,6 +165,7 @@ export const insertDataRowInTree = ({
defaultGroupingExpansionDepth,
isGroupExpandedByDefault,
}),
previousTree,
tree,
treeDepths,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const replaceDataGroupWithAutoGeneratedGroup = ({
updatedGroupsManager?.addAction(node.parent!, 'insertChildren');

updateGroupNodeIdAndAutoGenerated({
previousTree: null,
tree,
treeDepths,
node,
Expand Down
2 changes: 2 additions & 0 deletions packages/grid/x-data-grid-pro/src/utils/tree/updateRowTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const updateRowTree = (params: UpdateRowTreeParams): GridRowTreeCreationV
const { id, path } = params.nodes.inserted[i];

insertDataRowInTree({
previousTree: params.previousTree,
tree,
treeDepths,
updatedGroupsManager,
Expand Down Expand Up @@ -71,6 +72,7 @@ export const updateRowTree = (params: UpdateRowTreeParams): GridRowTreeCreationV
});

insertDataRowInTree({
previousTree: params.previousTree,
tree,
treeDepths,
updatedGroupsManager,
Expand Down
39 changes: 22 additions & 17 deletions packages/grid/x-data-grid-pro/src/utils/tree/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ export const addGroupDefaultExpansion = ({
*/
export const insertNodeInTree = ({
node,
previousTree,
tree,
treeDepths,
}: {
node: GridTreeNode;
previousTree: GridRowTreeConfig | null;
tree: GridRowTreeConfig;
treeDepths: GridTreeDepths;
}) => {
Expand All @@ -95,27 +97,27 @@ export const insertNodeInTree = ({
if (node.type === 'footer') {
// For footers,
// Register the node from its parent `footerId` property.
tree[node.parent] = {
...parentNode,
footerId: node.id,
};
parentNode.footerId = node.id;
} else if (node.type === 'group' || node.type === 'leaf') {
// For groups and leaves,
// Register the node from its parents `children` and `childrenFromPath` properties.
const groupingField = (node as GridGroupNode).groupingField ?? '__no_field__';
const groupingKey = (node as GridGroupNode).groupingKey ?? '__no_key__';
const groupingFieldName = (node as GridGroupNode).groupingField ?? '__no_field__';
const groupingKeyName = (node as GridGroupNode).groupingKey ?? '__no_key__';
const groupingField = parentNode.childrenFromPath?.[groupingFieldName];

tree[node.parent!] = {
...parentNode,
childrenFromPath: {
...parentNode.childrenFromPath,
[groupingField]: {
...parentNode.childrenFromPath?.[groupingField],
[groupingKey.toString()]: node.id,
},
},
children: [...parentNode.children, node.id],
};
if (previousTree !== null && previousTree[parentNode.id] === tree[parentNode.id]) {
parentNode.children = [...parentNode.children, node.id];
} else {
parentNode.children.push(node.id);
}

if (groupingField == null) {
parentNode.childrenFromPath[groupingFieldName] = {
[groupingKeyName.toString()]: node.id,
};
} else {
groupingField[groupingKeyName.toString()] = node.id;
}
}
};

Expand Down Expand Up @@ -184,9 +186,11 @@ export const removeNodeFromTree = ({
export const updateGroupNodeIdAndAutoGenerated = ({
node,
updatedNode,
previousTree,
tree,
treeDepths,
}: {
previousTree: GridRowTreeConfig | null;
node: GridGroupNode;
updatedNode: Pick<GridGroupNode, 'id' | 'isAutoGenerated'>;
tree: GridRowTreeConfig;
Expand Down Expand Up @@ -214,6 +218,7 @@ export const updateGroupNodeIdAndAutoGenerated = ({
};

insertNodeInTree({
previousTree,
node: groupNode,
tree,
treeDepths,
Expand Down

0 comments on commit df2113b

Please sign in to comment.