---
title: "Tree Data - Group Column"
enterprise: true
framework: angular
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/angular-data-grid/column-definitions/) to be overridden.

#### Group Column Configuration

```ts
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetDataPath,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [defaultColDef]="defaultColDef"
    [autoGroupColumnDef]="autoGroupColumnDef"
    [rowData]="rowData"
    [treeData]="true"
    [groupDefaultExpanded]="groupDefaultExpanded"
    [getDataPath]="getDataPath"
  /> `,
})
export class AppComponent {
  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`;
        }
      },
    },
  ];
  defaultColDef: ColDef = {
    flex: 1,
  };
  autoGroupColumnDef: AutoGroupColumnDef = {
    headerName: "My Group",
    minWidth: 340,
  };
  rowData: any[] | null = getData();
  groupDefaultExpanded = -1;
  getDataPath: GetDataPath = (data) => data.path;
}
```

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

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

```ts
<ag-grid-angular
    [autoGroupColumnDef]="autoGroupColumnDef"
    /* other grid options ... */ />

this.autoGroupColumnDef = {
    headerName: 'My Group',
    minWidth: 220,
};
```

## 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 { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetDataPath,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [defaultColDef]="defaultColDef"
    [autoGroupColumnDef]="autoGroupColumnDef"
    [rowData]="rowData"
    [treeData]="true"
    [groupDefaultExpanded]="groupDefaultExpanded"
    [getDataPath]="getDataPath"
  /> `,
})
export class AppComponent {
  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`;
        }
      },
    },
  ];
  defaultColDef: ColDef = {
    flex: 1,
  };
  autoGroupColumnDef: AutoGroupColumnDef = {
    headerName: "File Explorer",
    minWidth: 270,
  };
  rowData: any[] | null = getData();
  groupDefaultExpanded = -1;
  getDataPath: GetDataPath = (data) => data.path;
}
```

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

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/angular-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/angular-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 { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import {
  AutoGroupColumnDef,
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetDataPath,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);
import { CustomGroupCellRenderer } from "./custom-group-cell-renderer.component";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular, CustomGroupCellRenderer],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [treeData]="true"
    [getDataPath]="getDataPath"
    [autoGroupColumnDef]="autoGroupColumnDef"
    [defaultColDef]="defaultColDef"
    [groupDefaultExpanded]="groupDefaultExpanded"
    [rowData]="rowData"
    (cellDoubleClicked)="onCellDoubleClicked($event)"
    (cellKeyDown)="onCellKeyDown($event)"
  /> `,
})
export class AppComponent {
  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`;
        }
      },
    },
  ];
  getDataPath: GetDataPath = (data) => data.path;
  autoGroupColumnDef: AutoGroupColumnDef = {
    cellRenderer: CustomGroupCellRenderer,
  };
  defaultColDef: ColDef = {
    flex: 1,
    minWidth: 120,
  };
  groupDefaultExpanded = 1;
  rowData: any[] | null = 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);
    }
  }
}
```

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

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

```ts
<ag-grid-angular
    [autoGroupColumnDef]="autoGroupColumnDef"
    /* other grid options ... */ />

this.autoGroupColumnDef = {
    cellRenderer: CellRenderer,
};
```

### 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/angular-data-grid/tree-data-group-column/#custom-component) example to use a different renderer based on the rows level:

#### Dynamic Component Selection

```ts
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import {
  AutoGroupColumnDef,
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetDataPath,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { getData } from "./data";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);
import { CustomGroupCellRenderer } from "./custom-group-cell-renderer.component";

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular, CustomGroupCellRenderer],
  template: `<ag-grid-angular
    style="width: 100%; height: 100%;"
    [columnDefs]="columnDefs"
    [autoGroupColumnDef]="autoGroupColumnDef"
    [treeData]="true"
    [getDataPath]="getDataPath"
    [defaultColDef]="defaultColDef"
    [groupDefaultExpanded]="groupDefaultExpanded"
    [rowData]="rowData"
    (cellDoubleClicked)="onCellDoubleClicked($event)"
    (cellKeyDown)="onCellKeyDown($event)"
  /> `,
})
export class AppComponent {
  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`;
        }
      },
    },
  ];
  autoGroupColumnDef: AutoGroupColumnDef = {
    cellRendererSelector: (params) => {
      if (params.node.level === 0) {
        return {
          component: "agGroupCellRenderer",
        };
      }
      return {
        component: CustomGroupCellRenderer,
      };
    },
  };
  getDataPath: GetDataPath = (data) => data.path;
  defaultColDef: ColDef = {
    flex: 1,
    minWidth: 120,
  };
  groupDefaultExpanded = 1;
  rowData: any[] | null = 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);
    }
  }
}
```

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

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

```ts
<ag-grid-angular
    [cellRendererSelector]="cellRendererSelector"
    /* other grid options ... */ />

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

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