I've got a chart :
Ext.define('CarboZero.view.PieChart', {
extend: 'Ext.chart.PolarChart',
alias: 'widget.piechart',
requires: [
'CarboZero.view.override.PieChart'
],
config: {
animate: false,
store: 'relativedata',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111',
'#222222',
'#115ea6',
'#94cc0a',
'#b61120',
'#dd8809',
'#11d13e',
'#a68887',
'#94df9d',
'#7f74f4',
'#112341',
'#abcdef1'
],
series: [
{
type: 'pie',
renderer: function(sprite, record, attributes, index, store) {
if(record.type === 'label')
{
var total = Ext.getStore('relativedata').getTotal();
var name = record.text;
var value = Ext.getStore('relativedata').getByName(name);
var ratio = Math.round((value/total)*10000)/100;
sprite.labelCfg.text = sprite.labelCfg.text +" : "+ ratio +"%";
}
},
labelField: 'strName',
xField: 'numValue'
}
],
interactions: [
{
type: 'rotate'
}
],
legend: {
xtype: 'legend',
docked: 'bottom',
itemId: 'pie_legend',
itemTpl: [
'<tpl if="value != 0">',
' <span class="x-legend-item-marker {[values.disabled?\'x-legend-inactive\':\'\']}" style="background:{mark};"></span>{name}',
'</tpl>'
],
maxItemCache: 100,
store: 'relativedata'
},
listeners: [
{
fn: 'onPolarInitialize',
event: 'initialize'
}
]
}
});
Which uses this store
Ext.define('CarboZero.store.RelativeData', {
extend: 'Ext.data.Store',
alias: 'store.relativedata',
requires: [
'CarboZero.model.RelativeElement'
],
config: {
destroyRemovedRecords: false,
model: 'CarboZero.model.RelativeElement',
storeId: 'relativedata'
},
getTotal: function() {
var total =0;
for( var i=0; i<this.getCount();i++)
{
total += this.getAt(i).get('numValue');
}
return total;
},
getByName: function(name) {
var value;
for(var i=0;i<this.getCount();i++)
{
if(this.getAt(i).get('strName')===name)
{
value = this.getAt(i).get('numValue');
break;
}
}
return value;
}
});
I fill my store using this function :
var relStore = Ext.getStore('relativedata');
var eleStore = Ext.getStore('element');
var relModel;
var eleModel;
var boolAdded = false;
relStore.removeAll();
//Convert to CO2 qty
for(var i = 0; i< eleStore.getCount();i++)
{
eleModel = eleStore.getAt(i);
relModel = Ext.create(APPNAME + '.model.RelativeElement');
relModel.set('strName',eleModel.get('strName'));
relModel.set('numValue', elementCompute(eleModel));
if(eleModel.get('numValue')*eleModel.getFactor() >0)
{
boolAdded = true;
relStore.add(relModel);
}
}
APP.getController('TitleBar').parentToTitle();
//No element had a value superior to 0, nothing is displayed
if(!boolAdded)
{
APP.getController('PopUp').chartAlert();
}
this.refreshpie(); ///SPECIAL LINE NEEDED
Has you can see this store is local and use another store to fill it self. The last line of the function used to fill the store-linked to the chart is 'this.refreshpie()' which does some magic but clearly contribute to the problem I have. Here it is :
pie.sync();
pie.redraw();
If those lines are not there, no chart is displayed at all. Which does not make sense since .sync should be use for non-local store...
Problem is, i'm happy that it works at displaying the chart... but there is one little thing that i could not understand.
My chart display a level of my data-tree, when I go to another level the store is updated with the nodes in that level.
What happens is that when I go up in the tree, this kind of problem happens
The old data labels stay on the chart (Coal, Nuclear) and the new one is added over it... I checked the store, it's filled with the right models, I checked everything I could check inside the pie+chart model and couldnt find anything messed up...
IE. In this picture only Electricity is supposed to be displayed.
Can someone help me out, the black magic of sencha touch charts is getting the upper hand on my patience.
Good to know if i were to do a rotation of the chart (interation rotation - proced on gesture) the labels would reset themselve and display properly...
Let's call Serie._label.instances
array has arrLabels
.
Get the serie from attributes.serie
in the renderer()
arrLabels
has 5 elements in it.My solution was to make double check and slice those elements out arrLabels.slice(index,1)
and chart.refresh()
.
I would not recommend this solution if the store contains alot of elements has it will be called alot.
renderer()
is actually called 4 time by sprite to display O(4n)
...
Plus we know that you need to check if the element needs to be displayed or not which would be in O(N)
.
So it would be O(n^(4n))
approx O(n^n)
.
I bug reported it, sencha team should probably do something about it.
Bug report : http://www.sencha.com/forum/showthread.php?270229-Chart-Serie._Label_instances-Updating-is-not-working-properly