Friday, April 9, 2010

Flex 3: Pie Chart interactive Label

I have started exploring Flex 3 pie chart component few days back and i realize that the labels for pie chart is not interactive. There is no inbuilt events for pie chart label.

To make the label interactive of pie chart component i have extend the pie chart component. But It was really strange that there was no direct reference available to individual labels. Instead there is a reference to the labelContainer who hold all the labels. To achieve the label reference i have added the listener to the label container and check the current target is label field or not. and Then i have dispatched the custom label event.

Following snippet is for the custom pie chart component which i have extend from Pie chart.

File Name ClickableLabelPieChart.mxml

[Event(name="labelClick", type="events.ChartLabelEvent")]
[Event(name="labelDoubleClick", type="events.ChartLabelEvent")]
[Event(name="labelMouseDown", type="events.ChartLabelEvent")]
[Event(name="labelMouseUp", type="events.ChartLabelEvent")]
[Event(name="labelRollOver", type="events.ChartLabelEvent")]
[Event(name="labelRollOut", type="events.ChartLabelEvent")]
[Event(name="labelMouseMove", type="events.ChartLabelEvent")]

import mx.core.UITextField;
import mx.charts.series.PieSeries;
import events.ChartLabelEvent;

private var pieSeries:PieSeries;

private function addLabelEvents():void
pieSeries = this.series[0];
if (pieSeries)
pieSeries.labelContainer.addEventListener(MouseEvent.CLICK, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.DOUBLE_CLICK, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.MOUSE_DOWN, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.MOUSE_MOVE, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.MOUSE_OUT, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.MOUSE_OVER, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.MOUSE_UP, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.ROLL_OUT, dispatchLabelEventHandler);
pieSeries.labelContainer.addEventListener(MouseEvent.ROLL_OVER, dispatchLabelEventHandler);

private function dispatchLabelEventHandler(event:MouseEvent):void

if( is UITextField == false)

var currentLabel:UITextField = as UITextField
var chartEventType:String = '';
case MouseEvent.CLICK:
chartEventType = ChartLabelEvent.LABEL_CLICK;
case MouseEvent.DOUBLE_CLICK:
chartEventType = ChartLabelEvent.LABEL_DOUBLE_CLICK;
case MouseEvent.MOUSE_DOWN:
chartEventType = ChartLabelEvent.LABEL_MOUSE_DOWN;
case MouseEvent.MOUSE_MOVE:
chartEventType = ChartLabelEvent.LABEL_MOUSE_MOVE;
case MouseEvent.MOUSE_OUT:
chartEventType = ChartLabelEvent.LABEL_MOUSE_OUT;
case MouseEvent.MOUSE_OVER:
chartEventType = ChartLabelEvent.LABEL_MOUSE_OVER;
case MouseEvent.MOUSE_UP:
chartEventType = ChartLabelEvent.LABEL_MOUSE_UP;
case MouseEvent.ROLL_OUT:
chartEventType = ChartLabelEvent.LABEL_ROLL_OUT;
case MouseEvent.ROLL_OVER:
chartEventType = ChartLabelEvent.LABEL_ROLL_OVER;

this.dispatchEvent(new ChartLabelEvent(chartEventType, currentLabel));

I have used the custom event for label. For that i have created an Custom Event class based on MouseEvent

File Name

package events
import flash.display.InteractiveObject;
import flash.geom.Point;

import mx.core.UITextField;

public class ChartLabelEvent extends MouseEvent
public static const LABEL_CLICK:String = "labelClick";

public static const LABEL_DOUBLE_CLICK:String = "labelDoubleClick";

public static const LABEL_MOUSE_DOWN:String = "labelMouseDown";

public static const LABEL_MOUSE_MOVE:String = "labelMouseMove";

public static const LABEL_MOUSE_OUT:String = "labelMouseOut";

public static const LABEL_MOUSE_OVER:String = "labelMouseOver";

public static const LABEL_ROLL_OUT:String = "labelRollOut";

public static const LABEL_ROLL_OVER:String = "labelRollOver";

public static const LABEL_MOUSE_UP:String = "labelMouseUp";

private var _labelField:UITextField;

