PDA

View Full Version : Trouble updating charts



duncan1a
9 Sep 2009, 6:48 AM
Hi

I am new to Extjs, so I may be missing something you all take for granted but, I am trying to update six line charts.

Creating the charts is fine:


function get_store(minutes, direction, area){
// get the chart data
var store = new Ext.data.JsonStore({
url: 'app.php',
baseParams: {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction
},
autoLoad: true,
root: 'data',
fields: [{
name: 'time',
type: 'date',
dateFormat: 'Y-m-d H:i:s'
}, 'MW250', 'MW375', 'MW500', 'MW750']
});

return store;
}

I get the stores like so and save them in an array: store[target]


function get_forecast(target, minutes, direction, area){
Ext.get(target).update('<div class="loading-msg">loading...</div>');

stores[target] = get_store(minutes, direction, area);

stores[target].on('load', function(){
Ext.get(target).update('');
var yReverse = direction == '-' ? true : false;
// Make the graph
charts[target] = new Ext.Panel({
title: minutes + ' minute Ramp Rate: ' + stores[target].getAt(0).get('time'),
renderTo: target,
width: Ext.get(target).width,
height: 250, //Ext.get(target).height*.5,
layout: 'fit',

items: {
xtype: 'linechart',
store: stores[target],
xField: 'time',
yAxis: new Ext.chart.NumericAxis({
displayName: '%',
maximum: 100,
minimum: 0,
majorUnit: 10,
reverse: yReverse
}),
xAxis: new Ext.chart.TimeAxis({
labelRenderer: function(date){
return date.format("H:i");
}
}),
series: [{
type: 'line',
displayName: '250MW:',
yField: 'MW250',
style: {
lineSize: 2,
size: 3,
color: 0xd4f2d5
}
}, {
type: 'line',
displayName: '375MW:',
yField: 'MW375',
style: {
lineSize: 2,
size: 3,
color: 0xabe6ad
}
}, {
type: 'line',
displayName: '500MW:',
yField: 'MW500',
style: {
lineSize: 2,
size: 3,
color: 0x62d167
}
}, {
type: 'line',
displayName: '750MW:',
yField: 'MW750',
style: {
lineSize: 2,
size: 3,
color: 0x00b509
}
}]
}

});


});
}


Running get_forecast() with 6 different params gives me six charts.

The comboBox is:

new Ext.form.ComboBox({
store: region_store, //direct array data
typeAhead: true,
mode: 'local',
displayField: 'regionName',
valueField: 'regionID',
value: 'AGG',
width: 150,
triggerAction: 'all',
selectOnFocus: true,
hiddenName: 'regionId',
renderTo: 'forecast-regions-combo',
listeners: {
select: {
fn: function(combo, value){
var v = combo.getRawValue();
Ext.get('charts-title').update(v);
update_forecasts(combo.getValue());
}
}
}
});

update_forecasts(area) calls the following function for each chart with the new comboBox option

I'm trying to feed new data to the charts by:


function update_forecast(target, minutes, direction, area){
var req = Ext.Ajax.request({
url: 'app.php',
params: {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction
},
success:function(response){
//something here to update the chart by updating charts[target]????
// tried stores[target].loadData(response.responseText);
stores[target].load(response.responseText);

}
});
}
This retrieves the same data structure as the get_store() function above.

If each chart and its store are in charts[target] and stores[target], how to I update the store for a chart so that it update by animating the lines to the new values - ie without reloading the whole chart?

9 Sep 2009, 7:41 AM
simply update the store. use the store's loadData method. It seems that whatever you're doing, you're not passing valid JSON to the stores[target] reference.

duncan1a
10 Sep 2009, 1:25 AM
Thanks for the help. The JSON is the same as the JSON that originally makes the charts. I've tried it with just the 'root' json data and with it exactly as it is to create the charts.

when I do:



var s = stores[target];
stores[target].baseParams.area=area;

s.reload();
ie, reset the baseParam and refire the store it updates fine but the whole chart reloads - ie it dissapears and reappears with the new data.

if I do:

var d = {};
var req = Ext.Ajax.request({
url: 'app.php',
params: {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction,
update:'1'
},
success: function(response){
d=response.responseText;
}
});
var s = stores[target];
s.loadData(Ext.util.JSON.encode(d));


.. I get an error : 'l is undefined'

I need to get it to update by animating the lines because I'll also need to poll the server every minute for new data and I don't want the graphs dissapearing and reappearing every minute.

Thanks for your help

duncan1a
10 Sep 2009, 1:42 AM
that should have been JSON.decode...

Also, trying:

var s = stores[target];
var d = {};
var req = Ext.Ajax.request({
url: 'app.php',
params: {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction,
update:'1'
},
success: function(response){
d=Ext.util.JSON.decode(response.responseText);

s.loadData(d);
}

});
... the chart disapears and reloads - no animating lines

10 Sep 2009, 1:52 AM
yo should be doing:



store.load( {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction,
update:'1'
});

None the less, i have no issues with dynamically updating data via loadData. I'm currently working on this example for Ext JS in Action: http://extjsinaction.com/41/a-quick-look-at-a-draft-charts-and-graphs-chapter-final-example. The pie chart is loaded from cached data.

This is not a chart issue, rather a store issue.

Condor
10 Sep 2009, 1:54 AM
I assume you meant:

store.load({
params: {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction,
update: '1'
}
});

But the original problem remains:
Is there a way to update chart data without refreshing the entire datasource (which causes a complete chart redraw)?

I look through the YUI documentation (http://developer.yahoo.com/yui/charts/), but didn't find anything...

duncan1a
10 Sep 2009, 2:35 AM
using
var s = stores[target];
s.load({
params: {
p: 'get_forecast',
area: area,
minutes: minutes,
direction: direction,
update: '1'
}
});

allows an update once. Subsequent update generate the following error: this.swf.setDataProvider is not a function ext-all.js (line 11)

Surely this can be done? I've edited the example at http://www.extjs.com/deploy/dev/examples/chart/reload-chart.html to use a lineChart and it works nicely. But that example doesn't use Ajax.

doing s.load() or s.loadData() refreshes the whole chart.

duncan1a
10 Sep 2009, 2:47 AM
hmmm, every solution so far that does update the charts only allows one update and then gives the 'this.swf.setDataProvider is not a function ext-all.js (line 11)' error.

Condor
10 Sep 2009, 2:51 AM
You could be suffering from this problem (http://www.extjs.com/forum/showthread.php?t=78788).

ps. The Reload Column Chart Sample uses loadData to update the data, but for a chart there is no difference between using loadData, load or reload. I assume your type of chart simply doesn't handle updating data very well.

duncan1a
10 Sep 2009, 3:12 AM
You could be suffering from this problem (http://www.extjs.com/forum/showthread.php?t=78788).

ps. The Reload Column Chart Sample uses loadData to update the data, but for a chart there is no difference between using loadData, load or reload. I assume your type of chart simply doesn't handle updating data very well.
Yes, I assume it's because it's an Ajax call that takes time.

If I can't animate the update than I might as well just recreate the charts to work around the bug.

It's a pitty