How to Add a Chart to your JavaScript Data Grid
Data grids are great for showing and editing data. They allow you to edit, organize, inspect, and change the data. Charts are a great way to visualize data. They allow you to see trends and make comparisons instantly.
FlexGrid allows you to combine charts and data grids into a single view. This provides users with the best of both worlds. Simply use the grid's formatItem event to add bars to the grid cells.
Let's illustrate with an example:
https://jsfiddle.net/Wijmo5/3xv4w76o/
The fiddle listed above creates a groupable, sortable, editable grid that includes two bar charts:
The chart allows users to instantly see the magnitude of the sales and revenue for each product. As users scroll through the grid, the bars will automatically highlight products and periods with especially high or low sales and revenue.
Let us walk through the steps required to create this application.
Load the Data
Our application loads data from a Google Sheets document. The data is served in CSV format and is easy to update. Here is the code used to retrieve it:
// create the data source
var view = new wijmo.collections.CollectionView();
var url = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vRVhwWiWkXp_dqlf8jOSEJlP5DFGTAFwqYJdOweZ4WGJlBsMrcFW_-48eZVCoXMHdNxqFv1CMQXGinq/pub?gid=351800917&single=true&output=csv';
wijmo.httpRequest(url, {
success: function(xhr) {
view.sourceCollection = parseCsv(xhr.responseText);
}
});
The code creates a CollectionView and makes a request to load the CSV data. When the data arrives, the code parses it and assigns the resulting data array to the CollectionView's sourceCollection property.
The long URL contains a reference to the specific Google Sheets document that contains the data. This sheet was created in Google Sheets and shared as CSV.
We used a CollectionView instead of a simple JavaScript array because we want to group the data.
Create the Grid
Once we have the data, we create a grid to show it.
Here is the code that creates and initializes the grid:
// create and configure the grid
var theGrid = new wijmo.grid.FlexGrid('#theGrid', {
showAlternatingRows: false,
autoGenerateColumns: false,
headersVisibility: 'Column',
columns: [
{ binding: 'region', header: 'Region', visible: false },
{ binding: 'month', header: 'Period', format: 'MMM yyyy', width: '*' },
{ binding: 'product', header: 'Product', width: '2*' },
{ binding: 'units', header: 'Units Sold', width: '1.5*', format: 'n0' },
{ binding: 'revenue', header: 'Revenue', width: '1.5*', format: 'n2' }
],
itemsSource: view,
formatItem: showChart
});
The main points of interest in the code above are:
- It sets the autoGenerateColumns property to false and sets the columns property to an array that contains the properties for each column we want to display.
- The column widths are specified in star units, which causes them to fill the entire grid width with the proportions given in the code.
- The itemsSource property is set to the CollectionView we created in the previous step.
- The code assigns a handler to the formatItem event. This event handler will be described in detail in a later section.
Toggle Grouping
We mentioned earlier that we are using a CollectionView rather than a regular JavaScript array because we wanted to group the data.
Here is the code that does that:
// show the groups now
showGroups(true);
// toggle grouping when the user clicks the grouping checkbox
document.getElementById('group').addEventListener('click', function(e) {
showGroups(e.target.checked);
});
// toggle grouping
function showGroups(show) {
view.sortDescriptions.clear();
view.groupDescriptions.clear();
if (show) {
let sd = view.sortDescriptions;
sd.push(new wijmo.collections.SortDescription('region', true));
sd.push(new wijmo.collections.SortDescription('month', false));
let gd = view.groupDescriptions;
gd.push(new wijmo.collections.PropertyGroupDescription('region'));
}
}
The code starts by clearing all sort and group descriptions. If grouping is desired, it sorts the data by region and month and groups it by region by adding items to the CollectionView's sortDescriptions and groupDescriptions arrays.
Toggle Charting
We left the best for last. The code that turns the regular grid into a sortable, editable chart is the handler for the grid's formatItem event:
// toggle charting when user clicks the checkbox
document.getElementById('chart').addEventListener('click', function(e) {
theGrid.formatItem.removeHandler(showChart);
if (e.target.checked) {
theGrid.formatItem.addHandler(showChart);
}
});
// paint chart
function showChart(s, e) {
if (e.panel == s.cells) {
var col = s.columns[e.col];
switch (col.binding) {
case 'units':
case 'revenue':
var bar = document.createElement('div'),
val = s.getCellData(e.row, e.col, false),
max = s.collectionView.getAggregate(wijmo.Aggregate.Max, col.binding);
wijmo.addClass(bar, 'spark-bar ' + col.binding);
bar.style.width = (val / max * 100) + '%';
e.cell.appendChild(bar);
break;
}
}
}
The showChart function handles the grid's formatItem event and performs the following tasks:
- Check that we are formatting a regular data cell (not a header)
- Check that the column is bound to the "units" or "revenue" properties, which are the ones we want to chart.
- Create a "div" element, use the cell data to format the new "div", and add it to the cell.
The code adds a "spark-bar" style to the bar element. This is used in our CSS to customize the bar appearance:
.wj-flexgrid .wj-cell .spark-bar {
position: absolute;
opacity: 0.3;
top: 0;
left: 0;
bottom: 0;
border: 3px solid white;
border-radius: 0 8px 8px 0;
}
.wj-flexgrid .wj-cell .spark-bar.units {
background: #0085c7;
}
.wj-flexgrid .wj-cell .spark-bar.revenue {
background: #3b9200;
}
The chart is now visible. If you sort, edit, or group the data, the chart will be automatically updated. This is a nice way to add information to a grid without wasting screen real-estate.
Charts and Data Grids - Conclusion
Adding charts to your data grids is an easy way to convey additional useful without using additional screen real estate or complicating your application's UI.
The FlexGrid's formatItem event provides enough flexibility that you can do that and more with only a couple of lines of code.
We hope you find this information useful and that you start adding cool visualizations to your grids today. For more examples of custom cell rendering, and to learn more about Wijmo, take a look at our demo page .
If you have any questions or comments, feel free to leave a comment below.