Custom Cell Content

The FlexGrid control provides a powerful infrastructure for binding cells to data and formatting the cells using CSS, but in some cases that may not be enough. In those situations, use the formatItem event to customize the style or the content presented in each cell. The grid below uses formatItem to format cells with star ratings and sparklines.

Learn about FlexGrid | FlexGrid API Reference

import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjGrid from '@mescius/wijmo.grid'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // generate some data var data = [ { rank: 1, title: 'The Wizard of Oz', rating: 4, attendance: getArr(40), revenue: getArr(20) }, { rank: 2, title: 'Citizen Kane', rating: 5, attendance: getArr(40), revenue: getArr(20) }, { rank: 3, title: 'The Godfather', rating: 5, attendance: getArr(40), revenue: getArr(20) }, { rank: 4, title: 'Metropolis', rating: 4, attendance: getArr(40), revenue: getArr(20) }, { rank: 5, title: 'Singing\' in the Rain', rating: 2, attendance: getArr(40), revenue: getArr(20) }, { rank: 6, title: 'Casablanca', rating: 3, attendance: getArr(40), revenue: getArr(20) }, { rank: 7, title: 'Alien', rating: 5, attendance: getArr(40), revenue: getArr(20) }, { rank: 8, title: 'Vertigo', rating: 2, attendance: getArr(40), revenue: getArr(20) }, { rank: 9, title: 'Gone with the Wind', rating: 4, attendance: getArr(40), revenue: getArr(20) }, { rank: 10, title: 'Chinatown', rating: 2, attendance: getArr(40), revenue: getArr(20) } ]; function getArr(len) { var arr = []; for (var i = 0; i < len; i++) { arr.push(Math.round(Math.random() * 100)); } return arr; } // // column properties var theGrid = new wjGrid.FlexGrid('#theGrid', { isReadOnly: true, allowResizing: 'None', alternatingRowStep: 0, autoGenerateColumns: false, columns: [ { binding: 'rank', header: '#', width: 50 }, { binding: 'title', header: 'Title', width: '2*' }, { binding: 'rating', header: 'Rating', align: 'center', cssClass: 'cell-rating', width: '*' }, { binding: 'attendance', header: 'Attendance', cssClass: 'cell-attendance', width: '2*' }, { binding: 'revenue', header: 'Revenue', cssClass: 'cell-revenue', width: '2*' }, ], itemsSource: data, formatItem: function (s, e) { if (e.panel == s.cells) { var item = s.rows[e.row].dataItem; switch (s.columns[e.col].binding) { case 'rating': formatRatingCell(e.cell, item.rating); break; case 'attendance': formatAttendanceCell(e.cell, item.attendance); break; case 'revenue': formatRevenueCell(e.cell, item.revenue); break; } } } }); // function formatRatingCell(cell, rating) { var html = '<div aria-label="rating:' + rating + ' stars">'; for (var i = 0; i < rating; i++) { html += '<span class="glyphicon glyphicon-star"></span>'; } html += '</div>'; cell.innerHTML = html; } function formatAttendanceCell(cell, data) { cell.innerHTML = getSparklines(data); } function formatRevenueCell(cell, data) { cell.innerHTML = getSparkbars(data); } // // // generate sparklines as SVG function getSparklines(data) { var svg = '', min = Math.min.apply(Math, data), max = Math.max.apply(Math, data), x1 = 0, y1 = scaleY(data[0], min, max), x2, y2; for (var i = 1; i < data.length; i++) { x2 = Math.round((i) / (data.length - 1) * 100); y2 = scaleY(data[i], min, max); svg += '<line x1=' + x1 + '% y1=' + y1 + '% x2=' + x2 + '% y2=' + y2 + '% />'; x1 = x2; y1 = y2; } return wrapSvg(svg, 'sparklines'); } function getSparkbars(data) { var svg = '', min = Math.min.apply(Math, data), max = Math.max.apply(Math, data), base = Math.min(max, Math.max(min, 0)), basey = scaleY(base, min, max), w = Math.round(100 / data.length) - 2, x, y; for (var i = 0; i < data.length; i++) { x = i * Math.round(100 / data.length) + 1; y = scaleY(data[i], min, max); svg += '<rect x=' + x + '% width=' + w + '% y=' + Math.min(y, basey) + '% height=' + Math.abs(y - basey) + '% />'; } svg += '<rect x=0% width=100% height=1 y=' + basey + '% opacity=.5 />'; return wrapSvg(svg, 'sparkbars'); } // function scaleY(value, min, max) { return 100 - Math.round((value - min) / (max - min) * 100); } function wrapSvg(svg, title) { return '<div aria-label="' + title + '" ' + 'style="width:100%;height:100%;box-sizing:border-box;padding:4px">' + '<svg width="100%" height="100%" style="stroke:currentColor;"><g>' + svg + '</g></svg></div>'; } // }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid Sparklines</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"> <div id="theGrid"> </div> </div> </body> </html>
.wj-flexgrid { max-height: 250px; margin: 10px 0; } .cell-rating { color: gold; } .cell-attendance:not(.wj-state-selected):not(.wj-state-multi-selected), .cell-revenue:not(.wj-state-selected):not(.wj-state-multi-selected){ color: blue; } body { margin-bottom: 20px; }
(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);