Tuesday, March 8, 2011

Charts, JSON and ExtJS

A bit late, I admit, but finally I've started using Sencha's ExtJS framework.

The first project I was executing was involving charts with JSON data loaded from a C# ASP.NET WCF service.


I have encountered several problems and a lack of proper documentation. Many of the solutions were finally found in another websites and forums but there was no blog post I have found that had everything together in one example.


So I'm proud to be one of the first who does that. I will also describe the problems I've encountered and of course - the solutions.


In ExtJS, the code is created in Windows, Panels or Forms. The latter, Form, can not be added to Asp.net page as it regenerates a <form> tag, which can not be placed under the already-generated <form runat="'server'"> of the asp.net.


I've used the Ext.Panel then, in an external JS file, like so:

Ext.onReady(function () {
var myPanel = new Ext.Panel({ });

});


inside the panel, among the rest of the properties we're placing the items:

var myPanel = new Ext.Panel({
items: [ ... ]

});


In order to render it, we create in the html page a <div> with a certain ID, in which we render the panel into it:

myPanel.render('MainPanel');


which renders it into:

<div id="MainPanel"></div>

In the ASP.NET page itself.

So far, so good.

But the YUI charts were the complicated part.

Regardless the type of the chart (Pie, Bars, Columns, Line etc.), and like everything in life, every chart consists of 3 parts:
The data (Store)
The data type (Record)
and the style (Chart)

The Store is responsible for the data itself. It can hold array of items, of data - like EVERY example on the web...
But it can also load it dynamically from another service, like my WCF JSON service.

var store = new Ext.data.JsonStore({
autoLoad: true,
proxy: new Ext.data.HttpProxy({
url: 'Services/Service.svc/GetJSONData',
method: 'GET',
restful: true
}),
sortInfo: {
field: 'Order',
direction: 'ASC'
or 'DESC' (case sensitive for local sorting)

},
storeId: 'myStore',

The Store also defines the Record (type of the data itself):

// reader configs
root: 'd',
idProperty: 'Id',
fields: [{ name: 'Id', mapping: 'Id', type: 'int' },
{ name: 'OrderId', mapping: 'OrderId', type: 'int' },
{ name: 'Field', mapping: 'Field', type: 'int'}]
});

What I found confusing in loading the data form an external source was actually the proxy. The correct form of using it is using the Ext.data.HttpProxy While I have used at first the Ext.data.DataProxy, which gave as a result a JS error of 'this.load is not a function'.

So after the Store problem was solved and I was finally calling the service and getting back my data, I needed to create the chart itself inside the items part of the Panel.
As this part is a bit more document, I'll still emphasize one aspect.
The basic usage is
{
store: store,
height: 100,
xtype: 'columnchart',
xField: 'Id',
yField: 'Field'
}

But, If you want to add more bars, or graphs - omit the yField part and use instead the 'series' property:
{
store: store,
height: 100,
xtype: 'columnchart',
xField: 'Id',
series: [{
displayName: 'name',
yField: 'Field1',
fillColor: '0x0000FF',
style: {
image: 'bar.gif',
mode: 'stretch',
color: '0x0000FF'
}
},
{
displayName: 'name',
yField: 'Field2',
fillColor: '0x0000FF',
style: {
image: 'bar.gif',
mode: 'stretch',
color: '0x0000FF'
}
}
]
}

I sure hope it was helpful, and I would be delighted to assist or answer questions if needed.

Happy coding
Liad

2 comments:

kesu said...
This comment has been removed by the author.
kesu said...

Thanks for posting this! However, as a programmer I am looking for some example JSON data which I can send as JSON response, so that EXTJS understands. Say, for pie charts and line charts with mutiple data series. Could you please post the same incase you can think of some? Also, how to create a JSONStore using json response that I will get at EXTJS end?