Data Grid - Row grouping
Group rows together based on column values in the Data Grid.
The Data Grid Premium provides a row grouping feature to create subsets of rows based on repeated column values or custom functions.
For example, in the demo below, movies are grouped based on their respective values in the Company column—try clicking the > on the left side of a row group to expand it:
Initializing row grouping
To initialize row grouping, provide a model to the initialState
prop on the <DataGridPremium />
component.
The model's parameters correspond to the columns to be checked for repeating values.
<DataGridPremium
initialState={{
rowGrouping: {
model: ['company', 'director'],
},
}}
/>
This example creates groups for the Company column with nested subgroups based on the Director column:
Controlled row grouping
Use the rowGroupingModel
prop to control the state of the criteria used for grouping.
You can use the onRowGroupingModelChange
prop to listen to changes to the grouping criteria and update the prop accordingly.
Grouping columns
Single grouping column
By default, the Data Grid displays a single column that holds all grouped columns, no matter how many criteria are provided. If there's only one criterion, the name of the grouping column will be the same as that of the grouped column from which it's derived. When there are multiple criteria, the grouping column is named Group.
Multiple grouping columns
To display a grouping column for each criterion, set the rowGroupingColumnMode
prop to multiple
.
Custom grouping column
Use the groupingColDef
prop to customize the rendering of the grouping column.
You can override any property from the column definition (GridColDef
) interface, with the exceptions of the field
, the type
, and the properties related to inline editing.
By default, when using the object format, the properties are applied to all grouping columns.
This means that if rowGroupingColumnMode
is set to multiple
, then all columns will share the same groupingColDef
properties.
To override properties for specific grouping columns, or to apply different overrides based on the current grouping criteria, you can pass a callback function to groupingColDef
instead of an object with its config.
The callback is called for each grouping column, and it receives the respective column's fields as parameters.
The demo below illustrates this approach to provide buttons for toggling between different grouping criteria:
Grouping rows with custom cell renderer
By default, when rows are grouped by a column that uses a custom cell component, that component is also used for the cells in the grouping column.
For example, the demo below groups together movies based on the values in the Rating column. Those cells contain a custom component with a star icon, and that same component is used to fill the grouping column.
You can opt out of this default behavior by returning params.value
from the renderCell()
function—this ensures that the grouping rows will only display the shared value rather than the entire component.
const ratingColDef: GridColDef = {
// ...
renderCell: (params) => {
if (params.rowNode.type === 'group') {
return params.value;
}
return (
// ...
);
},
};
Show values for leaves
By default, grouped rows display no value in their grouping column cells—these cells are called leaves.
To display a value in a leaf, provide the leafField
property to the groupingColDef
.
The demo below uses leafField
to display values from the Title column in the leaves.
Hide descendant count
By default, row group cells display the number of descendant rows they contain, in parentheses.
Use the hideDescendantCount
property of the groupingColDef
to hide this number.
Hide grouped columns
By default, grouped columns remain visible when grouping is applied.
This means that when there's only one grouping criterion, the grouping column and the grouped column both display the same values, which may be redundant or unnecessary.
You can use the useKeepGroupedColumnsHidden
utility hook to hide grouped columns.
This automatically hides grouped columns when added to the model, and displays them when removed.
The two examples below show how to use columnVisibilityModel
and initialState
with the useKeepGroupedColumnsHidden
hook.
You can mix the two examples to support both at the same time.
// Usage with the initial state
const apiRef = useGridApiRef();
const initialState = useKeepGroupedColumnsHidden({
apiRef,
initialState: {
rowGrouping: {
model: ['company'],
},
columns: {
// Other hidden columns
columnVisibilityModel: { gross: false },
},
},
});
return <DataGridPremium {...data} apiRef={apiRef} initialState={initialState} />;
// Usage with the controlled model
const apiRef = useGridApiRef();
const [rowGroupingModel, setRowGroupingModel] = React.useState([
'company',
'director',
]);
const initialState = useKeepGroupedColumnsHidden({
apiRef,
rowGroupingModel,
});
return (
<DataGridPremium
{...data}
apiRef={apiRef}
initialState={initialState}
rowGroupingModel={rowGroupingModel}
/>
);
Disable row grouping
For all columns
To disable row grouping for all columns, set the disableRowGrouping
prop to true
.
This disables all features related to row grouping, unless a model is provided, in which case row grouping is set to read-only mode as described in Grouping non-groupable columns programmatically.
For specific columns
To disable grouping for a specific column, set the groupable
property on its GridColDef
to false
.
In the example below, the Director column cannot be grouped, even though there are repeating values. (The Title and Gross columns cannot be grouped in any examples in this doc because there are no repeating values.)
Grouping non-groupable columns programmatically
To apply row grouping programmatically on non-groupable columns (columns with groupable: false
in the GridColDef
), you can provide the row grouping model in one of three ways:
- Pass
rowGrouping.model
to theinitialState
prop. This initializes grouping with the provided model. - Provide the
rowGroupingModel
prop. This controls grouping with the provided model. - Call the API method
setRowGroupingModel
. This sets the aggregation with the provided model.
In the following example, the Company column is not groupable through the interface, but the rowGroupingModel
prop is passed to generate a read-only row group.
Using groupingValueGetter for complex grouping value
The grouping value must be either a string, a number, null
, or undefined
.
If your cell value is more complex, pass a groupingValueGetter
property to the column definition to convert it into a valid value.
const columns: GridColDef[] = [
{
field: 'composer',
groupingValueGetter: (value) => value.name,
},
// ...
];
Rows with missing groups
If a grouping criterion's key is null
or undefined
for a given row, the Data Grid will treat that row as if it doesn't have a value and exclude it from grouping.
The demo below illustrates this behavior—movies are grouped by Cinematic Universe, and rows with no value for this column are displayed individually before those with values are displayed in groups:
Group expansion
By default, all groups are initially displayed collapsed.
You can change this behavior by setting the defaultGroupingExpansionDepth
prop to expand all the groups up to a given depth when loading the data.
To expand the whole tree, set defaultGroupingExpansionDepth = -1
.
Use the isGroupExpandedByDefault()
prop to expand groups by default according to more complex logic.
This prop is a callback that receives a node as an argument.
When defined, this callback always takes priority over the defaultGroupingExpansionDepth
prop.
isGroupExpandedByDefault={
node => node.groupingField === 'company' && node.groupingKey === '20th Century Fox'
}
The example below uses this pattern to render the Grid with the 20th Century Fox group expanded:
Use the setRowChildrenExpansion()
method on the apiRef
object to programmatically set the expansion of a row.
Changing the expansion of a row emits a rowExpansionChange
event that you can listen for to react to the expansion change.
The demo below uses this pattern to implement the expansion toggle button:
Customize grouping cell indent
Use the --DataGrid-cellOffsetMultiplier
CSS variable to change the default cell indentation, as shown here:
<DataGridPremium
sx={{
// default value is 2
'--DataGrid-cellOffsetMultiplier': 6,
}}
/>
Sorting and filtering
Single grouping column
When using rowGroupingColumnMode = "single"
, the default behavior is to sort each grouping criterion using the column's sortComparator
, then apply the filterOperators
from the top-level grouping criteria.
If you're rendering leaves with the leafField
property of the groupingColDef
, then sorting and filtering will be applied on the leaves based on the sortComparator
and filterOperators
of their original column.
You can force the filtering to be applied to other grouping criteria using the mainGroupingCriteria
property of groupingColDef
.
Multiple grouping columns
When using rowGroupingColumnMode = "multiple"
, the default behavior is to apply the sortComparator
and filterOperators
of the grouping criteria of each grouping column.
If you're rendering leaves in one of those columns with the leafField
property of groupingColDef
, then sorting and filtering will be applied on the leaves for this grouping column based on the sortComparator
and filterOperators
of their original column.
If you want to render leaves but apply the sorting and filtering on the grouping criteria of the column, you can force it by setting the mainGroupingCriteria
property groupingColDef
to be equal to the grouping criteria.
In the example below, sorting and filtering from the Company grouping column are applied to the company
field, while sorting and filtering from the Director grouping column are applied to the director
field even though it has leaves.
Automatic parent and child selection
By default, selecting a parent row also selects all of its descendants.
You can customize this behavior using the rowSelectionPropagation
prop.
Here's how it's structured:
type GridRowSelectionPropagation = {
descendants?: boolean; // default: true
parents?: boolean; // default: true
};
When rowSelectionPropagation.descendants
is set to true
:
- Selecting a parent selects all of its filtered descendants automatically
- Deselecting a parent row deselects of all its filtered descendants automatically
When rowSelectionPropagation.parents
is set to true
:
- Selecting all the filtered descendants of a parent also selects the parent automatically
- Deselecting a descendant of a selected parent also deselects the parent automatically
The example below demonstrates the usage of the rowSelectionPropagation
prop—use the checkboxes at the top to see how the selection behavior changes between parents and children.
Row selection propagation also affects the Select all checkbox like any other checkbox group. Selected rows that do not pass the filtering criteria are automatically deselected when the filter is applied. Row selection propagation is not applied to the unfiltered rows.
Get all rows in a group
Use the apiRef.current.getRowGroupChildren()
method to get the IDs of all rows in a group.
The results will not contain autogenerated rows such as subgroup rows or aggregation footers.
const rows: GridRowId[] = apiRef.current.getRowGroupChildren({
groupId: params.id,
// If true, the rows will be in the order displayed on screen
applySorting: true,
// If true, only the rows matching the current filters will be returned
applyFiltering: true,
});
Use getGroupRowIdFromPath()
to get row IDs from within all groups that match a given grouping criterion:
const rows = apiRef.current.getRowGroupChildren({
groupId: getGroupRowIdFromPath([{ field: 'company', key: 'Disney Studios' }]),
});
Row group panel 🚧
With the row group panel, users would be able to control which columns are used for grouping by dragging them inside the panel.
Advanced use cases
The demo below provides an example of row grouping that's closer to a real-world use case for this feature, grouping a large dataset of contacts based on the types of goods they provide (via the hidden Commodity column).
See Row grouping recipes for more advanced use cases.
apiRef
The Data Grid exposes a set of methods via the apiRef
object that are used in the implementation of the row grouping feature.
The reference below describes the relevant functions.
See API object for more details.
Signature:
addRowGroupingCriteria: (groupingCriteriaField: string, groupingIndex?: number) => void
Signature:
removeRowGroupingCriteria: (groupingCriteriaField: string) => void
Signature:
setRowGroupingCriteriaIndex: (groupingCriteriaField: string, groupingIndex: number) => void
Signature:
setRowGroupingModel: (model: GridRowGroupingModel) => void