Sencha Touch 2 – Thoughts from the Trenches

As you may have seen, we put out the first public preview release of Sencha Touch 2 today. It only went live a few hours ago but the feedback has been inspiring so far. For the full scoop see the post on the sencha.com blog. A few thoughts on where we are with the product:

Performance

Performance on Android devices in particular is breathtaking. I never thought I’d see the day where I could pick up an Android 2.3 device and have it feel faster than an iPhone 4, and yet that’s exactly what Sencha Touch 2 brings to the table. I recorded this short video on an actual device to show real world performance:

Now try the same on Sencha Touch 1.x (or any other competing framework) and (if you’re anything like me) cringe at what we were accustomed to using before. That video’s cool, but the one that’s really driving people wild is the side by side comparison of the layout engines in 1.x and 2.x.

Getting our hands on a high speed camera and recording these devices at 120fps was a lot of fun. Slowing time down to 1/4 of normal speed shows just how much faster the new layout engine is than what we used to have:

The most amazing part here is that we actually finish laying out *before* the phone’s rotation animation has completed. Skipping through the video frame by frame there are at least 5 frames where the app is fully laid out and interactive while the phone’s rotation animation is still running. Beating the phone’s own rotation speed is the holy grail – it’s not possible to make it any faster.

Documentation

I’ll admit it, I’m fanatical about great documentation. I’m sure I drive everyone else on the team crazy but I think it’s worth it. This is only a preview release but it already contains by far the best, most complete documentation we’ve ever shipped in an initial release.

In fact, the team’s worked so hard on documenting classes that it’s probably better than the (already good) Ext JS 4 docs. Naturally, this makes it time to further improve the Ext JS documentation.

We’ve added some awesome features here – lots of videos, 11 brand new guides and illustrations. My favourite new feature is definitely the inline examples with live previews though – seeing Sencha Touch running live in a phone/tablet right there in the docs is just amazing. Little gems like the live twitter feed in the bottom-most example in the DataView docs really sell just how easy it is to configure these components.

We set a high bar for this though. We’ve gone from woeful documentation in 1.x to good documentation in 2.x, but what we’re shooting for is excellence. We’ll continue to round out our content over coming weeks, and have a few new features rolling out soon that will raise the bar once again.

Onwards

We have a few features left to implement, which is why we’re calling this preview and not beta. Probably the biggest thing now is getting routing/deep linking back into the framework, along with a nice new syntax that I think you’ll find really easy to use. We’re also missing carousel animations and a handful of other things that will be going back in over the coming weeks. We have Sencha Con 2011 in just 12 days now though so we’ll share more details there.

Finally though, I want to thank everyone who participated in the closed preview phase, and for everyone sending their support and kind words on the blog, the forums and on twitter. We really appreciate all the great feedback and I hope we can exceed your expectations with a fast, polished, gorgeous 2.0 final!

Using the Ext JS PivotGrid

One of the new components we just unveiled for the Ext JS 3.3 beta is PivotGrid. PivotGrid is a powerful new component that reduces and aggregates large datasets into a more understandable form.

A classic example of PivotGrid’s usefulness is in analyzing sales data. Companies often keep a database containing all the sales they have made and want to glean some insight into how well they are performing. PivotGrid gives the ability to rapidly summarize this large and unwieldy dataset – for example showing sales count broken down by city and salesperson.

A simple example

We created an example of this scenario in the 3.3 beta release. Here we have a fictional dataset containing 300 rows of sales data (see the raw data). We asked PivotGrid to break the data down by Salesperson and Product, showing us how they performed over time. Each cell contains the sum of sales made by the given salesperson/product combination in the given city and year.

Let’s see how we create this PivotGrid:

var SaleRecord = Ext.data.Record.create([
    {name: 'person',   type: 'string'},
    {name: 'product',  type: 'string'},
    {name: 'city',     type: 'string'},
    {name: 'state',    type: 'string'},
    {name: 'month',    type: 'int'},
    {name: 'quarter',  type: 'int'},
    {name: 'year',     type: 'int'},
    {name: 'quantity', type: 'int'},
    {name: 'value',    type: 'int'}
]);

