A front-end development blog

aboutfrontend.com

Data from multiple stores to charts in ExtJs – jQuery flot

with 3 comments

Got a comment on my previous post Ext JS Charts and timeaxis:

Hi Nils -
Thanks for the article. We have got two lines within a chart. We are using this for trend analysis. So, one line should show the actual data and the other we want to trend it beyond the actual data. We know how to trend and all. But, can we have two datasets to be used for drawing the lines? Would appreciate any information. Thanks, again.

“Two datasets” – I did some testing based on the Charts package in ExtJs. But, I soon figured out it would not work without lots of work.

Flot charts and multiple stores in ExtJs

But, I have worked with another charts library called flot in a project lately. We even hired Ole Laursen, the guy behind flot, to do some further development on the library. He wrote a method for converting ExtJs Stores to flot data series. The following shows how this can be done. Happy reading.

Basics – setup data stores

This post is based on the Ext JS Charts and timeaxis. The main source is the same, so read read it first if you are just looking for how to make charts in Ext Js.

You will need the following files:
jquery.js
jquery-flot.js

/*
I have defined two div's in a html file: 

The last one just for debug and testing purpose.
*/

	// Defining the fields for the record.
	// For simplicity we use the same fields definition and the same record for both stores.
	var fields = [ {name: 'timestamp', type: 'date'}, 'temperature'];

	// Sets up the record
	var rec = new Ext.data.Record.create([
        { name: 'datetime', type: 'date', dateFormat: 'Y-m-d H:i:s'},
        { name: 'temp' }
    ]);

	// Creates an array with the data
	var data = [
	    ['2009-08-22 00:00:00', 10],
	    ['2009-08-22 01:00:00', 10.2],
	    ['2009-08-22 02:00:00', 10.6],
	    ['2009-08-22 03:00:00', 10.7],
	    ['2009-08-22 04:00:00', 10.8],
	    ['2009-08-22 05:00:00', 10.6],
	    ['2009-08-22 06:00:00', 10.9],
	    ['2009-08-22 09:00:00', 10.6],
	    ['2009-08-22 12:00:00', 11.2],
	    ['2009-08-22 15:00:00', 11.5],
	    ['2009-08-22 18:00:00', 11.7],
	    ['2009-08-22 21:00:00', 11.9]
    ];

    var data2 = [
        ['2009-08-22 00:00:00', 12],
        ['2009-08-22 01:00:00', 12.2],
        ['2009-08-22 02:00:00', 12.6],
        ['2009-08-22 03:00:00', 12.7],
        ['2009-08-22 04:00:00', 12.8],
        ['2009-08-22 05:00:00', 12.6],
        ['2009-08-22 06:00:00', 12.9],
        ['2009-08-22 09:00:00', 12.6],
        ['2009-08-22 12:00:00', 13.2],
        ['2009-08-22 15:00:00', 13.5],
        ['2009-08-22 18:00:00', 13.7],
        ['2009-08-22 21:00:00', 13.9]
     ];

	// Creates an array reader
	var reader = new Ext.data.ArrayReader({}, rec);

	// And finally the store
	var store = new Ext.data.Store({
		fields: fields,
		reader: reader,
		data  : data
	});

	var store2 = new Ext.data.Store({
		fields: fields,
		reader: reader,
		data  : data2
	});

Now we have two stores, with slightly different data.

Setting up flot series

The API docs for flot says the following about the data format for the series:


The data is an array of data series:
[ series1, series2, ... ]
A series can either be raw data or an object with properties. The raw
data format is an array of points:
[ [x1, y1], [x2, y2], ... ]
E.g.
[ [1, 3], [2, 14.01], [3.5, 3.14] ]

So, we now need a method for taking data from ExtJs Stores and convert them to, yeah exactly, arrays.

	function flotDataFromExtStore(store, xField, yField, appendId) {
		function convert(data) {
			if (data === "")
				return null;
			if(data === null)
				return null;

			if (typeof data == "object" && data.constructor == Date)
                // correct with local timezone offset to work-around data being
                // in local time
				return data.getTime() - data.getTimezoneOffset() * 60 * 1000;
			return +data;
		}

		var res = [];
		store.each(function (record) {
			res.push([convert(record.data[xField]),
					  convert(record.data[yField])]);
			if (appendId)
				res[res.length - 1].push(record.id);
		});
		return res;
	}

The next step is to generate the chart and the dataseries based on our two stores:

// I have defined a div element with the id chart
	jQuery.plot(
			document.getElementById("chart"),
			[
                // data from the first store
                flotDataFromExtStore(store, "datetime", "temp"),
                // data from the second store
                flotDataFromExtStore(store2,"datetime","temp")
            ]
    );

That’s pretty much it, you have a perfect working chart with lines from two different Ext data stores.

flot chart based on extjs data store

A working example can be seen here.

Sweet or what?

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Twitter

Written by Nils-Fredrik G. Kaland

October 11th, 2009 at 10:09 pm

3 Responses to 'Data from multiple stores to charts in ExtJs – jQuery flot'

Subscribe to comments with RSS or TrackBack to 'Data from multiple stores to charts in ExtJs – jQuery flot'.

  1. Nils -

    Thanks for taking time to setup the example. Much appreciated. Would we be able to get source for this? We will also try with this information and see how it goes. Again, thanks.

    vnug

    12 Oct 09 at 07:35

  2. Nils-Fredrik G. Kaland

    12 Oct 09 at 09:13

  3. I got some questions in the Sencha forum (http://www.sencha.com/forum/showthread.php?82630-Charts-jQuery-flot-and-data-from-multiple-extjs-stores&highlight=aboutfrontend) about how to add the charts to panels. As far as I can see this cannot be done directly, since flot is written in jQuery and the rest is ExtJs.

    Of course, there are ways to solve it anyways. The point is that the panel needs to be rendered first, so that you can assign an id to it.

    var renderPanel = new Ext.Panel({
    	renderTo: "chart",
    	html: 'A panel',
    	id: "renderPanel",
    	height: 300,
    	width: 600
    });
    
    jQuery.plot(
    	Ext.getDom("renderPanel"),
    	[
            flotDataFromExtStore(store, "datetime", "temp"),
            flotDataFromExtStore(store2,"datetime","temp")
        ]
    );
    

    Working example can be seen at http://aboutfrontend.com/wp-content/uploads/2009/10/to-panel.html

    Nils-Fredrik G. Kaland

    20 Jul 10 at 09:50

Leave a Reply