Skip to main content
Row Grouping allows you to organize data into hierarchical groups with automatic aggregation. This is an Enterprise feature.

Overview

Row Grouping provides:
  • Hierarchical organization - Group data by one or more columns
  • Automatic aggregation - Sum, average, min, max, and custom aggregations
  • Expandable groups - Expand/collapse to show grouped data
  • Group panel - Drag-and-drop interface for dynamic grouping
  • Multi-level grouping - Create nested group hierarchies

Basic Row Grouping Implementation

import type { GridApi, GridOptions } from 'ag-grid-community';
import { 
    ClientSideRowModelModule, 
    ModuleRegistry, 
    ValidationModule, 
    createGrid 
} from 'ag-grid-community';
import { 
    RowGroupingModule, 
    RowGroupingPanelModule 
} from 'ag-grid-enterprise';

ModuleRegistry.registerModules([
    ClientSideRowModelModule,
    RowGroupingModule,
    RowGroupingPanelModule,
    ValidationModule,
]);

interface IOlympicData {
    athlete: string;
    age: number;
    country: string;
    year: number;
    date: string;
    sport: string;
    gold: number;
    silver: number;
    bronze: number;
    total: number;
}

let gridApi: GridApi<IOlympicData>;

const gridOptions: GridOptions<IOlympicData> = {
    columnDefs: [
        { field: 'country', rowGroup: true, hide: true },
        { field: 'year', rowGroup: true, hide: true },
        { field: 'athlete' },
        { field: 'sport' },
        { field: 'gold' },
        { field: 'silver' },
        { field: 'bronze' },
    ],
    defaultColDef: {
        flex: 1,
        minWidth: 100,
    },
    autoGroupColumnDef: {
        minWidth: 200,
    },
    rowGroupPanelShow: 'always',
    groupDefaultExpanded: 1,
};

// Setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function () {
    const gridDiv = document.querySelector<HTMLElement>('#myGrid')!;
    gridApi = createGrid(gridDiv, gridOptions);

    fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
        .then((response) => response.json())
        .then((data: IOlympicData[]) => 
            gridApi!.setGridOption('rowData', data)
        );
});

Key Configuration

Enable Row Grouping

Set rowGroup: true on columns to group by:
columnDefs: [
    { 
        field: 'country', 
        rowGroup: true,  // Group by country
        hide: true       // Hide the original column (optional)
    },
    { 
        field: 'year', 
        rowGroup: true   // Secondary grouping by year
    },
    { field: 'athlete' },
    { field: 'sport' },
]

Auto Group Column

Configure the automatically created group column:
autoGroupColumnDef: {
    headerName: 'Group',
    minWidth: 200,
    cellRendererParams: {
        suppressCount: false,  // Show row count in groups
        checkbox: true,        // Enable checkbox selection
    },
}

Group Panel

Enable drag-and-drop grouping:
rowGroupPanelShow: 'always',  // 'always', 'onlyWhenGrouping', 'never'
Users can drag column headers to the panel to create groups dynamically.

Default Expansion Level

Control which group levels are expanded by default:
groupDefaultExpanded: 1,  // Expand first level, -1 for all levels

Aggregation Functions

Add aggregations to numeric columns:
columnDefs: [
    { field: 'country', rowGroup: true },
    { field: 'athlete' },
    { 
        field: 'gold',
        aggFunc: 'sum',  // Sum all gold medals in group
    },
    { 
        field: 'silver',
        aggFunc: 'sum'
    },
    { 
        field: 'bronze',
        aggFunc: 'sum'
    },
    {
        field: 'age',
        aggFunc: 'avg',  // Average age in group
    },
]

Built-in Aggregation Functions

  • sum - Sum of all values
  • avg - Average of all values
  • min - Minimum value
  • max - Maximum value
  • count - Count of rows
  • first - First value
  • last - Last value

Advanced Features

