Column Groups (Object Model)

In addition to the possibility to define grid's columnGroups property using a POJO array, you can use reactive ColumnGroupCollection of ColumnGroup objects for this purpose. In frameworks, you can use corresponding components in framework templates, along with cell templates defining cells and group headers content.

This object model gives you a possibility to change group properties and to restructure the groups tree without recreating the whole tree.

Learn about FlexGrid | FlexGrid API Reference

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo-core.css'; import './styles.css'; import { FlexGrid, ColumnGroup, ColumnGroupCollection } from '@grapecity/wijmo.grid'; import { toggleClass } from '@grapecity/wijmo'; import * as DataService from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { let theGrid = new FlexGrid('#theGrid', { headersVisibility: 'Column', alternatingRowStep: 0, showMarquee: true, showSelectedHeaders: 'All', autoGenerateColumns: false, columnGroups: new ColumnGroupCollection([ new ColumnGroup({ binding: 'name', header: 'Name', width: 150 }), new ColumnGroup({ binding: 'currency', header: 'Curr', width: 80, align: 'center' }), new ColumnGroup({ header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80 }), new ColumnGroup({ binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80 }), new ColumnGroup({ header: 'Detail', align: 'center', columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80 }), new ColumnGroup({ binding: 'alloc.other', header: 'Other', format: 'p0', width: 80 }), ]) }), new ColumnGroup({ binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 100, cssClass: 'main-column' }), ]) }), new ColumnGroup({ header: 'Perf', align: 'center', columns: new ColumnGroupCollection([ new ColumnGroup({ header: 'Short', align: 'center', collapseTo: 'perf.ytd', isCollapsed: true, columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClass: 'main-column' }), new ColumnGroup({ binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 }), ]) }), new ColumnGroup({ header: 'Long', align: 'center', collapseTo: 'perf.m12', isCollapsed: true, columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 }), new ColumnGroup({ binding: 'perf.m12', header: '12 M', format: 'p2', width: 100, cssClassAll: 'main-column' }), ]) }), ]) }), ]), itemsSource: DataService.getData(), }); // init collapse/expand animation checkbox const setAnimation = (animated) => { toggleClass(theGrid.hostElement, 'animated', animated); }; const animChk = document.getElementById('animated'); animChk.addEventListener('click', e => setAnimation(e.target.checked)); animChk.checked = true; setAnimation(animChk.checked); // init use cell templates checkbox const setUseTemplates = (useTemplates) => { const cellTemplate = useTemplates ? cell => { const grid = cell.row.grid; const rowIdx = cell.row.index; const colIdx = cell.col.index; const cssClass = grid.getCellData(rowIdx, colIdx, false) > .2 ? 'big-val' : 'small-val'; const value = grid.getCellData(rowIdx, colIdx, true); return `<span class="${cssClass}">${value}</span>`; } : null; theGrid.getColumn('alloc.stock').cellTemplate = cellTemplate; theGrid.getColumn('alloc.bond').cellTemplate = cellTemplate; theGrid.getColumn('alloc.cash').cellTemplate = cellTemplate; theGrid.getColumn('alloc.other').cellTemplate = cellTemplate; }; const tplChk = document.getElementById('templates'); tplChk.addEventListener('click', e => setUseTemplates(e.target.checked)); tplChk.checked = true; setUseTemplates(tplChk.checked); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid Column Groups with Templates</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" /> </label> <label> Use cell templates <input id="templates" type="checkbox" /> </label> <div id="theGrid" /> </div> </body> </html>
// 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-flexgrid { margin: 10px 0; } /* highlight the main column in the group */ .wj-flexgrid .wj-cells .wj-cell.main-column { 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-colheaders .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);