---
title: "Tree Data - Group Column"
enterprise: true
framework: javascript
version: "36.1.0"
---

# Tree Data - Group Column

Customise the generated group column when using Tree Data.

## Group Column Configuration

When using Tree Data, the grid will automatically generate a group column to display the hierarchy. This column can be configured by using the `autoGroupColumnDef` grid option, allowing any [Column Property](https://www.ag-grid.com/javascript-data-grid/column-definitions/) to be overridden.

#### Group Column Configuration

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    { field: "created" },
    { field: "modified" },
    {
      field: "size",
      aggFunc: "sum",
      valueFormatter: (params) => {
        const sizeInKb = params.value / 1024;

        if (sizeInKb > 1024) {
          return `${+(sizeInKb / 1024).toFixed(2)} MB`;
        } else {
          return `${+sizeInKb.toFixed(2)} KB`;
        }
      },
    },
  ],
  defaultColDef: {
    flex: 1,
  },
  autoGroupColumnDef: {
    headerName: "My Group",
    minWidth: 340,
  },
  rowData: getData(),
  treeData: true,
  groupDefaultExpanded: -1,
  getDataPath: (data) => data.path,
};

// wait for the document to be loaded, otherwise
// AG Grid will not find the div in the document.
// lookup the container we want the Grid to use
const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;

// create the grid passing in the div to use together with the columns & data we want to use
gridApi = createGrid(gridDiv, gridOptions);
```

[Live example: Group Column Configuration](https://www.ag-grid.com/examples/tree-data-group-column/group-column/typescript/)

The example above sets different header text and a minimum width to each Group Column cell using the following configuration:

```js
const gridOptions = {
    autoGroupColumnDef: {
        headerName: 'My Group',
        minWidth: 220,
    },

    // other grid options ...
}
```

## Group Cell Component

The grid uses the `agGroupCellRenderer` component to render the group column cells.

### Child Row Counts

When showing child counts with Tree Data, the child count is a count of all descendants, including groups.

#### Child Counts

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    { field: "created" },
    { field: "modified" },
    {
      field: "size",
      aggFunc: "sum",
      valueFormatter: (params) => {
        const sizeInKb = params.value / 1024;

        if (sizeInKb > 1024) {
          return `${+(sizeInKb / 1024).toFixed(2)} MB`;
        } else {
          return `${+sizeInKb.toFixed(2)} KB`;
        }
      },
    },
  ],
  defaultColDef: {
    flex: 1,
  },
  autoGroupColumnDef: {
    headerName: "File Explorer",
    minWidth: 270,
  },
  rowData: getData(),
  treeData: true,
  groupDefaultExpanded: -1,
  getDataPath: (data) => data.path,
};

// wait for the document to be loaded, otherwise
// AG Grid will not find the div in the document.
// lookup the container we want the Grid to use
const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;

// create the grid passing in the div to use together with the columns & data we want to use
gridApi = createGrid(gridDiv, gridOptions);
```

