Row grouping

by stitot

HTML

<script src="https://cdn.jsdelivr.net/npm/@highcharts/grid-pro/grid-pro.js"></script>

<div class="controls">
    <label for="grouping-mode">
        Group by
        <select id="grouping-mode">
            <option value="region-segment" selected="">Region, segment</option>
            <option value="region">Region</option>
        </select>
    </label>
    <button type="button" id="expand-all">Expand all</button>
    <button type="button" id="collapse-all">Collapse all</button>
</div>
<div id="container"></div>

CSS

@import url("https://cdn.jsdelivr.net/npm/@highcharts/grid-pro/css/grid-pro.css");

.controls {
    padding: 8px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

#container {
    min-height: 420px;
    padding: 8px;
}

.highcharts-light #container .hcg-row-tree .hcg-cell-aggregated,
#container .hcg-row-tree .hcg-cell-aggregated {
    color: #69707d;
    font-style: italic;
}

@media (prefers-color-scheme: dark) {
    #container .hcg-row-tree .hcg-cell-aggregated {
        color: #a0a0a0;
    }
}

.highcharts-dark #container .hcg-row-tree .hcg-cell-aggregated {
    color: #a0a0a0;
}

JavaScript

const groupByOptions = {
    region: 'region',
    'region-segment': ['region', 'segment']
};

const grid = Grid.grid('container', {
    data: {
        columns: {
            region: [
                'Americas', 'Americas', 'Americas',
                'EMEA', 'EMEA', 'EMEA',
                'APAC', 'APAC'
            ],
            segment: [
                'Enterprise', 'Enterprise', 'Retail',
                'Enterprise', 'Retail', 'Retail',
                'Enterprise', 'Retail'
            ],
            account: [
                'Northwind Systems',
                'Bluefin Group',
                'Summit Outfitters',
                'Nordic Manufacturing',
                'Luma Foods',
                'Mercury Sports',
                'Pacific Logistics',
                'Harbor Retail'
            ],
            owner: [
                'Anne', 'Luis', 'Ola', 'Ola',
                'Anne', 'Tom', 'Kenji', 'Tom'
            ],
            revenue: [
                128000, 98000, 74000, 112000,
                68000, 54000, 88000, 62000
            ],
            units: [
                42, 31, 27, 39,
                22, 19, 28, 21
            ],
            margin: [
                0.31, 0.28, 0.24, 0.34,
                0.27, 0.22, 0.30, 0.25
            ]
        }
    },
    rowGrouping: {
        enabled: true,
        groupBy: groupByOptions['region-segment']
    },
    rendering: {
        rows: {
            expandedLevels: 'all'
        }
    },
    columns: [{
        id: 'account',
        header: {
            format: 'Account'
        },
        width: 170
    }, {
        id: 'owner',
        header: {
            format: 'Owner'
        },
        width: 90
    }, {
        id: 'revenue',
        header: {
            format: 'Revenue'
        },
        cells: {
            format: '${value:,0f}'
        },
        rowAggregator: 'SUM'
    }, {
        id:...