Exploding Pie Charts
Flex is good, but see trying to get that last few bits out of it at times can be a pain. Take pie charts and the legends. What was required was a simple pie chart with the middle cut out (doughnut chart) and when you moused over the appropriate legend item it would expand the matching item in the pie chart. Surely that would be simple, yeah. Nope, it wasn’t and what I’ve done feels like a hack, but it works.
I’m not going to cover the creation of pie charts, if you want to know that then check out
and
http://blog.flexexamples.com/2007/11/06/exploding-wedges-in-a-flex-piechart-control/
So how did I do the exploding and keep it smooth?
Well first you must make sure the Lengend is listening for the itemMouseOver and Out event
After that you implement the over and out functions. Although you can get the itemMouseOver event you do not actual get a reference/index to what you have just moused over that you can use, so you have to go through the PieSeries data and check its labels against the label that comes with the event. Once you have that you can set the wedge explode radius (perWedgeExplodeRadius).
I also change the alpha value just to make things look a bit better. I also set a over flag so that if you mouse over the label/marker then mouse over it again you stop any flickering. If you mouse over the marker -> label this will result in a item mouse out & over event even though its the same item.
At the same time if an itemMouseOut event occurs i start a short timer before resetting the exploded radius. Again this just helps things look a little smoother.
private var pieSeries : PieSeries;
//Boolean value to make sure that the animation is smooth and that the correct item is exploded.
//the item out event gets fired when the mouse moves from label to the marker
private var over : Boolean = false;
//explode the section of the chart that was just moused over in the legend
private function explode(event : LegendMouseEvent) : void {
if(delayTimer){//this will stop the legend, pie chart flickering as the user moves mouse from the label to the marker
delayTimer.stop();
delayTimer.removeEventListener(TimerEvent.TIMER, callAfterDelay);
}
var len : Number = PieSeries(event.item.source).legendData.length;
var index : Number = 0;
var arr:Array = new Array(len);
if(over){
event.item.alpha = 0.70;
} else {
event.item.alpha = 0.70;
for(var i : Number = 0; i < len ; i++){
//set the explode radius on the item that fired the over event
//and make sure that the rest of the exploded radii are 0
if(event.item.label == event.item.source.legendData[i].label){
index = i;
arr[i] = 0.1;
}else {
arr[i] = 0;
}
}
PieSeries(event.item.element).perWedgeExplodeRadius = arr;
over = true;//set the flag to true
}
}
//on the mouse out event this gets called, start a timer in case the user is just moving from label to marker or vice-versa
private function implode(event : LegendMouseEvent) : void {
delayTimer = new Timer(200, 1);
delayTimer.addEventListener(TimerEvent.TIMER, callAfterDelay, false, 0, true);
delayTimer.start();
pieSeries = PieSeries(event.item.element);
over = false;//if you don't reset this then when the user moves the mouse down the list nothing will happen
}
//This gets called if the timer has finished (mouse has been of legend for a set amount of time)
private function callAfterDelay(event : TimerEvent) : void {
var arr : Array = [];
pieSeries.perWedgeExplodeRadius = arr;
}
Thats it, hopefully that will help someone.
Check out part 2 of this explanation here. Part 2 explains the circular effect and how to do the labels for the legend.
[ad name="ad-1"]
6 Replies to “Exploding Pie Charts”
You forgot to show how you get that nice effect. With a “showDataEffect”. Another question. How do you get those (..%) in the legend label?
check out http://kennethsutherland.com/2009/05/27/exploding-pie-charts-part-2/
Hi,Thanks Good Post
Hi! When legend has horizontal direction, it flickers. Is it possible to correct this?
Hi Kenneth,
Good post and nice explanation.
How do we get the PieSeries fill color information inside the Legend ? So that I can change the color of my LegendText based on the PieColor .
I’ve tried accessing super.element in my custom LegendItem class. However I could not find it.
Need your help.