Skip to content
+

Data Grid - Tree data

Use tree data to render rows with parent-child relationships in the Data Grid.

Trees are hierarchical data structures that organize data into parent-child relationships. The Data Grid Pro can use tree data to render rows that conform to this pattern. The demo below illustrates this feature with a large and complex hierarchical dataset:

Rendering tree data

To work with tree data, pass the treeData and getTreeDataPath props to the <DataGridPro /> component. The getTreeDataPath function returns an array of strings representing the path to a given row.

<DataGridPro treeData getTreeDataPath={getTreeDataPath} />

Both examples that follow will render a tree that looks like this:

// - Sarah
//     - Thomas
//         - Robert
//         - Karen

1. Without transformation:

const columns: GridColDef[] = [{ field: 'jobTitle', width: 250 }];

const rows: GridRowsProp = [
  { path: ['Sarah'], jobTitle: 'CEO', id: 0 },
  { path: ['Sarah', 'Thomas'], jobTitle: 'Head of Sales', id: 1 },
  { path: ['Sarah', 'Thomas', 'Robert'], jobTitle: 'Sales Person', id: 2 },
  { path: ['Sarah', 'Thomas', 'Karen'], jobTitle: 'Sales Person', id: 3 },
];

const getTreeDataPath: DataGridProProps['getTreeDataPath'] = (row) => row.path;

<DataGridPro
  treeData
  getTreeDataPath={getTreeDataPath}
  rows={rows}
  columns={columns}
/>;

2. With transformation:

const columns: GridColDef[] = [{ field: 'jobTitle', width: 250 }];

const rows: GridRowsProp = [
  { path: 'Sarah', jobTitle: 'CEO', id: 0 },
  { path: 'Sarah/Thomas', jobTitle: 'Head of Sales', id: 1 },
  { path: 'Sarah/Thomas/Robert', jobTitle: 'Sales Person', id: 2 },
  { path: 'Sarah/Thomas/Karen', jobTitle: 'Sales Person', id: 3 },
];

const getTreeDataPath: DataGridProProps['getTreeDataPath'] = (row) =>
  row.path.split('/');

<DataGridPro
  treeData
  getTreeDataPath={getTreeDataPath}
  rows={rows}
  columns={columns}
/>;

Customizing grouping columns with tree data

For complete details on customizing grouping columns, see Row grouping—Grouping columns. The implementation and behavior are the same when working with tree data, but note that the leafField and mainGroupingCriteria props are not applicable.

The demo below customizes the Hierarchy grouping column:

Accessing the grouping column field

To access the grouping column field—for example, to use it with column pinning—the Grid provides the GRID_TREE_DATA_GROUPING_FIELD constant:

<DataGridPro
  treeData
  initialState={{
    pinnedColumns: {
      left: [GRID_TREE_DATA_GROUPING_FIELD],
    },
  }}
  {...otherProps}
/>

Group expansion with tree data

For complete details on customizing the group expansion experience, see Row grouping—Group expansion. The implementation and behavior are the same when working with tree data.

Automatic parent and child selection with tree data

For complete details on automatic parent and child selection, see Row grouping—Automatic parent and child selection. The implementation and behavior are the same when working with tree data.

Gaps in the tree

If the tree data provided is missing levels in the hierarchy, the Data Grid Pro will automatically create the rows needed to fill the gaps. Consider a simple dataset with two rows:

[{ path: ['A'] }, { path: ['A', 'B', 'C'] }];

This tree data implies a { path: ["A", "B"] } row that's not present. To address this, the Grid generates an internal row so it can render without issues.

In the demo below, rows with no gaps are denoted with in the Gap column—you can see that the rows for Thomas, Mary, and Linda have been autogenerated since they're not present in the dataset.

Filtering tree data

When a filter is applied, a node is included if it or any of its descendents passes.

By default, filtering is applied at every level of the tree. You can limit it to top-level rows with the disableChildrenFiltering prop.

Sorting tree data

By default, sorting is applied at every level of the tree. You can limit it to top-level rows with the disableChildrenSorting prop.

Drag-and-drop tree data reordering

With row reordering, users can reorder tree data or move rows from one group to another.

To enable this feature with tree data, pass the rowReordering prop to the Data Grid component. You also need to pass the setTreeDataPath() prop to revert the operation done by getTreeDataPath() while building the tree, because row reordering can change the path of the row.

<DataGridPro
  columns={columns}
  rows={rows}
  treeData
  getTreeDataPath={getTreeDataPath}
  setTreeDataPath={setTreeDataPath}
  rowReordering
/>

Reordering persistance

To sync the updated row order with an external store, depending on how you manage the order of rows in the external store, you can use either processRowUpdate() or the onRowOrderChange() callback, or both.

The processRowUpdate() callback is triggered whenever a row is updated either by row editing or when the path value is updated during a cross parent reorder operation.

After the reorder operation is successfully completed, the onRowOrderChange() callback is triggered, which contains information about the new row reordering of the format GridRowOrderChangeParams.

<DataGridPro
  // Fired when:
  // - A row is edited (e.g. when the user changes the value of a cell)
  // - The `path` value is updated during a cross parent reorder operation
  processRowUpdate={processRowUpdate}
  // Fired after a reorder operation is completed
  onRowOrderChange={handleRowOrderChange}
/>

The demo below uses a custom data store bound using useSyncExternalStore() to persist the row data in local storage.

It maintains a row tree structure which is used to recompute path values after a reorder operation is performed, these props are used to sync the updated row order with the external store:

  • processRowUpdate(): Used to update the row data when a row is edited (path value change isn't needed due to dynamic path computation. For static paths, you might need to also sync the path values).
  • onRowOrderChange(): Used to capture the new row order after a reorder operation is performed, and update the external store with the new row order.

You can test out the demo by reordering the rows and then refreshing the page to see that the order persists.

Lazy-loading tree data children

See Server-side data—Tree data for details on lazy-loading tree data children.

API