DevExtreme v24.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Angular Data Grid - Group Summaries

To configure group summaries, populate the summary.groupItems array with summary configuration objects. Each object should specify a column that supplies data for summary calculation and a summaryType—an aggregate function that should be applied to this data.

Backend API
<dx-data-grid id="gridContainer" [dataSource]="orders" keyExpr="ID" [showBorders]="true" > <dxo-selection mode="single"></dxo-selection> <dxo-pager [visible]="true"></dxo-pager> <dxi-column dataField="OrderNumber" [width]="130" caption="Invoice Number" ></dxi-column> <dxi-column dataField="OrderDate" dataType="date"></dxi-column> <dxi-column dataField="Employee" [groupIndex]="0"></dxi-column> <dxi-column dataField="CustomerStoreCity" caption="City"></dxi-column> <dxi-column dataField="CustomerStoreState" caption="State"></dxi-column> <dxi-column dataField="SaleAmount" alignment="right" format="currency" [width]="160" ></dxi-column> <dxi-column dataField="TotalAmount" alignment="right" format="currency" [width]="160" ></dxi-column> <dxo-summary> <dxi-group-item column="OrderNumber" summaryType="count" displayFormat="{0} orders" > </dxi-group-item> <dxi-group-item column="SaleAmount" summaryType="max" valueFormat="currency" [showInGroupFooter]="false" [alignByColumn]="true" > </dxi-group-item> <dxi-group-item column="TotalAmount" summaryType="max" valueFormat="currency" [showInGroupFooter]="false" [alignByColumn]="true" > </dxi-group-item> <dxi-group-item column="TotalAmount" summaryType="sum" valueFormat="currency" displayFormat="Total: {0}" [showInGroupFooter]="true" > </dxi-group-item> </dxo-summary> <dxi-sort-by-group-summary-info summaryItem="count" ></dxi-sort-by-group-summary-info> </dx-data-grid>
import { NgModule, Component, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { DxDataGridModule } from 'devextreme-angular'; import { Order, Service } from './app.service'; if (!/localhost/.test(document.location.host)) { enableProdMode(); } @Component({ selector: 'demo-app', templateUrl: `app/app.component.html`, styleUrls: [`app/app.component.css`], providers: [Service], }) export class AppComponent { orders: Order[]; constructor(private service: Service) { this.orders = service.getOrders(); } } @NgModule({ imports: [ BrowserModule, DxDataGridModule, ], declarations: [AppComponent], bootstrap: [AppComponent], }) export class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule);
::ng-deep #gridContainer { height: 440px; }
import { Injectable } from '@angular/core'; export class Order { ID: number; OrderNumber: number; OrderDate: string; SaleAmount: number; TotalAmount: number; Terms: string; CustomerStoreState: string; CustomerStoreCity: string; Employee: string; } const orders: Order[] = [{ ID: 1, OrderNumber: 35703, OrderDate: '2014-04-10', SaleAmount: 11800, Terms: '15 Days', TotalAmount: 12175, CustomerStoreState: 'California', CustomerStoreCity: 'Los Angeles', Employee: 'Harv Mudd', }, { ID: 4, OrderNumber: 35711, OrderDate: '2014-01-12', SaleAmount: 16050, Terms: '15 Days', TotalAmount: 16550, CustomerStoreState: 'California', CustomerStoreCity: 'San Jose', Employee: 'Jim Packard', }, { ID: 5, OrderNumber: 35714, OrderDate: '2014-01-22', SaleAmount: 14750, Terms: '15 Days', TotalAmount: 15250, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 7, OrderNumber: 35983, OrderDate: '2014-02-07', SaleAmount: 3725, Terms: '15 Days', TotalAmount: 3850, CustomerStoreState: 'Colorado', CustomerStoreCity: 'Denver', Employee: 'Todd Hoffman', }, { ID: 9, OrderNumber: 36987, OrderDate: '2014-03-11', SaleAmount: 14200, Terms: '15 Days', TotalAmount: 14800, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 11, OrderNumber: 38466, OrderDate: '2014-03-01', SaleAmount: 7800, Terms: '15 Days', TotalAmount: 8200, CustomerStoreState: 'California', CustomerStoreCity: 'Los Angeles', Employee: 'Harv Mudd', }, { ID: 15, OrderNumber: 39874, OrderDate: '2014-02-04', SaleAmount: 9050, Terms: '30 Days', TotalAmount: 19100, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 18, OrderNumber: 42847, OrderDate: '2014-02-15', SaleAmount: 20400, Terms: '30 Days', TotalAmount: 20800, CustomerStoreState: 'Wyoming', CustomerStoreCity: 'Casper', Employee: 'Todd Hoffman', }, { ID: 19, OrderNumber: 43982, OrderDate: '2014-05-29', SaleAmount: 6050, Terms: '30 Days', TotalAmount: 6250, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 29, OrderNumber: 56272, OrderDate: '2014-02-06', SaleAmount: 15850, Terms: '30 Days', TotalAmount: 16350, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 30, OrderNumber: 57429, OrderDate: '2013-12-31', SaleAmount: 11050, Terms: '30 Days', TotalAmount: 11400, CustomerStoreState: 'Arizona', CustomerStoreCity: 'Phoenix', Employee: 'Clark Morgan', }, { ID: 32, OrderNumber: 58292, OrderDate: '2014-05-13', SaleAmount: 13500, Terms: '15 Days', TotalAmount: 13800, CustomerStoreState: 'California', CustomerStoreCity: 'Los Angeles', Employee: 'Harv Mudd', }, { ID: 36, OrderNumber: 62427, OrderDate: '2014-01-27', SaleAmount: 23500, Terms: '15 Days', TotalAmount: 24000, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 39, OrderNumber: 65977, OrderDate: '2014-02-05', SaleAmount: 2550, Terms: '15 Days', TotalAmount: 2625, CustomerStoreState: 'Wyoming', CustomerStoreCity: 'Casper', Employee: 'Todd Hoffman', }, { ID: 40, OrderNumber: 66947, OrderDate: '2014-03-23', SaleAmount: 3500, Terms: '15 Days', TotalAmount: 3600, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 42, OrderNumber: 68428, OrderDate: '2014-04-10', SaleAmount: 10500, Terms: '15 Days', TotalAmount: 10900, CustomerStoreState: 'California', CustomerStoreCity: 'Los Angeles', Employee: 'Harv Mudd', }, { ID: 43, OrderNumber: 69477, OrderDate: '2014-03-09', SaleAmount: 14200, Terms: '15 Days', TotalAmount: 14500, CustomerStoreState: 'California', CustomerStoreCity: 'Anaheim', Employee: 'Harv Mudd', }, { ID: 46, OrderNumber: 72947, OrderDate: '2014-01-14', SaleAmount: 13350, Terms: '30 Days', TotalAmount: 13650, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 47, OrderNumber: 73088, OrderDate: '2014-03-25', SaleAmount: 8600, Terms: '30 Days', TotalAmount: 8850, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Reno', Employee: 'Clark Morgan', }, { ID: 50, OrderNumber: 76927, OrderDate: '2014-04-27', SaleAmount: 9800, Terms: '30 Days', TotalAmount: 10050, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 51, OrderNumber: 77297, OrderDate: '2014-04-30', SaleAmount: 10850, Terms: '30 Days', TotalAmount: 11100, CustomerStoreState: 'Arizona', CustomerStoreCity: 'Phoenix', Employee: 'Clark Morgan', }, { ID: 56, OrderNumber: 84744, OrderDate: '2014-02-10', SaleAmount: 4650, Terms: '30 Days', TotalAmount: 4750, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 57, OrderNumber: 85028, OrderDate: '2014-05-17', SaleAmount: 2575, Terms: '30 Days', TotalAmount: 2625, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Reno', Employee: 'Clark Morgan', }, { ID: 59, OrderNumber: 87297, OrderDate: '2014-04-21', SaleAmount: 14200, Terms: '30 Days', TotalAmount: 0, CustomerStoreState: 'Wyoming', CustomerStoreCity: 'Casper', Employee: 'Todd Hoffman', }, { ID: 60, OrderNumber: 88027, OrderDate: '2014-02-14', SaleAmount: 13650, Terms: '30 Days', TotalAmount: 14050, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 65, OrderNumber: 94726, OrderDate: '2014-05-22', SaleAmount: 20500, Terms: '15 Days', TotalAmount: 20800, CustomerStoreState: 'California', CustomerStoreCity: 'San Jose', Employee: 'Jim Packard', }, { ID: 66, OrderNumber: 95266, OrderDate: '2014-03-10', SaleAmount: 9050, Terms: '15 Days', TotalAmount: 9250, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 69, OrderNumber: 98477, OrderDate: '2014-01-01', SaleAmount: 23500, Terms: '15 Days', TotalAmount: 23800, CustomerStoreState: 'Wyoming', CustomerStoreCity: 'Casper', Employee: 'Todd Hoffman', }, { ID: 70, OrderNumber: 99247, OrderDate: '2014-02-08', SaleAmount: 2100, Terms: '15 Days', TotalAmount: 2150, CustomerStoreState: 'Utah', CustomerStoreCity: 'Salt Lake City', Employee: 'Clark Morgan', }, { ID: 78, OrderNumber: 174884, OrderDate: '2014-04-10', SaleAmount: 7200, Terms: '30 Days', TotalAmount: 7350, CustomerStoreState: 'Colorado', CustomerStoreCity: 'Denver', Employee: 'Todd Hoffman', }, { ID: 81, OrderNumber: 188877, OrderDate: '2014-02-11', SaleAmount: 8750, Terms: '30 Days', TotalAmount: 8900, CustomerStoreState: 'Arizona', CustomerStoreCity: 'Phoenix', Employee: 'Clark Morgan', }, { ID: 82, OrderNumber: 191883, OrderDate: '2014-02-05', SaleAmount: 9900, Terms: '30 Days', TotalAmount: 10150, CustomerStoreState: 'California', CustomerStoreCity: 'Los Angeles', Employee: 'Harv Mudd', }, { ID: 83, OrderNumber: 192474, OrderDate: '2014-01-21', SaleAmount: 12800, Terms: '30 Days', TotalAmount: 13100, CustomerStoreState: 'California', CustomerStoreCity: 'Anaheim', Employee: 'Harv Mudd', }, { ID: 84, OrderNumber: 193847, OrderDate: '2014-03-21', SaleAmount: 14100, Terms: '30 Days', TotalAmount: 14350, CustomerStoreState: 'California', CustomerStoreCity: 'San Diego', Employee: 'Harv Mudd', }, { ID: 85, OrderNumber: 194877, OrderDate: '2014-03-06', SaleAmount: 4750, Terms: '30 Days', TotalAmount: 4950, CustomerStoreState: 'California', CustomerStoreCity: 'San Jose', Employee: 'Jim Packard', }, { ID: 86, OrderNumber: 195746, OrderDate: '2014-05-26', SaleAmount: 9050, Terms: '30 Days', TotalAmount: 9250, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Las Vegas', Employee: 'Harv Mudd', }, { ID: 87, OrderNumber: 197474, OrderDate: '2014-03-02', SaleAmount: 6400, Terms: '30 Days', TotalAmount: 6600, CustomerStoreState: 'Nevada', CustomerStoreCity: 'Reno', Employee: 'Clark Morgan', }, { ID: 88, OrderNumber: 198746, OrderDate: '2014-05-09', SaleAmount: 15700, Terms: '30 Days', TotalAmount: 16050, CustomerStoreState: 'Colorado', CustomerStoreCity: 'Denver', Employee: 'Todd Hoffman', }, { ID: 91, OrderNumber: 214222, OrderDate: '2014-02-08', SaleAmount: 11050, Terms: '30 Days', TotalAmount: 11250, CustomerStoreState: 'Arizona', CustomerStoreCity: 'Phoenix', Employee: 'Clark Morgan', }]; @Injectable() export class Service { getOrders() { return orders; } }
// In real applications, you should not transpile code in the browser. // You can see how to create your own application with Angular and DevExtreme here: // https://js.devexpress.com/Documentation/Guide/Angular_Components/Getting_Started/Create_a_DevExtreme_Application/ const componentNames = [ 'accordion', 'action-sheet', 'autocomplete', 'bar-gauge', 'box', 'bullet', 'button-group', 'button', 'calendar', 'chart', 'check-box', 'circular-gauge', 'color-box', 'context-menu', 'data-grid', 'date-box', 'date-range-box', 'defer-rendering', 'diagram', 'draggable', 'drawer', 'drop-down-box', 'drop-down-button', 'file-manager', 'file-uploader', 'filter-builder', 'form', 'funnel', 'gallery', 'gantt', 'html-editor', 'linear-gauge', 'list', 'load-indicator', 'load-panel', 'lookup', 'map', 'menu', 'multi-view', 'nested', 'number-box', 'pie-chart', 'pivot-grid-field-chooser', 'pivot-grid', 'polar-chart', 'popover', 'popup', 'progress-bar', 'radio-group', 'range-selector', 'range-slider', 'recurrence-editor', 'resizable', 'responsive-box', 'sankey', 'scheduler', 'scroll-view', 'select-box', 'slider', 'sortable', 'sparkline', 'speed-dial-action', 'splitter', 'switch', 'tab-panel', 'tabs', 'tag-box', 'text-area', 'text-box', 'tile-view', 'toast', 'toolbar', 'tooltip', 'tree-list', 'tree-map', 'tree-view', 'validation-group', 'validation-summary', 'validator', 'vector-map', ]; window.exports = window.exports || {}; window.config = { transpiler: 'ts', typescriptOptions: { module: 'system', emitDecoratorMetadata: true, experimentalDecorators: true, }, meta: { 'typescript': { 'exports': 'ts', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, '@angular/platform-browser-dynamic': { 'esModule': true, }, '@angular/platform-browser': { 'esModule': true, }, '@angular/core': { 'esModule': true, }, '@angular/common': { 'esModule': true, }, '@angular/common/http': { 'esModule': true, }, '@angular/compiler': { 'esModule': true, }, '@angular/animations': { 'esModule': true, }, '@angular/forms': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', 'bundles:': '../../../../bundles/', }, map: { 'ts': 'npm:plugin-typescript@4.2.4/lib/plugin.js', 'typescript': 'npm:typescript@4.2.4/lib/typescript.js', /* @angular */ '@angular/compiler': 'bundles:@angular/compiler.umd.js', '@angular/platform-browser-dynamic': 'bundles:@angular/platform-browser-dynamic.umd.js', '@angular/core': 'bundles:@angular/core.umd.js', '@angular/core/primitives/signals': 'bundles:@angular/core.primitives.signals.umd.js', '@angular/common': 'bundles:@angular/common.umd.js', '@angular/common/http': 'bundles:@angular/common-http.umd.js', '@angular/platform-browser': 'bundles:@angular/platform-browser.umd.js', '@angular/platform-browser/animations': 'bundles:@angular/platform-browser.umd.js', '@angular/forms': 'bundles:@angular/forms.umd.js', /* devextreme */ 'devextreme': 'npm:devextreme@24.1.7/cjs', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.13', 'devextreme/bundles/dx.all': 'npm:devextreme@24.1.7/bundles/dx.all.js', 'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.13', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.56', /* devextreme-angular umd maps */ 'devextreme-angular': 'bundles:devextreme-angular/devextreme-angular.umd.js', 'devextreme-angular/core': 'bundles:devextreme-angular/devextreme-angular-core.umd.js', 'devextreme-angular/http': 'bundles:devextreme-angular/devextreme-angular-http.umd.js', ...componentNames.reduce((acc, name) => { acc[`devextreme-angular/ui/${name}`] = `bundles:devextreme-angular/devextreme-angular-ui-${name}.umd.js`; return acc; }, {}), 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'tslib': 'npm:tslib@2.6.1/tslib.js', 'rxjs': 'npm:rxjs@7.5.3/dist/bundles/rxjs.umd.js', 'rxjs/operators': 'npm:rxjs@7.5.3/dist/cjs/operators/index.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', // Prettier 'prettier/standalone': 'npm:prettier@2.8.8/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js', }, packages: { 'app': { main: './app.component.ts', defaultExtension: 'ts', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, 'rxjs': { defaultExtension: 'js', }, 'rxjs/operators': { defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.13/inferno/package.json', 'npm:rxjs@7.5.3/package.json', 'npm:rxjs@7.5.3/operators/package.json', 'npm:devexpress-diagram@2.2.13/package.json', 'npm:devexpress-gantt@4.1.56/package.json', ], }; System.config(window.config); // System.import('@angular/compiler').catch(console.error.bind(console));
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.1.7/css/dx.light.css" /> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.13.3/bundles/zone.umd.min.js"></script> <script src="https://unpkg.com/reflect-metadata@0.1.13/Reflect.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script src="config.js"></script> <script> System.import("app").catch(console.error.bind(console)); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> </body> </html>

Position a Group Summary

Group summaries are displayed in parentheses after the group caption. You can reposition them as follows:

  • Display a summary in a column
    You can align a summary to its corresponding column (see the Sale Amount and Total Amount columns). To do this, enable the alignByColumn property. If you want to align a summary to a different column, specify the showInColumn property.

  • Display Summary Values within Group Footers
    You can make a summary item display its values within group footers. To do this, enable the showInGroupFooter property. Summary items will appear within their corresponding columns (see the Total Amount column). If you want to display summaries in another column, specify the showInColumn property.

Format Summary Values

To format summary values, use the valueFormat property. This demo applies the "currency" format to summary values calculated against the Total Amount and Sale Amount columns. If you also want to add custom text to summary values, use the displayFormat property. This demo sets this property for summaries of "sum" and "count" types.

Sort Groups by Summary Values

This demo sorts groups by summary values (the number of orders). To do this, the code adds an object to the sortByGroupSummaryInfo array. The object specifies the summaryItem whose values are used to sort the group rows.