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

#### Group Column Configuration

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
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]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :rowData="rowData"
      :treeData="true"
      :groupDefaultExpanded="groupDefaultExpanded"
      :getDataPath="getDataPath"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<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 defaultColDef = ref<ColDef>({
      flex: 1,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      headerName: "My Group",
      minWidth: 340,
    });
    const rowData = ref<any[] | null>(getData());
    const groupDefaultExpanded = ref(-1);
    const getDataPath = ref<GetDataPath>((data) => data.path);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      rowData,
      groupDefaultExpanded,
      getDataPath,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

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

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

```ts
<ag-grid-vue
    :autoGroupColumnDef="autoGroupColumnDef"
    /* other grid options ... */>
</ag-grid-vue>

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 {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
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]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :rowData="rowData"
      :treeData="true"
      :groupDefaultExpanded="groupDefaultExpanded"
      :getDataPath="getDataPath"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<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 defaultColDef = ref<ColDef>({
      flex: 1,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      headerName: "File Explorer",
      minWidth: 270,
    });
    const rowData = ref<any[] | null>(getData());
    const groupDefaultExpanded = ref(-1);
    const getDataPath = ref<GetDataPath>((data) => data.path);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      rowData,
      groupDefaultExpanded,
      getDataPath,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

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

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/vue-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/vue-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 { createApp, defineComponent } from "vue";

import type {
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ColDef,
  GridReadyEvent,
  ValueFormatterParams,
} from "ag-grid-community";
import {
  ClientSideRowModelModule,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { AgGridVue } from "ag-grid-vue3";

import CustomGroupCellRenderer from "./customGroupCellRendererVue";
import { getData } from "./data";

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

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
                
                style="width: 100%; height: 100%;"
                :columnDefs="columnDefs"
                @grid-ready="onGridReady"
                @cell-double-clicked="onCellDoubleClicked"
                @cell-key-down="onCellKeyDown"
                :autoGroupColumnDef="autoGroupColumnDef"
                :defaultColDef="defaultColDef"
                :groupDefaultExpanded="groupDefaultExpanded"
                :rowData="rowData"
                :treeData="true"
                :getDataPath="getDataPath"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomGroupCellRenderer,
  },
  data: function () {
    return {
      columnDefs: <ColDef[]>[
        { field: "created" },
        { field: "modified" },
        {
          field: "size",
          aggFunc: "sum",
          valueFormatter: (params: ValueFormatterParams) => {
            const sizeInKb = params.value / 1024;

            if (sizeInKb > 1024) {
              return `${+(sizeInKb / 1024).toFixed(2)} MB`;
            } else {
              return `${+sizeInKb.toFixed(2)} KB`;
            }
          },
        },
      ],
      gridApi: null,
      defaultColDef: <ColDef>{
        flex: 1,
        minWidth: 120,
      },
      autoGroupColumnDef: null,
      groupDefaultExpanded: null,
      rowData: null,
      getDataPath: (data) => data.path,
    };
  },
  created() {
    this.autoGroupColumnDef = {
      cellRenderer: "CustomGroupCellRenderer",
    };
    this.groupDefaultExpanded = 1;
  },
  methods: {
    onGridReady(params: GridReadyEvent) {
      this.gridApi = params.api;

      params.api.setGridOption("rowData", getData());
    },
    onCellDoubleClicked: (params: CellDoubleClickedEvent) => {
      if (params.colDef.showRowGroup) {
        params.node.setExpanded(!params.node.expanded);
      }
    },
    onCellKeyDown: (params: CellKeyDownEvent) => {
      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);
      }
    },
  },
});

createApp(VueExample).mount("#app");
```

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

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

```ts
<ag-grid-vue
    :autoGroupColumnDef="autoGroupColumnDef"
    /* other grid options ... */>
</ag-grid-vue>

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

#### Dynamic Component Selection

```ts
import { createApp, defineComponent } from "vue";

import type {
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ColDef,
  GridReadyEvent,
} from "ag-grid-community";
import {
  ClientSideRowModelModule,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { TreeDataModule } from "ag-grid-enterprise";
import { AgGridVue } from "ag-grid-vue3";

import CustomGroupCellRenderer from "./customGroupCellRendererVue";
import { getData } from "./data";

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

ModuleRegistry.registerModules([ClientSideRowModelModule, TreeDataModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue                
                    style="width: 100%; height: 100%;"
                    :columnDefs="columnDefs"
                    @grid-ready="onGridReady"
                    @cell-double-clicked="onCellDoubleClicked"
                    @cell-key-down="onCellKeyDown"
                    :autoGroupColumnDef="autoGroupColumnDef"
                    :defaultColDef="defaultColDef"
                    :groupDefaultExpanded="groupDefaultExpanded"
                    :rowData="rowData"
                    :treeData="true"
                    :getDataPath="getDataPath">
                </ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomGroupCellRenderer,
  },
  data: function () {
    return {
      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`;
            }
          },
        },
      ],
      gridApi: null,
      defaultColDef: <ColDef>{
        flex: 1,
        minWidth: 120,
      },
      autoGroupColumnDef: null,
      groupDefaultExpanded: null,
      rowData: null,
      getDataPath: (data) => data.path,
    };
  },
  created() {
    this.autoGroupColumnDef = <ColDef>{
      cellRendererSelector: (params) => {
        if (params.node.level === 0) {
          return {
            component: "agGroupCellRenderer",
          };
        }
        return {
          component: "CustomGroupCellRenderer",
        };
      },
    };
    this.groupDefaultExpanded = 1;
  },
  methods: {
    onGridReady(params: GridReadyEvent) {
      this.gridApi = params.api;

      params.api.setGridOption("rowData", getData());
    },
    onCellDoubleClicked: (params: CellDoubleClickedEvent) => {
      if (params.colDef.showRowGroup) {
        params.node.setExpanded(!params.node.expanded);
      }
    },
    onCellKeyDown: (params: CellKeyDownEvent) => {
      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);
      }
    },
  },
});

createApp(VueExample).mount("#app");
```

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

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-vue
    :cellRendererSelector="cellRendererSelector"
    /* other grid options ... */>
</ag-grid-vue>

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

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