May 19, 2010

Getting Started with ExtJS Charts

The Charts feature in ExtJS is not a new thing, but recently few Techno Paper readers asked me questions regrading the same. This article is about getting started with ExtJS Charts how to do some basic customizations. For now, we will see what kind of charts ExtJS provide and how to get your first chart displayed.

Prerequisites

I assume you already have knowledge in building the UI (panels at least) and have worked on DataStores ( I will be using JSONStore). If you are not ready with these, may be you can have a look at my basic tutorials like "All about...".

What ExtJS offers
ExtJS offers you Line, Bar, Column, Pie and stacked charts. It also offers good amount of customization options as well. All the chart related classes are under the package Ext.chart and Chart is the base class. Apart from the chart classes, the library also provides classes that can be used to customize the axis, series and even the chart display. But note that, ExtJS makes use of Flash to render the charts and its not pure JavaScript component. Internally ExtJS is making use of YUI charts features and classes. Now, lets get started with coding!

Hello World of Charts

Building charts with ExtJS requires three things. The Datastore, the Chart object and a Panel to display the chart. In our first example i am going to keep things very simple. Lets build a DataStore first:
var store = new Ext.data.JsonStore({
fields:['month', 'sales'],
data: [
    {month:'Jan', sales: 2000},{month:'Feb', sales: 1800},
    {month:'Mar', sales: 1500},{month:'Apr', sales: 2150},
    {month:'May', sales: 2210},{month:'Jun', sales: 2250},
    {month:'Jul', sales: 2370},{month:'Aug', sales: 2500},
    {month:'Sep', sales: 3000},{month:'Oct', sales: 2580},
    {month:'Nov', sales: 2100},{month:'Dec', sales: 2650}
]});
I have a simple JsonStore here with the data hardcoded. In later examples, we will be fetching the data through ajax request. In the JsonStore, I have provided metadata and data. The fields attribute describe the fields in my records. The data attribute actually holds the data in the form of JSON. Instead of using JSON, we could also use XML.

Next, to create the chart object. For this example, I have used the line chart. Here is the code:
var chart = new Ext.chart.LineChart({
    store: store,
    xField: 'month',
    yField: 'sales'
});
Its very clean and simple! I have just provided the data store and what has to be plotted along x and y axis. And finally we need to put the chart into display. Here is our Panel:
var Panel = new Ext.Panel({
    title: 'Yearly Sales',
    renderTo: 'chartDiv',
    width: 400,
    height: 200,
    items:[chart]
});
If you are experienced coder I suggest you define the chart object in the panel rather than declaring it separately. Lets begin dig deeper!

Working with Axis

Chat's axis can be configured using xAsix and yAsix properties. There properties can accept objects of CategoryAsix, NumericAxis or TimeAxis. Lets add titles to our chart's axis:
xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
                  }),
                  yAxis: new Ext.chart.NumericAxis({
                  title:'USD',
                  majorUnit: 500
                  })
Note that we have made use of CategoryAxis for y-axis as it hold months. Whereas, we have used NumericAxis for x-axis as it represents sales value in USD. I also changed the units in which the x-axis is represented. Check the API for other properties of these classes.

Working with Series

You don't always plot one parameter on a chart. At times, you have multiple data to be visualized onto the charts. Lets take our example of sales per month and add revenue to it. Now we need to plot both sales and revenue for each month. ExtJS allows you to do this by adding series object to the chart. The framework provides five implementations for different types of charts. Let's modify our chart to show revenue as well:
new Ext.Panel({
       title: 'A Simple Chart',
       renderTo: 'container',
       width:600,
       height:300,
       items: {
           xtype: 'linechart',
           store: store,
           xField: 'month',
xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
}),
yAxis: new Ext.chart.NumericAxis({
title:'USD',
majorUnit: 500
}),
series: [{
yField: 'sales'
},{
yField: 'rev'
             }]
}
   });
I have kept the series objects very simple. We have just added the data alone. Upon execution, you will notice that it difficult to interpret the data as we do not have a legend on our chart. And that's exactly our next objective. To start with, lets modify the series as:
series: [{
yField: 'sales',
displayName: 'Sales'
},{
yField: 'rev',
displayName: 'Revenue'
 }]
I have just added the displyName property. To complete our modifications we need to do one final task, i.e display the legend!

Working with Extra Styles

extraSyle is an important property for styling your charts. It helps in modifying the colors, fonts, borders for various parts of your chart like axis, data tips, legends etc. First lets add a legend to our existing chart. Here is the code:
new Ext.Panel({
       title: 'A Simple Chart',
       renderTo: 'container',
       width:600,
       height:300,
       items: {
           xtype: 'linechart',
           store: store,
           xField: 'month',
xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
}),
yAxis: new Ext.chart.NumericAxis({
title:'USD',
majorUnit: 500
}),
series: [{
yField: 'sales',
displayName: 'Sales'
},{
yField: 'rev',
displayName: 'Revenue'
             }],
extraStyle: {
legend: {
display: 'right'
}
}
}
   });
If you think of more customizations and styling, you need to have a good look at the extraStyle.
Well, that all for now. Feel free to provide me your feedback on this post. Next, we will have a look at pie charts.

10 comments:

Anonymous said...

This is a very good example, however, you are missing the Revenue data. So it can get confusing to an individual who is copying your code. The store field should add {month: 'Jan', rev: 3000}, {month: 'Feb', rev: 2900}

Abdel Olakara said...

Actually, it should be {month:'Jan',sales: 3000, rev: 4000} if you need to plot both sales and revenue. I left that for the readers to try out. So that they get better understanding rather than just copy,paste and run.

Anonymous said...

The ExtJs documentation is not very good. I am having some issues. My question how does the Click event work. How will you know which series the user has clicked. The line chart example on ExtJs only explains how to get the index but it does not tell you which series a user has selected. could you please post this this would be really helpful.

Anonymous said...

In order to get the index the user has clicked in a multiple line chart you have to use the Object (o) reference in your function. The property " o.seriesIndex " will let you know which series was selected. Ex.

listeners: {
itemclick: function (o) {
// GETS INDEX IN A MULTIPLE LINE CHART.
var index = o.seriesIndex;
}
}

Abdel Olakara said...

Check the latest blog article. Its about handling event in ExtJS charts.

Anonymous said...

Hi,
i am getting some error in browser while trying to use extjs charts, please help me out

error displayed in browser -
"Warning: Cannot establish communication between YUI Charts and JavaScript. YUI Charts must be served from HTTP and cannot be viewed locally with file:/// protocol unless location is trusted by Flash Player.
"


Can you let me know what may be wrong with my setup?

Abdel Olakara said...

@Anonymous,
check if you have set Ext.chart.Chart.CHART_URL variable to point to correct location of charts.swf file. And use a HTTP path not physical path. contact me on @olakara on twitter.

Sumi said...

For security purpose, flash player doesn't take local(hard disk) content while rendering.
Still, in case we want this to work, we need to mention that the extjs folder path (or exact files) as secure folder in flash plugin for browsers.

Gokul said...

Hello sir,

Is this possible!, "I Want to add fields for JsonStore dynamically"?

If possible plz ,help me ..!

eg:

fields :['date','client1','client2',.... ]

Abdel Olakara said...

@Gokul, I have not tried it though. You should be able to modify a store using the proxy metadata settings.