var myStore = new Ext.data.Store({
    url: 'salesdata.json',
    autoLoad: true,
    reader: new Ext.data.JsonReader({
        root: 'rows',
        idProperty: 'id'
    }, SaleRecord)
});

var pivotGrid = new Ext.grid.PivotGrid({
    title     : 'Sales Performance',
    store     : myStore,
    aggregator: 'sum',
    measure   : 'value',
    
    leftAxis: [
        {dataIndex: 'person',  width: 80},
        {dataIndex: 'product', width: 90}
    ],
    
    topAxis: [
        {dataIndex: 'year'},
        {dataIndex: 'city'}
    ]
});

The first half of this ought to be very familiar – we just set up a normal Record and Store. This is all we need to load our sample data so that it’s ready for pivoting. This is all exactly the same code as for our other Store-bound components like Grid and DataView so it’s easy to take an existing Grid and turn it into a PivotGrid.

The second half of the code creates the PivotGrid itself. There are 5 main components to a PivotGrid – the store, the measure, the aggregator, the left axis and the top axis. Taking these in turn:

  • Store – the Store we created above
  • Measure – the field in the data that we want to aggregate (in this case the sale value)
  • Aggregator – the function we use to combine data into the cells. See the docs for full details
  • Left Axis – the fields to break data down by on the left axis
  • Top Axis – the fields to break data down by on the top axis

The measure and the items in the axes must all be fields from the Store. The aggregator function can usually be passed in as a string – there are 5 aggregator functions built in: sum, count, min, max and avg.

Renderers

This is all we need to create a simple PivotGrid; now it’s time to look at a few more advanced options. Let’s start with renderers. Once the data for each cell has been calculated, the value is passed to an optional renderer function, which takes each value in turn and returns another value. One of the PivotGrid examples shows average heights in feet and inches but the calculated data is in decimal. Here’s the renderer we use in that example:

new Ext.grid.PivotGrid({
    store     : myStore,
    aggregator: 'avg',
    measure   : 'height',
    
    //turns a decimal number of feet into feet and inches
    renderer  : function(value) {
        var feet   = Math.floor(value),
            inches = Math.round((value - feet) * 12);
            
        return String.format("{0}' {1}"", feet, inches);
    },
    //the rest of the config
});

Customising cell appearance

Another one of the PivotGrid examples uses a custom cell style. As with the renderer, each cell has the opportunity to alter itself with a custom function – here’s the one we use in the countries example:

new Ext.grid.PivotGrid({
    store     : myStore,
    aggregator: 'avg',
    measure   : 'height',
    
    viewConfig: {
        getCellCls: function(value) {
            if (value < 20) {
                return 'expense-low';
            } else if (value < 75) {
                return 'expense-medium';
            } else {
                return 'expense-high';
            }
        }
    },
    //the rest of the config
});

Reconfiguring at runtime

A lot of the power of PivotGrid is that it can be used by users of your application to summarize datasets any way they want. This is made possible by PivotGrid’s ability to reconfigure itself at runtime. We present one final example of a PivotGrid that can be reconfigured at runtime. Here’s how we perform the reconfiguration:

//the left axis can also be changed
pivot.topAxis.setDimensions([
    {dataIndex: 'city', direction: 'DESC'},
    {dataIndex: 'year', direction: 'ASC'}
]);

pivot.setMeasure('value');
pivot.setAggregator('avg');

pivot.view.refresh(true);

It’s easy to change the axes, dimension, aggregator and measure at any time and then refresh the data. The calculations are all performed client side so there is no need for another round-trip to the server when reconfiguring. The example linked above gives an example interface for updating a PivotGrid, though anything that can make the API calls above could be used.

I hope you enjoy the new components in this Ext JS 3.3 beta and look forward to comments and suggestions. Although we’re only at beta stage I think the additions are already quite robust so feel free to stress-test them.

%d bloggers like this: