Skip to content

Commit

Permalink
[DataGridPremium] Improve aggregation performance for multiple columns (
Browse files Browse the repository at this point in the history
  • Loading branch information
cherniavskii authored Jan 8, 2025
1 parent 3fe74a9 commit 068ab78
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,20 @@ import {
import { getAggregationRules } from './gridAggregationUtils';
import { gridAggregationModelSelector } from './gridAggregationSelectors';

const getAggregationCellValue = ({
apiRef,
groupId,
field,
aggregationFunction,
aggregationRowsScope,
}: {
apiRef: React.MutableRefObject<GridApiPremium>;
groupId: GridRowId;
field: string;
aggregationFunction: GridAggregationFunction;
aggregationRowsScope: DataGridPremiumProcessedProps['aggregationRowsScope'];
}) => {
const getGroupAggregatedValue = (
groupId: GridRowId,
apiRef: React.MutableRefObject<GridApiPremium>,
aggregationRowsScope: DataGridPremiumProcessedProps['aggregationRowsScope'],
aggregatedFields: string[],
aggregationRules: GridAggregationRules,
position: GridAggregationPosition,
) => {
const groupAggregationLookup: GridAggregationLookup[GridRowId] = {};
const aggregatedValues: { aggregatedField: string; values: any[] }[] = [];

const rowIds = apiRef.current.getRowGroupChildren({ groupId });
const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef);
const rowIds: GridRowId[] = apiRef.current.getRowGroupChildren({ groupId });

const values: any[] = [];
rowIds.forEach((rowId) => {
if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
return;
Expand All @@ -53,51 +50,43 @@ const getAggregationCellValue = ({
return;
}

if (typeof aggregationFunction.getCellValue === 'function') {
const row = apiRef.current.getRow(rowId);
values.push(aggregationFunction.getCellValue({ row }));
} else {
values.push(apiRef.current.getCellValue(rowId, field));
}
});
const row = apiRef.current.getRow(rowId);

return aggregationFunction.apply({
values,
groupId,
field, // Added per user request in https://github.com/mui/mui-x/issues/6995#issuecomment-1327423455
});
};
for (let j = 0; j < aggregatedFields.length; j += 1) {
const aggregatedField = aggregatedFields[j];
const columnAggregationRules = aggregationRules[aggregatedField];

const getGroupAggregatedValue = ({
groupId,
apiRef,
aggregationRowsScope,
aggregatedFields,
aggregationRules,
position,
}: {
groupId: GridRowId;
apiRef: React.MutableRefObject<GridApiPremium>;
aggregationRowsScope: DataGridPremiumProcessedProps['aggregationRowsScope'];
aggregatedFields: string[];
aggregationRules: GridAggregationRules;
position: GridAggregationPosition;
}) => {
const groupAggregationLookup: GridAggregationLookup[GridRowId] = {};
const aggregationFunction = columnAggregationRules.aggregationFunction;
const field = aggregatedField;

for (let j = 0; j < aggregatedFields.length; j += 1) {
const aggregatedField = aggregatedFields[j];
const columnAggregationRules = aggregationRules[aggregatedField];
if (aggregatedValues[j] === undefined) {
aggregatedValues[j] = {
aggregatedField,
values: [],
};
}

if (typeof aggregationFunction.getCellValue === 'function') {
aggregatedValues[j].values.push(aggregationFunction.getCellValue({ row }));
} else {
const colDef = apiRef.current.getColumn(field);
aggregatedValues[j].values.push(apiRef.current.getRowValue(row, colDef));
}
}
});

for (let i = 0; i < aggregatedValues.length; i += 1) {
const { aggregatedField, values } = aggregatedValues[i];
const aggregationFunction = aggregationRules[aggregatedField].aggregationFunction;
const value = aggregationFunction.apply({
values,
groupId,
field: aggregatedField, // Added per user request in https://github.com/mui/mui-x/issues/6995#issuecomment-1327423455
});

groupAggregationLookup[aggregatedField] = {
position,
value: getAggregationCellValue({
apiRef,
groupId,
field: aggregatedField,
aggregationFunction: columnAggregationRules.aggregationFunction,
aggregationRowsScope,
}),
value,
};
}

Expand All @@ -115,11 +104,11 @@ export const createAggregationLookup = ({
aggregationRowsScope: DataGridPremiumProcessedProps['aggregationRowsScope'];
getAggregationPosition: DataGridPremiumProcessedProps['getAggregationPosition'];
}): GridAggregationLookup => {
const aggregationRules = getAggregationRules({
columnsLookup: gridColumnLookupSelector(apiRef),
aggregationModel: gridAggregationModelSelector(apiRef),
const aggregationRules = getAggregationRules(
gridColumnLookupSelector(apiRef),
gridAggregationModelSelector(apiRef),
aggregationFunctions,
});
);

const aggregatedFields = Object.keys(aggregationRules);
if (aggregatedFields.length === 0) {
Expand All @@ -143,14 +132,14 @@ export const createAggregationLookup = ({
if (hasAggregableChildren) {
const position = getAggregationPosition(groupNode);
if (position != null) {
aggregationLookup[groupNode.id] = getGroupAggregatedValue({
groupId: groupNode.id,
aggregationLookup[groupNode.id] = getGroupAggregatedValue(
groupNode.id,
apiRef,
aggregatedFields,
aggregationRowsScope,
aggregatedFields,
aggregationRules,
position,
});
);
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,16 @@ export const mergeStateWithAggregationModel =
aggregation: { ...state.aggregation, model: aggregationModel },
});

export const getAggregationRules = ({
columnsLookup,
aggregationModel,
aggregationFunctions,
}: {
columnsLookup: GridColumnRawLookup;
aggregationModel: GridAggregationModel;
aggregationFunctions: Record<string, GridAggregationFunction>;
}) => {
export const getAggregationRules = (
columnsLookup: GridColumnRawLookup,
aggregationModel: GridAggregationModel,
aggregationFunctions: Record<string, GridAggregationFunction>,
) => {
const aggregationRules: GridAggregationRules = {};

Object.entries(aggregationModel).forEach(([field, columnItem]) => {
// eslint-disable-next-line guard-for-in
for (const field in aggregationModel) {
const columnItem = aggregationModel[field];
if (
columnsLookup[field] &&
canColumnHaveAggregationFunction({
Expand All @@ -111,7 +109,7 @@ export const getAggregationRules = ({
aggregationFunction: aggregationFunctions[columnItem],
};
}
});
}

return aggregationRules;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ export const useGridAggregation = (

const aggregationRules = props.disableAggregation
? {}
: getAggregationRules({
columnsLookup: gridColumnLookupSelector(apiRef),
aggregationModel: gridAggregationModelSelector(apiRef),
aggregationFunctions: props.aggregationFunctions,
});
: getAggregationRules(
gridColumnLookupSelector(apiRef),
gridAggregationModelSelector(apiRef),
props.aggregationFunctions,
);

// Re-apply the row hydration to add / remove the aggregation footers
if (!areAggregationRulesEqual(rulesOnLastRowHydration, aggregationRules)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ export const useGridAggregationPreProcessors = (
(columnsState) => {
const aggregationRules = props.disableAggregation
? {}
: getAggregationRules({
columnsLookup: columnsState.lookup,
aggregationModel: gridAggregationModelSelector(apiRef),
aggregationFunctions: props.aggregationFunctions,
});
: getAggregationRules(
columnsState.lookup,
gridAggregationModelSelector(apiRef),
props.aggregationFunctions,
);

columnsState.orderedFields.forEach((field) => {
const shouldHaveAggregationValue = !!aggregationRules[field];
Expand Down Expand Up @@ -76,11 +76,11 @@ export const useGridAggregationPreProcessors = (
(value) => {
const aggregationRules = props.disableAggregation
? {}
: getAggregationRules({
columnsLookup: gridColumnLookupSelector(apiRef),
aggregationModel: gridAggregationModelSelector(apiRef),
aggregationFunctions: props.aggregationFunctions,
});
: getAggregationRules(
gridColumnLookupSelector(apiRef),
gridAggregationModelSelector(apiRef),
props.aggregationFunctions,
);

const hasAggregationRule = Object.keys(aggregationRules).length > 0;

Expand Down

0 comments on commit 068ab78

Please sign in to comment.