[Live example: Child Counts](https://www.ag-grid.com/examples/tree-data-group-column/child-counts/typescript/)

Note how in the example above, the `Desktop` row has a child count of 5, of which one of is the `ProjectAlpha` [Filler Group](https://www.ag-grid.com/javascript-data-grid/tree-data-paths/#filler-groups) row.

### Default Component Options

The options configurable on the `agGroupCellRenderer` via the column definition `cellRendererParams` are:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `suppressPadding` | `boolean` |  |  | Set to `true` to not include any padding (indentation) in the child rows. |
| `suppressDoubleClickExpand` | `boolean` |  |  | Set to `true` to suppress expand on double click. |
| `suppressEnterExpand` | `boolean` |  |  | Set to `true` to suppress expand on ↵ Enter |
| `totalValueGetter` | `string \| TotalValueGetterFunc` |  |  | The value getter for the total row text. Can be a function or expression. |
| `suppressCount` | `boolean` |  |  | If `true`, count is not displayed beside the name. |
| `innerRenderer` | `any` |  |  | The renderer to use for inside the cell (after grouping functions are added) |
| `innerRendererParams` | `any` |  |  | Additional params to customise to the `innerRenderer`. |
| `innerRendererSelector` | `CellRendererSelectorFunc` |  |  | Callback to enable different innerRenderers to be used based of value of params. |

### Custom Component

Where the default `agGroupCellRenderer` does not meet your requirements, you can provide a [Custom Cell Component](https://www.ag-grid.com/javascript-data-grid/component-cell-renderer/), via the `cellRenderer` property in the `autoGroupColumnDef` grid option.

The below example provides a custom cell renderer which:

- Uses a custom icon to represent the groups expanded state
- Responds to row expansion events to update if the group is expanded or collapsed from another source
- Cleans up all event listeners when it's destroyed

#### Custom Component

```ts
import {
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ClientSideRowModelModule,
  ColDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { CustomGroupCellRenderer } from "./customGroupCellRenderer";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

const columnDefs: ColDef[] = [
  { field: "created" },
  { field: "modified" },
  {
    field: "size",
    aggFunc: "sum",
    valueFormatter: (params) => {
      const sizeInKb = params.value / 1024;

      if (sizeInKb > 1024) {
        return `${+(sizeInKb / 1024).toFixed(2)} MB`;
      } else {
        return `${+sizeInKb.toFixed(2)} KB`;
      }
    },
  },
];

let gridApi: GridApi;

const gridOptions: GridOptions = {
  treeData: true,
  getDataPath: (data) => data.path,
  columnDefs: columnDefs,
  autoGroupColumnDef: {
    cellRenderer: CustomGroupCellRenderer,
  },
  defaultColDef: {
    flex: 1,
    minWidth: 120,
  },
  groupDefaultExpanded: 1,
  rowData: getData(),
  onCellDoubleClicked: (params: CellDoubleClickedEvent<IOlympicData, any>) => {
    if (params.colDef.showRowGroup) {
      params.node.setExpanded(!params.node.expanded);
    }
  },
  onCellKeyDown: (params: CellKeyDownEvent<IOlympicData, any>) => {
    if (!("colDef" in params)) {
      return;
    }
    if (!(params.event instanceof KeyboardEvent)) {
      return;
    }
    if (params.event.code !== "Enter") {
      return;
    }
    if (params.colDef.showRowGroup) {
      params.node.setExpanded(!params.node.expanded);
    }
  },
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);
```

[Live example: Custom Component](https://www.ag-grid.com/examples/tree-data-group-column/custom-component/typescript/)

This demonstrates supplying a custom cell renderer via the `cellRenderer` property in the `autoGroupColumnDef`:

```js
const gridOptions = {
    autoGroupColumnDef: {
        cellRenderer: CellRenderer,
    },

    // other grid options ...
}
```

### Dynamic Component Selection

When it's necessary to use different renderers in the same column, you can configure this with the `cellRendererSelector` property in the `autoGroupColumnDef` grid option.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `cellRendererSelector` | `CellRendererSelectorFunc` |  |  | Callback to select which cell renderer to be used for a given row within the same column. |

The example below extends the [Custom Component](https://www.ag-grid.com/javascript-data-grid/tree-data-group-column/#custom-component) example to use a different renderer based on the rows level:

#### Dynamic Component Selection

```ts
import {
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ClientSideRowModelModule,
  ColDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { CustomGroupCellRenderer } from "./customGroupCellRenderer";
import { getData } from "./data";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

const columnDefs: ColDef[] = [
  { field: "created" },
  { field: "modified" },
  {
    field: "size",
    aggFunc: "sum",
    valueFormatter: (params) => {
      const sizeInKb = params.value / 1024;

      if (sizeInKb > 1024) {
        return `${+(sizeInKb / 1024).toFixed(2)} MB`;
      } else {
        return `${+sizeInKb.toFixed(2)} KB`;
      }
    },
  },
];

const autoGroupColumnDef: ColDef = {
  cellRendererSelector: (params) => {
    if (params.node.level === 0) {
      return {
        component: "agGroupCellRenderer",
      };
    }
    return {
      component: CustomGroupCellRenderer,
    };
  },
};

let gridApi: GridApi;

const gridOptions: GridOptions = {
  treeData: true,
  getDataPath: (data) => data.path,
  columnDefs: columnDefs,
  autoGroupColumnDef: autoGroupColumnDef,
  defaultColDef: {
    flex: 1,
    minWidth: 120,
  },
  groupDefaultExpanded: 1,
  rowData: getData(),
  onCellDoubleClicked: (params: CellDoubleClickedEvent<IOlympicData, any>) => {
    if (params.colDef.showRowGroup) {
      params.node.setExpanded(!params.node.expanded);
    }
  },
  onCellKeyDown: (params: CellKeyDownEvent<IOlympicData, any>) => {
    if (!("colDef" in params)) {
      return;
    }
    if (!(params.event instanceof KeyboardEvent)) {
      return;
    }
    if (params.event.code !== "Enter") {
      return;
    }
    if (params.node.level === 0) {
      return;
    }
    if (params.colDef.showRowGroup) {
      params.node.setExpanded(!params.node.expanded);
    }
  },
};

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);
```

[Live example: Dynamic Component Selection](https://www.ag-grid.com/examples/tree-data-group-column/dynamic-component/typescript/)

This uses the following configuration to display the default cell renderer for root level groups, and the custom renderer for all others:

```js
const gridOptions = {
    cellRendererSelector: (params) => {
        if (params.node.level === 0) {
            return {
                component: 'agGroupCellRenderer',
            };
        }
        return {
            component: CustomGroupCellRenderer,
        };
    },

    // other grid options ...
}
```

Refer to the [Cell Components](https://www.ag-grid.com/javascript-data-grid/component-cell-renderer/) documentation for information on how to create custom cell renderers.
