Join Virtual JavaScript Days 2026 and Get a Free Participation Certificate – Register Now!

mzPivotGrid: A pivot table for Ext JS

March 13, 2013 3073 Views

Get a summary of this article:

Show

Guest Blog Post

At mzSolutions, I work on creating components for Ext JS and Sencha Touch. In this post, I will show you how to use mzPivotGrid with Sencha Ext JS.

What is a pivot grid?

The Ext JS grid panel is perfect for displaying large sets of data, and it provides many features for all kinds of data display. One type of data display that it doesn’t provide is a pivot grid. When it comes to reporting, a pivot grid is the way to go because it helps you organize and summarize data and create reports; and it enables users to make more informed decisions about their data.

What is mzPivotGrid

mzPivotGrid is a component that you can use with Ext JS to create a pivot grid. Let’s imagine the following scenario. You have some sales data with the following fields: country, salesperson, order date, order amount and order ID. If you want to edit this data, you could easily use an Ext JS GridPanel with CellEditing or RowEditing plugins.

What would you do if you had to answer the following questions?

  1. What are the order amounts of each salesperson?
  2. What are the order amounts of each salesperson in a specific country?
  3. How did salespeople perform in a specific year?

You could use mzPivotGrid to create those reports, and this is how they would look:

Using mzPivotGrid

mzPivotGrid inherits the Ext JS Grid Panel component, so you can use most of the features you are already familiar with: column resizing, locking, cell renderers, row/cell events etc. The mzPivotGrid can be used when you want to get summation and pivot features that aren’t provided in the default GridPanel.

To break down the dataset into salespeople and years, you just have to configure the top and left axis:

[style code sample below]

leftAxis: [{
width: 80,
dataIndex: ‘salesperson’,
header: ‘Salesperson’
}],

topAxis: [{
dataIndex: ‘year’,
header: ‘Year’,
direction: ‘ASC’
}]

Multiple levels are supported, so you can just specify them in the top and left axis. Grouping the rows and/or columns could be handy here, so you can simply do that by setting “enableGrouping” to true.

Now that you broke down the dataset on the top and left axis, it’s time to aggregate the cell values. Several kinds of aggregations are available including: sum, average, min, max, count etc. If these are not enough, you can provide your own aggregation function.

[style code sample below]

aggregate: [{
measure: ‘amount’,
header: ‘Sales’,
aggregator: ‘sum’,
align: ‘right’,
width: 85,
renderer: Ext.util.Format.numberRenderer(‘0,000.00’)
},{
measure: ‘orderid’,
header: ‘Qnt’,
aggregator: function(records, measure, matrix, rowGroupKey, colGroupKey) {
// do your own algorithm
return records.length;
},
align: ‘right’,
width: 85,
renderer: Ext.util.Format.numberRenderer(‘0,000.00’)
}]

As you have probably noticed in the above example, you could aggregate multiple data fields, say “sales” and “quantity.” You can easily achieve this by configuring all required aggregations.

Showing the grand totals for rows and/or columns is pretty easy to configure (“enableRowGrandTotals: true” or “enableColGrandTotals: true”). The group totals are also available via “enableRowSummary” and “enableColSummary” configs. Styling is also easy, and you can even define cell renderers.

The pivot grid uses any kind of Store available in Ext JS, so filtering the data is pretty easy to do on the Store object. This means you can implement a plugin to handle the filtering.

The Ext JS Data Model class is awesome, so you should use its powerful “convert” function to extend your model and break down your data in custom group intervals. Check out this example:

[style code sample below]

fields: [
{name: ‘orderid’, type: ‘int’},
{name: ‘salesperson’, type: ‘string’},
{name: ‘country’, type: ‘string’},
{name: ‘orderdate’, type: ‘date’, dateFormat: ‘d/m/Y’},
{name: ‘amount’, type: ‘int’},
{
name: ‘person-range’,
convert: function(v, record){
if(/^[a-j]/i.test(record.get(‘salesperson’))) return ‘A-J’;
if(/^[k-s]/i.test(record.get(‘salesperson’))) return ‘K-S’;
if(/^[t-z]/i.test(record.get(‘salesperson’))) return ‘T-Z’;
return v;
}
},{
name: ‘year’,
convert: function(v, record){
return Ext.Date.format(record.get(‘orderdate’), “Y”);
}
}
]

… it will look like this:

A sample use case

[style code sample below]

var pivotGrid = Ext.create(‘Mz.pivot.Grid’, {
title: ‘Pivot grid’,
height: 400,
width: 600,
enableLocking: false,
enableGrouping: true,
viewConfig: {
trackOver: true,
stripeRows: false
},
store: store,
aggregate: [{
measure: ‘amount’,
header: ‘Sales’,
aggregator: ‘sum’,
align: ‘right’,
width: 85,
renderer: Ext.util.Format.numberRenderer(‘0,000.00’)
}],
caption: ‘Sales report’,
leftAxis: [{
width: 80,
dataIndex: ‘salesperson’,
header: ‘Sales Person’
}],
topAxis: [{
dataIndex: ‘year’,
header: ‘Year’,
direction: ‘ASC’
}] });

Future

Since mzPivotGrid is a commercial product, it will constantly be improved with new plugins and features. Feel free to contact us if you need something special implemented.

To learn more about mzPivotGrid licensing, click here.

Additional resources:

[Add to author section]

Written by Adrian Teodorescu
Adrian Teodorescu has more than 15 years experience as a software developer and has been active in the Sencha community since 2009. His main focus is creating components for Ext JS and Sencha Touch. You can contact Adrian on his website.

Recommended Articles

Building Responsive, Data-Driven Enterprise Applications with JavaScript

In enterprise software, responsiveness is no longer a nice-to-have. Users expect the same application to perform smoothly whether they are working at a desktop with…

What’s New in ReExt 1.2

Modern teams are under constant pressure to ship faster without sacrificing UX quality, maintainability, or enterprise-grade capabilities. That’s easy to say, but much harder to…

BFF Architecture – Optimizing Communication between Node. js and Ext JS

Modern enterprise applications rarely struggle because they lack features. More often, they struggle because the frontend and backend are speaking slightly different languages. Your database…

Case Study: Building a Modern Recruitment Application with Ext JS

Hiring the right talent requires more than collecting resumes. Modern recruitment teams need streamlined workflows, real-time visibility, and reliable tools that support every stage of…

Techniques for Handling Large Data Sets in Ext JS

Enterprise applications often need to display and process thousands – or even millions – of records while maintaining a responsive and intuitive user experience. Whether…

Building an AI-Powered School Grading System with Ext JS

Educational institutions are under increasing pressure to evaluate growing numbers of student assessments while maintaining fairness, consistency, and timely feedback. Although artificial intelligence offers new…

View More
JS Days Popup