03.12
So you’ve got a nice Ext JS application but you want a little more from your charts. Even better, you’ve found a nice plugin for JQuery called jqPlot that creates all kinds of nice charts. So, how do you make jqPlot work nicely within the ExtJS framework?
First, include the jqPlot & jQuery files in your index.html file in the head section:
<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="jQuery/excanvas.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="jQuery/jquery-1.7.1.js"></script>
<script language="javascript" type="text/javascript" src="jQuery/jquery.jqplot.min.js"></script>
<script language="javascript" type="text/javascript" src="jQuery/jqplot.dateAxisRenderer.min.js"></script> |
Now, lets run though how jqPlot works. It takes a div, and within that div it injects all it’s chart stuff. That means more divs and whatnot, but everything is contained in the base div we pass to jqPlot. We’re going to use the panel’s body as the containing div for the chart since there’s no other content. We also want the chart to be drawn once, and we need to make sure ExtJS has created the div for us to use, so we’ll override the afterComponentLayout function like so:
afterComponentLayout: function(width, height) { data = [['1/2012', 50],['2/2012', 66],['3/2012', 75]]; $.jqplot(this.body.id, data, { title:'Server Load', axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}}, series:[ {label:'Awesome Level'} ] }); this.callParent(arguments); } |
this.body.id is the class of the body div the panel is built around. But what if you drag the panel around, or gets resized? Your chart is drawn multiple times stacked. We need JQuery to clear the old chart before the lastest is drawn. So add this before your $.jqplot call:
$('#'+this.body.id).empty(); |
Which asks JQuery to empty the contents of the div (in this case the body). Why the #? JQuery uses # to look up the id. It’s part of the JQuery selection syntax. Put them together and you have a nice chart.
But what if you want to use an ExtJS store? Well, it’s a little more complicated since you have to translate your data, but it’s not hard. Lets say we have a store that tracks our Awesome levels. So it’s has date & awesome fields. We’ve already set it up in our Ext.define with store: ‘AwesomeLevels’; So let’s pull it up and reference it:
var dataArray = Ext.Array.pluck(Ext.data.StoreManager.lookup(this.store).data.items,'data'); var data = [[]]; dataArray.forEach(function(obj){ data[0].push([obj.date, obj.awesome]); }); |
And thus we’ve populated our data object that we’re going to pass to jqPlot. So the final afterComponentLayout function looks like this:
afterComponentLayout: function(width, height) { var dataArray = Ext.Array.pluck(Ext.data.StoreManager.lookup(this.store).data.items,'data'); var data = [[]]; dataArray.forEach(function(obj){ data[0].push([obj.date, obj.awesome]); }); $('#'+this.body.id).empty(); data = [['1/2012', 50],['2/2012', 66],['3/2012', 75]]; $.jqplot(this.body.id, data, { title:'Server Load', axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}}, series:[ {label:'Awesome Level'} ] }); this.callParent(arguments); } |
And we have a nice Panel with a jqPlot chart.