Row Groups

This sample shows how you can create row groups by initializing the grid's rowGroups collection with an array of hierarchical elements where rows may have a rows property containing child rows.

The row groups may be collapsible and configured to show any of the child rows when the group is collapsed.

You can use CSS to animate the row groups as they expand or collapse.

Learn about FlexGrid | TransposedGrid API Reference

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import '@grapecity/wijmo.touch'; import { toggleClass } from '@grapecity/wijmo'; import { HeadersVisibility } from '@grapecity/wijmo.grid'; import { TransposedGrid } from '@grapecity/wijmo.grid.transposed'; import { getRowGroups, getDeeperRowGroups, getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // row grouping options let rowGroups1 = getRowGroups(), rowGroups2 = getDeeperRowGroups(); // create the grid with row groups let trnGrid = new TransposedGrid('#trnGrid', { alternatingRowStep: 0, showMarquee: true, showSelectedHeaders: HeadersVisibility.Row, autoGenerateRows: false, rowGroups: rowGroups1, itemsSource: getData() }); // toggle group definition document.getElementById('toggle').addEventListener('click', e => { trnGrid.rowGroups = trnGrid.rowGroups != rowGroups1 ? rowGroups1 : rowGroups2; }); // toggle row group collapse/expand animation document.getElementById('animated').addEventListener('click', e => { toggleClass(trnGrid.hostElement, 'animated', e.target.checked); }); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo TransposedGrid Row Groups</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <label> Collapse/Expand Animation <input id="animated" type="checkbox" checked="checked" /> </label> <button id="toggle" class="btn btn-primary"> Toggle Row Groups </button> <div id="trnGrid" class="animated"></div> </div> </body> </html>
// get an array with hierarchical row definitions // the 'rows' property of the objects contain child rows // the 'collapseTo' property specifies the binding of their child row that // should remain visible when the group is collapsed. export function getRowGroups() { const allocTemplate = '<span class=${value > .2 ? "big-val" : "small-val"}>${value}:${col.format}</span>'; const amountTemplate = '<span class=${value > 50000 ? "big-val" : "small-val"}>${value}:${col.format}</span>'; return [ { binding: 'name', header: 'Name', height: 50 }, { binding: 'currency', header: 'Curr', height: 50, align: 'center' }, { header: 'Perf', width: 100, align: 'center', collapseTo: 'perf.ytd', rows: [ { binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 80, cssClass: 'main-row' }, { binding: 'perf.m1', header: '1 M', format: 'p2', width: 60 }, { binding: 'perf.m6', header: '6 M', format: 'p2', width: 60 }, { binding: 'perf.m12', header: '12 M', format: 'p2', width: 60 }, ] }, { header: 'Allocation', width: 100, align: 'center', collapseTo: 'alloc.amount', rows: [ { binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80, cellTemplate: allocTemplate }, { binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80, cellTemplate: allocTemplate }, { binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80, cellTemplate: allocTemplate }, { binding: 'alloc.other', header: 'Other', format: 'p0', width: 80, cellTemplate: allocTemplate }, { binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 80, cssClass: 'main-row', cellTemplate: amountTemplate } ] } ]; } export function getDeeperRowGroups() { return [ { binding: 'name', header: 'Name', height: 50 }, { binding: 'currency', header: 'Curr', height: 50, align: 'center' }, { header: 'Allocation', width: 100, align: 'center', collapseTo: 'alloc.amount', rows: [ { binding: 'alloc.stock', header: 'Stocks', format: 'p0' }, { binding: 'alloc.bond', header: 'Bonds', format: 'p0' }, { header: 'Detail', width: 80, align: 'center', rows: [ { binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 60 }, { binding: 'alloc.other', header: 'Other', format: 'p0', width: 60 }, ] }, { binding: 'alloc.amount', header: 'Amount', format: 'c0', cssClassAll: 'highlight' }, ] }, { header: 'Perf', width: 100, align: 'center', rows: [ { header: 'Short', width: 80, align: 'center', collapseTo: 'perf.ytd', isCollapsed: true, rows: [ { binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 60, cssClassAll: 'highlight' }, { binding: 'perf.m1', header: '1 M', format: 'p2', width: 60 }, ] }, { header: 'Long', width: 80, align: 'center', collapseTo: 'perf.m12', isCollapsed: true, rows: [ { binding: 'perf.m6', header: '6 M', format: 'p2', width: 60 }, { binding: 'perf.m12', header: '12 M', format: 'p2', width: 60, cssClassAll: 'highlight' } ] }, ] }, ]; } // get some sample data export function getData() { return [{ name: 'Constant Growth', currency: 'USD', perf: { ytd: .0523, m1: 0.0142, m6: 0.0443, m12: 0.0743 }, alloc: { stock: 0.17, bond: 0.32, cash: 0.36, other: 0.15, amount: 23432 } }, { name: 'Optimus Prime', currency: 'EUR', perf: { ytd: .0343, m1: 0.043, m6: 0.0244, m12: 0.0543 }, alloc: { stock: 0.61, bond: 0.8, cash: 0.9, other: 0.22, amount: 43223 } }, { name: 'Crypto Planet', currency: 'BTC', perf: { ytd: .0343, m1: 0.014, m6: 0.034, m12: 0.01243 }, alloc: { stock: 0.1, bond: 0, cash: 0, other: 0.9, amount: 2234 } }, { name: 'MegaZone', currency: 'EUR', perf: { ytd: .0443, m1: 0.034, m6: 0.0424, m12: 0.0343 }, alloc: { stock: 0.51, bond: 0.9, cash: 0.8, other: 0.12, amount: 32234 } }, { name: 'Serenity', currency: 'YEN', perf: { ytd: .0522, m1: 0.0143, m6: 0.0458, m12: 0.0732 }, alloc: { stock: 0.66, bond: 0.09, cash: 0.19, other: 0.06, amount: 65624 } }]; }
label { display: block; } .wj-transposed-grid { margin: 10px 0; } /* highlight the main row in the group */ .wj-flexgrid .wj-cells .wj-cell.main-row:not(.wj-state-selected):not(.wj-state-multi-selected) { background: #e3f4ff; } /* some conditional formatting */ .big-val { font-weight: bold; color: darkgreen; } .small-val { font-style: italic; color: rgb(202, 0, 0); } /* some animation when collapsing/expanding the groups */ .wj-flexgrid.animated .wj-rowheaders .wj-header.wj-cell.wj-colgroup { transition: all .2s; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.js', '@grapecity/wijmo': 'npm:@grapecity/wijmo/index.js', '@grapecity/wijmo.input': 'npm:@grapecity/wijmo.input/index.js', '@grapecity/wijmo.styles': 'npm:@grapecity/wijmo.styles', '@grapecity/wijmo.cultures': 'npm:@grapecity/wijmo.cultures', '@grapecity/wijmo.chart': 'npm:@grapecity/wijmo.chart/index.js', '@grapecity/wijmo.chart.analytics': 'npm:@grapecity/wijmo.chart.analytics/index.js', '@grapecity/wijmo.chart.animation': 'npm:@grapecity/wijmo.chart.animation/index.js', '@grapecity/wijmo.chart.annotation': 'npm:@grapecity/wijmo.chart.annotation/index.js', '@grapecity/wijmo.chart.finance': 'npm:@grapecity/wijmo.chart.finance/index.js', '@grapecity/wijmo.chart.finance.analytics': 'npm:@grapecity/wijmo.chart.finance.analytics/index.js', '@grapecity/wijmo.chart.hierarchical': 'npm:@grapecity/wijmo.chart.hierarchical/index.js', '@grapecity/wijmo.chart.interaction': 'npm:@grapecity/wijmo.chart.interaction/index.js', '@grapecity/wijmo.chart.radar': 'npm:@grapecity/wijmo.chart.radar/index.js', '@grapecity/wijmo.chart.render': 'npm:@grapecity/wijmo.chart.render/index.js', '@grapecity/wijmo.chart.webgl': 'npm:@grapecity/wijmo.chart.webgl/index.js', '@grapecity/wijmo.chart.map': 'npm:@grapecity/wijmo.chart.map/index.js', '@grapecity/wijmo.gauge': 'npm:@grapecity/wijmo.gauge/index.js', '@grapecity/wijmo.grid': 'npm:@grapecity/wijmo.grid/index.js', '@grapecity/wijmo.grid.detail': 'npm:@grapecity/wijmo.grid.detail/index.js', '@grapecity/wijmo.grid.filter': 'npm:@grapecity/wijmo.grid.filter/index.js', '@grapecity/wijmo.grid.search': 'npm:@grapecity/wijmo.grid.search/index.js', '@grapecity/wijmo.grid.grouppanel': 'npm:@grapecity/wijmo.grid.grouppanel/index.js', '@grapecity/wijmo.grid.multirow': 'npm:@grapecity/wijmo.grid.multirow/index.js', '@grapecity/wijmo.grid.transposed': 'npm:@grapecity/wijmo.grid.transposed/index.js', '@grapecity/wijmo.grid.transposedmultirow': 'npm:@grapecity/wijmo.grid.transposedmultirow/index.js', '@grapecity/wijmo.grid.pdf': 'npm:@grapecity/wijmo.grid.pdf/index.js', '@grapecity/wijmo.grid.sheet': 'npm:@grapecity/wijmo.grid.sheet/index.js', '@grapecity/wijmo.grid.xlsx': 'npm:@grapecity/wijmo.grid.xlsx/index.js', '@grapecity/wijmo.grid.selector': 'npm:@grapecity/wijmo.grid.selector/index.js', '@grapecity/wijmo.grid.cellmaker': 'npm:@grapecity/wijmo.grid.cellmaker/index.js', '@grapecity/wijmo.nav': 'npm:@grapecity/wijmo.nav/index.js', '@grapecity/wijmo.odata': 'npm:@grapecity/wijmo.odata/index.js', '@grapecity/wijmo.olap': 'npm:@grapecity/wijmo.olap/index.js', '@grapecity/wijmo.rest': 'npm:@grapecity/wijmo.rest/index.js', '@grapecity/wijmo.pdf': 'npm:@grapecity/wijmo.pdf/index.js', '@grapecity/wijmo.pdf.security': 'npm:@grapecity/wijmo.pdf.security/index.js', '@grapecity/wijmo.viewer': 'npm:@grapecity/wijmo.viewer/index.js', '@grapecity/wijmo.xlsx': 'npm:@grapecity/wijmo.xlsx/index.js', '@grapecity/wijmo.undo': 'npm:@grapecity/wijmo.undo/index.js', '@grapecity/wijmo.interop.grid': 'npm:@grapecity/wijmo.interop.grid/index.js', '@grapecity/wijmo.touch': 'npm:@grapecity/wijmo.touch/index.js', '@grapecity/wijmo.cloud': 'npm:@grapecity/wijmo.cloud/index.js', '@grapecity/wijmo.barcode': 'npm:@grapecity/wijmo.barcode/index.js', '@grapecity/wijmo.barcode.common': 'npm:@grapecity/wijmo.barcode.common/index.js', '@grapecity/wijmo.barcode.composite': 'npm:@grapecity/wijmo.barcode.composite/index.js', '@grapecity/wijmo.barcode.specialized': 'npm:@grapecity/wijmo.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);