public function ChartLabelEvent(type:String, labelField:UITextField = null, triggerEvent:MouseEvent=null)
var relPt:Point;
if (triggerEvent &&
relPt = target.globalToLocal(
new Point(triggerEvent.localX, triggerEvent.localY)));
relPt = new Point(target.mouseX,target.mouseY);
relPt = new Point(0,0);

var bubbles:Boolean = true;
var cancelable:Boolean = false;
var relatedObject:InteractiveObject = null;
var ctrlKey:Boolean = false;
var shiftKey:Boolean = false;
var altKey:Boolean = false;
var buttonDown:Boolean = false;
var delta:int = 0;

bubbles = triggerEvent.bubbles;
cancelable = triggerEvent.cancelable;
relatedObject = triggerEvent.relatedObject;
ctrlKey = triggerEvent.ctrlKey;
altKey = triggerEvent.altKey;
shiftKey = triggerEvent.shiftKey;
buttonDown = triggerEvent.buttonDown;
delta =;
super(type, bubbles, cancelable, relPt.x, relPt.y, relatedObject, ctrlKey, altKey, shiftKey, buttonDown, delta);

this.labelField = labelField;

public override function clone():Event
return new ChartLabelEvent(type, labelField, this);

public function get labelField():UITextField
return _labelField;

public function set labelField(value:UITextField):void
_labelField = value;

Finally the application mxml. In this file i have added the custom Pie chart component and added all label mouse events on creation complete. On the mouse handler function, I have changed the Label color on roll over and roll out with background. On click the color of lable changes to green.


import mx.collections.ArrayCollection;
import events.ChartLabelEvent;
private function init():void
labelPieChart.addEventListener(ChartLabelEvent.LABEL_CLICK, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_DOUBLE_CLICK, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_MOUSE_DOWN, chartLabelMouseHandler);
//labelPieChart.addEventListener(ChartLabelEvent.LABEL_MOUSE_MOVE, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_MOUSE_OUT, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_MOUSE_OVER, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_MOUSE_OVER, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_MOUSE_UP, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_ROLL_OUT, chartLabelMouseHandler);
labelPieChart.addEventListener(ChartLabelEvent.LABEL_ROLL_OVER, chartLabelMouseHandler);
private function chartLabelMouseHandler(event:ChartLabelEvent):void
if(event.type == ChartLabelEvent.LABEL_MOUSE_OVER)
event.labelField.background = true;
event.labelField.backgroundColor = 0xFF0000;
event.labelField.textColor = 0xffff00;
}else if(event.type == ChartLabelEvent.LABEL_MOUSE_OUT)
event.labelField.background = false;
event.labelField.textColor = 0x000000;
}else if(event.type == ChartLabelEvent.LABEL_CLICK)
var color:uint = event.labelField.textColor != 0x00ff00 ? 0x00ff00 : 0x000000;
event.labelField.textColor = color;

private var fragments:ArrayCollection = new ArrayCollection([
{ Country: "USA", Gold: 35},
{ Country: "China", Gold: 32},
{ Country: "India", Gold: 5},
{ Country: "Brazil", Gold: 15},
{ Country: "Russia", Gold: 27}

private var _fillList:Array = [
new SolidColor(0xFF5B5B,0.9),
new SolidColor(0xA9FE5C,0.9),
new SolidColor(0xFEBD5C,0.9),
new SolidColor(0xFF8040,0.9),
new SolidColor(0x5BFFCA,0.9),

private function displayGold(data:Object, field:String, index:Number, percentValue:Number):String {
var temp:String= (" " + percentValue).substr(0,6);
return data.Country + ": " + "Total Gold: " + Math.round(data.Gold);

weight = "2"
color = "0x999999"
alpha = ".8"
caps = "square"/>

weight = "1"
color = "0xFFFFCC"
alpha = ".5"/>

color = "0x000000"
weight = "2"
alpha = ".5"/>
dataProvider = "{fragments}"
showDataTips = "true"
selectionMode = "single"
height = "100%"
width = "100%">

nameField = "Country"
labelPosition = "callout"
selectable = "true"
labelFunction = "displayGold"
calloutStroke = "{callouts}"
radialStroke = "{radial}"
stroke = "{pieborder}"
fills = "{_fillList}"/>

You can use these mouse event to make the label draggable. I will explain this in my next post where i will create an application which will have a functionality of changing the label by dragging from the list.


Post a Comment