PDA

View Full Version : GOTCHA: store writes during render trigger endless chart refreshes



awebb
21 Sep 2011, 8:25 AM
In the following chart config, event 'labelOverflow' uses the store to communicate to the callout renderer. However, writing to the store during the rendering of the chart will fire the 'update' event, which will cause Touch Charts to queue up another refresh. And during that refresh, the store-write will trigger another refresh. The result is endless refreshes. The fix is to suspend events during the store-write, as the config shows.



// Construct config for the Ext.chart.Chart constructor.
config = {
renderTo: this.assetAllocPanel.getTargetEl(), // gets panel's inner div, the one that's updated by a call to panel.update()
width: width,
height: height,
insetPadding: 35, // increase the inset padding to accomodate the callout labels
store: this.assetAllocationSeriesStore,
series: [{
type: 'pie',
angleField: 'angleValue',
colorSet: [],
listeners: {
// Called when the label doesn't fit within the slice.
labelOverflow: function(label, item) {
var store = item.storeItem.store;

// Use callout (but then every slice is using a callout, so not strictly necessary).
item.useCallout = true;

// Indicate to the callout renderer (below) that the callout label should
// include the segment name, since it won't appear within the slice. Note that
// we have to suspend events when writing to the store, otherwise doing so will
// fire an 'update' event, which will cause Touch Charts to queue up a refresh
// of the chart; during that refresh this code will be reached again, which will
// queue up another refresh - and so the chart refreshes forever. Suspending
// events during the store-write sorts this out.
store.suspendEvents();
item.storeItem.set('showNameInCallout', true);
store.resumeEvents();
}
},
callouts: {
// Callout renderer.
renderer: function(callout, storeItem) {
var text;

// Start off with the segment name, if 'showNameInCallout' in the store is true.
text = storeItem.get('showNameInCallout') ? storeItem.get('name') + '; ' : '';

// Append the 'calloutLabel' text from the store.
text += storeItem.get('calloutLabel');

// Set the text of the callout label.
callout.label.setAttributes({
text: text
}, true);
},
filter: function() {
return true; // give every slice a callout label
}
},
label: {
field: 'name',
display: 'rotate',
contrast: true,
font: '18px Arial'
}
}]
};