Create custom aggregation functions:
const gridOptions: GridOptions = {
    columnDefs: [
        { field: 'country', rowGroup: true },
        { 
            field: 'medals',
            aggFunc: customMedalAggregation,
        },
    ],
};

function customMedalAggregation(params: IAggFuncParams) {
    // Custom logic to aggregate medals
    let gold = 0;
    let silver = 0;
    let bronze = 0;

    params.values.forEach(value => {
        if (value && typeof value === 'object') {
            gold += value.gold || 0;
            silver += value.silver || 0;
            bronze += value.bronze || 0;
        }
    });

    return { gold, silver, bronze };
}

Group Selection

Enable selection at the group level:
const gridOptions: GridOptions = {
    rowSelection: 'multiple',
    groupSelectsChildren: true,  // Selecting group selects all children
    groupSelectsFiltered: true,  // Only select filtered children
};

Filtering with Groups

Configure how filters interact with groups:
const gridOptions: GridOptions = {
    columnDefs: [
        { field: 'country', rowGroup: true },
        { field: 'athlete', filter: true },
        { field: 'sport', filter: true },
    ],
    groupHideOpenParents: false,  // Keep parent groups visible
    groupMaintainOrder: true,     // Maintain group order when filtering
};

Sorting Groups

Control group sorting behavior:
const gridOptions: GridOptions = {
    autoGroupColumnDef: {
        sort: 'asc',              // Sort groups
        comparator: (a, b) => {   // Custom group comparator
            // Custom sorting logic
            return a.localeCompare(b);
        },
    },
};

Group Rendering

Customize how groups are displayed:
const gridOptions: GridOptions = {
    autoGroupColumnDef: {
        cellRendererParams: {
            // Hide row count
            suppressCount: true,
            
            // Add checkbox
            checkbox: true,
            
            // Inner renderer for group cells
            innerRenderer: (params: any) => {
                if (params.node.group) {
                    return `<b>${params.value}</b> (${params.node.allChildrenCount} items)`;
                }
                return params.value;
            },
        },
    },
};

Required Modules

Row Grouping requires specific Enterprise modules:
import { 
    RowGroupingModule,
    RowGroupingPanelModule  // For drag-and-drop panel
} from 'ag-grid-enterprise';

ModuleRegistry.registerModules([
    ClientSideRowModelModule,
    RowGroupingModule,         // Enterprise - Required
    RowGroupingPanelModule,    // Enterprise - Optional (for panel)
]);
Row Grouping is an Enterprise feature and requires an AG Grid Enterprise license.

Best Practices

  1. Hide grouped columns - Set hide: true on grouped columns to reduce clutter
  2. Set appropriate aggregations - Choose meaningful aggregation functions
  3. Configure auto group column - Customize width and rendering
  4. Limit default expansion - Don’t expand all levels for large datasets
  5. Enable group panel - Allows users to create their own groupings
  6. Use appropriate display type - Choose between single/multiple columns based on UX
  7. Add footers for totals - Use groupIncludeFooter for group summaries

Common Patterns

Simple Two-Level Grouping

columnDefs: [
    { field: 'department', rowGroup: true, hide: true },
    { field: 'team', rowGroup: true, hide: true },
    { field: 'employee' },
    { field: 'salary', aggFunc: 'sum' },
]

Dynamic User-Controlled Grouping

const gridOptions: GridOptions = {
    columnDefs: [
        // All columns available for grouping
        { field: 'country', enableRowGroup: true },
        { field: 'year', enableRowGroup: true },
        { field: 'sport', enableRowGroup: true },
        { field: 'athlete' },
        { field: 'gold', aggFunc: 'sum' },
    ],
    rowGroupPanelShow: 'always',  // Show drag-and-drop panel
};

Grouping with Grand Totals

const gridOptions: GridOptions = {
    columnDefs: [...],
    groupIncludeTotalFooter: true,
    pinnedBottomRowData: [{ /* grand total data */ }],
};

Next Steps