Column Groups

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

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

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

Learn about FlexGrid | FlexGrid API Reference

import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo-core.css'; import './styles.css'; import { FlexGrid } from '@mescius/wijmo.grid'; import { toggleClass } from '@mescius/wijmo'; import * as DataService from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // column grouping options let colGroups1 = DataService.getColumnGroups(), colGroups2 = DataService.getDeeperColumnGroups(); // create the grid with column groups let theGrid = new FlexGrid('#theGrid', { headersVisibility: 'Column', alternatingRowStep: 0, showMarquee: true, showSelectedHeaders: 'All', autoGenerateColumns: false, columnGroups: colGroups1, itemsSource: DataService.getData() }); // toggle group definition document.getElementById('toggle').addEventListener('click', e => { theGrid.columnGroups = theGrid.columnGroups != colGroups1 ? colGroups1 : colGroups2; }); // toggle column collapse/expand animation document.getElementById('animated').addEventListener('click', e => { toggleClass(theGrid.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>MESCIUS Wijmo FlexGrid Column Groups</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.5/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></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 Column Groups </button> <div id="theGrid" class="animated"></div> </div> </body> </html>
// get an array with hierarchical column definitions // the 'columns' property of the objects contain child columns // the 'collapseTo' property specifies the binding of thei child column that // should remain visible when the group is collapsed. import * as wijmo from '@mescius/wijmo'; export function getColumnGroups() { const allocTemplate = (ctx) => (`<span class=${ctx.value > .2 ? "big-val" : "small-val"}> ${wijmo.Globalize.format(ctx.value, ctx.col.format)} </span>`); const amountTemplate = (ctx) => (`<span class=${ctx.value > 50000 ? "big-val" : "small-val"}> ${wijmo.Globalize.format(ctx.value, ctx.col.format)}</span>`); return [ { binding: 'name', header: 'Name', width: 150 }, { binding: 'currency', header: 'Curr', width: 80, align: 'center' }, { header: 'Perf', align: 'center', collapseTo: 'perf.ytd', columns: [ { binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClass: 'main-column' }, { binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 }, { binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 }, { binding: 'perf.m12', header: '12 M', format: 'p2', width: 80 }, ] }, { header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: [ { 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: 100, cssClass: 'main-column', cellTemplate: amountTemplate } ] } ]; } // slightly different column groups export function getDeeperColumnGroups() { return [ { binding: 'name', header: 'Name', width: 150 }, { binding: 'currency', header: 'Curr', width: 80, align: 'center' }, { header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: [ { binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80 }, { binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80 }, { header: 'Detail', align: 'center', columns: [ { binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80 }, { binding: 'alloc.other', header: 'Other', format: 'p0', width: 80 }, ] }, { binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 100, cssClassAll: 'main-column' }, ] }, { header: 'Perf', align: 'center', columns: [ { header: 'Short', align: 'center', collapseTo: 'perf.ytd', isCollapsed: true, columns: [ { binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClassAll: 'main-column' }, { binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 }, ] }, { header: 'Long', align: 'center', collapseTo: 'perf.m12', isCollapsed: true, columns: [ { binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 }, { binding: 'perf.m12', header: '12 M', format: 'p2', width: 100, cssClassAll: 'main-column' } ] }, ] }, ]; } // 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', '@mescius/wijmo': 'npm:@mescius/wijmo/index.js', '@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js', '@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles', '@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures', '@mescius/wijmo.chart': 'npm:@mescius/wijmo.chart/index.js', '@mescius/wijmo.chart.analytics': 'npm:@mescius/wijmo.chart.analytics/index.js', '@mescius/wijmo.chart.animation': 'npm:@mescius/wijmo.chart.animation/index.js', '@mescius/wijmo.chart.annotation': 'npm:@mescius/wijmo.chart.annotation/index.js', '@mescius/wijmo.chart.finance': 'npm:@mescius/wijmo.chart.finance/index.js', '@mescius/wijmo.chart.finance.analytics': 'npm:@mescius/wijmo.chart.finance.analytics/index.js', '@mescius/wijmo.chart.hierarchical': 'npm:@mescius/wijmo.chart.hierarchical/index.js', '@mescius/wijmo.chart.interaction': 'npm:@mescius/wijmo.chart.interaction/index.js', '@mescius/wijmo.chart.radar': 'npm:@mescius/wijmo.chart.radar/index.js', '@mescius/wijmo.chart.render': 'npm:@mescius/wijmo.chart.render/index.js', '@mescius/wijmo.chart.webgl': 'npm:@mescius/wijmo.chart.webgl/index.js', '@mescius/wijmo.chart.map': 'npm:@mescius/wijmo.chart.map/index.js', '@mescius/wijmo.gauge': 'npm:@mescius/wijmo.gauge/index.js', '@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js', '@mescius/wijmo.grid.detail': 'npm:@mescius/wijmo.grid.detail/index.js', '@mescius/wijmo.grid.filter': 'npm:@mescius/wijmo.grid.filter/index.js', '@mescius/wijmo.grid.search': 'npm:@mescius/wijmo.grid.search/index.js', '@mescius/wijmo.grid.style': 'npm:@mescius/wijmo.grid.style/index.js', '@mescius/wijmo.grid.grouppanel': 'npm:@mescius/wijmo.grid.grouppanel/index.js', '@mescius/wijmo.grid.multirow': 'npm:@mescius/wijmo.grid.multirow/index.js', '@mescius/wijmo.grid.transposed': 'npm:@mescius/wijmo.grid.transposed/index.js', '@mescius/wijmo.grid.transposedmultirow': 'npm:@mescius/wijmo.grid.transposedmultirow/index.js', '@mescius/wijmo.grid.pdf': 'npm:@mescius/wijmo.grid.pdf/index.js', '@mescius/wijmo.grid.sheet': 'npm:@mescius/wijmo.grid.sheet/index.js', '@mescius/wijmo.grid.xlsx': 'npm:@mescius/wijmo.grid.xlsx/index.js', '@mescius/wijmo.grid.selector': 'npm:@mescius/wijmo.grid.selector/index.js', '@mescius/wijmo.grid.cellmaker': 'npm:@mescius/wijmo.grid.cellmaker/index.js', '@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js', '@mescius/wijmo.odata': 'npm:@mescius/wijmo.odata/index.js', '@mescius/wijmo.olap': 'npm:@mescius/wijmo.olap/index.js', '@mescius/wijmo.rest': 'npm:@mescius/wijmo.rest/index.js', '@mescius/wijmo.pdf': 'npm:@mescius/wijmo.pdf/index.js', '@mescius/wijmo.pdf.security': 'npm:@mescius/wijmo.pdf.security/index.js', '@mescius/wijmo.viewer': 'npm:@mescius/wijmo.viewer/index.js', '@mescius/wijmo.xlsx': 'npm:@mescius/wijmo.xlsx/index.js', '@mescius/wijmo.undo': 'npm:@mescius/wijmo.undo/index.js', '@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js', '@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js', '@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/index.js', '@mescius/wijmo.barcode': 'npm:@mescius/wijmo.barcode/index.js', '@mescius/wijmo.barcode.common': 'npm:@mescius/wijmo.barcode.common/index.js', '@mescius/wijmo.barcode.composite': 'npm:@mescius/wijmo.barcode.composite/index.js', '@mescius/wijmo.barcode.specialized': 'npm:@mescius/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);