September 6th, 2007 by Kyle
Tags: charting, charting-legend, Flex, flex-charting, graphing, graphs, interactive, legend
Posted in: Flex
I worked on this sample with a customer to help debug some issues. I must confess, I don’t remember what I did and haven’t review the code to recall how this works, but it is a nice little sample. When you mouse over an item in the legend, the series in the chart glows and vice versa, when you mouse over an item in the chart, the corresponding item in the legend glows. Neato!
Here is the extension to the Legend class.
import mx.charts.LegendItem;
import flash.events.MouseEvent;
import mx.containers.Canvas;
import flash.geom.Rectangle;
import flash.display.DisplayObject;
import flash.display.Sprite;
public class myLegendItem extends LegendItem
{
private var bgElement:Canvas;
private var _highlight:Boolean;
public function myLegendItem()
{
super();
addEventListener(MouseEvent.MOUSE_OVER, handleEvent);
addEventListener(MouseEvent.MOUSE_OUT, handleEvent);
}
override protected function createChildren():void {
super.createChildren();
bgElement = new Canvas();
bgElement.setStyle("backgroundColor", 0×00ff00);
addChildAt(bgElement,0);
}
private function handleEvent(event:MouseEvent):void{
if(event.type == MouseEvent.MOUSE_OVER)
highlight = true;
else if(event.type == MouseEvent.MOUSE_OUT)
highlight = false;
}
public function set highlight(value:Boolean):void{
_highlight = value;
invalidateDisplayList()
}
protected override function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
graphics.clear();
graphics.beginFill(0,0);
graphics.drawRect(0,0,unscaledWidth,unscaledHeight);
graphics.endFill();
name = label;
bgElement.setActualSize(unscaledWidth, unscaledHeight);
if(_highlight)
bgElement.visible = true;
else
bgElement.visible = false;
}
}
}
Here is the app:
<!– Simple example to demonstrate the LineChart and AreaChart controls. –>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Stroke id="stroke1" weight="2" />
<mx:Stroke id="stroke2" weight="15" />
<mx:Sequence id="animate" >
<mx:AnimateProperty property="alpha" toValue="0.2" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="1" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="0.2" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="1" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="0.2" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="1" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="0.2" duration="{animateDuration}" />
<mx:AnimateProperty property="alpha" toValue="1" duration="{animateDuration}" />
</mx:Sequence>
<mx:Panel title="LineChart and AreaChart Controls Example"
height="100%" width="100%" layout="horizontal">
<mx:LineChart id="linechart" height="100%" width="100%"
paddingLeft="5" paddingRight="5"
showDataTips="true" dataProvider="{expensesAC}"
seriesFilters="[]">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="Month"/>
</mx:horizontalAxis>
<mx:series>
<mx:LineSeries yField="Profit" form="curve" displayName="Profitppp"
mouseOver="mouseOverSeries(event)" mouseOut="mouseOutSeries(event)" />
<mx:LineSeries yField="Expenses" form="curve" displayName="Expenses"
mouseOver="mouseOverSeries(event)" mouseOut="mouseOutSeries(event)" />
<mx:LineSeries yField="Amount" form="curve" displayName="Amount"
mouseOver="mouseOverSeries(event)" mouseOut="mouseOutSeries(event)"/>
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider="{linechart}" verticalGap="0" horizontalGap="0" markerWidth="50" markerHeight="4"
itemMouseOver="overLegend(event)" itemMouseOut="outLegend(event)" id="myLegend"
legendItemClass="myLegendItem">
</mx:Legend>
</mx:Panel>
<mx:Script>
<![CDATA[
import mx.charts.events.LegendMouseEvent;
import mx.collections.ArrayCollection;
[Bindable] private var animateDuration:Number = 60;
[Bindable]
private var expensesAC:ArrayCollection = new ArrayCollection( [
{ Month: "Jan", Profit: 2000, Expenses: 1500, Amount: 450 },
{ Month: "Feb", Profit: 1000, Expenses: 200, Amount: 600 },
{ Month: "Mar", Profit: 1500, Expenses: 500, Amount: 300 },
{ Month: "Apr", Profit: 1800, Expenses: 1200, Amount: 900 },
{ Month: "May", Profit: 2400, Expenses: 575, Amount: 500 } ]);
private function overLegend(event:LegendMouseEvent):void{
var lineSer:LineSeries = findSeries(event.item.label);
highlightSeries(lineSer);
}
private function outLegend(event:LegendMouseEvent):void{
var lineSer:LineSeries = findSeries(event.item.label);
animate.end();
lineSer.filters = [];
}
private function findSeries(lbl:String):LineSeries{
var series:LineSeries = new LineSeries()
for(var i:int=0;i<linechart.series.length;i++){
var tmpSeries:LineSeries = linechart.series[i];
if(tmpSeries.displayName == lbl)
series = tmpSeries;
}
return series;
}
private function mouseOverSeries(event:MouseEvent):void{
var lineSer:LineSeries = event.target as LineSeries;
highlightSeries(lineSer);
(myLegend.getChildByName(lineSer.displayName) as myLegendItem).highlight = true;
}
private function mouseOutSeries(event:MouseEvent):void{
var lineSer:LineSeries = event.target as LineSeries;
animate.end();
lineSer.filters = [];
(myLegend.getChildByName(lineSer.displayName) as myLegendItem).highlight = false;
}
private function highlightSeries(lineSer:LineSeries):void{
//set filter
var filter:GlowFilter = getBitmapFilter();
var myFilters:Array = new Array();
myFilters.push(filter);
lineSer.filters = myFilters;
// blink series
var target:Array = new Array();
target.push(lineSer);
animate.play(target);
}
private function getBitmapFilter():GlowFilter {
var color:Number = 0×00FF00;
var alpha:Number = 1;
var blurX:Number = 5;
var blurY:Number = 5;
var strength:Number = 5;
var inner:Boolean = false;
var knockout:Boolean = false;
var quality:Number = 5;
return new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout);
}
]]>
</mx:Script>
</mx:Application>
Here is a link to a Flex Builder 2.0.1 project (compiled with SDK hotfix2) containing a sample demonstrating the solution described above.











July 8th, 2008 at 3:02 pm
does not compile in flex 3