You want to draw a horizontal line across your columnChart which Y coordinate is based on your data, but the standard chart does not provide this functionality.
Use an ItemRenderer in your columnSeries that extends the UIComponent class and implement the IDataRenderer interface and uses the graphics class to draw the line across your chart.
You want to draw a horizontal like based on your data like the one shown below:
The red line is the average value of the values in the chart.
Similar to recipe "Using a programmatic renderer in your ColumnChart to set the color of your columnSeries based on your data" (http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&postId=2021&productId=2) you extend the IComponet class and implement the IDataRenderer interface.
This recipe uses the following dataProvider, and uses the AverageIncome field as the YAxis value in the horizontal line:
[Bindable]
public var dataCollection:ArrayCollection = new ArrayCollection([
{Month: "Jan", Income: 2000, AverageIncome:1620 },
{Month: "Feb", Income: 600, AverageIncome:1620},
{Month: "Mar", Income: 1500,AverageIncome:1620},
{Month: "Apr", Income: 2500, AverageIncome:1620},
{Month: "May", Income: 1500, AverageIncome:1620}]);
In addition to drawing a horizontal line, we are adding a label on the top of the lines to display the average value. So our ItemRenderer creates such label on its constructor.
Constructor in AverageLineRenderer.as
private var _label:Label; // A label to place on the top of the column.
public function AverageLineRenderer():void
{
super();
// Add the label
_label = new Label();
addChild(_label);
_label.setStyle("color",0x000000);
}
We define the setData method of the IDataRenderer where we assign data to a local chartItem variable. In addition, we assign the yValue to our label.
public function set data(value:Object):void
{
_chartItem = value as ColumnSeriesItem;
if(_chartItem != null)
{
// Assigns the yValue to the label
if (ColumnSeriesItem(_chartItem).yValue!=null)
_label.text = ColumnSeriesItem(_chartItem).yValue.toString();
else
_label.text="";
}
}
Finally we draw our horizontal line. Notice this is not different than drawing the original column. Except that we only do it for the first chartItem and we use parent.width and not width to draw the line. In this case, width would be the width of a single column and parent.width is the width of the chart.
Also notice that we are placing the label at the top of the line by changing the y coordinate in the move method:
_label.move(unscaledWidth ,-15 );
A negative number will place the label on the top of the line. If you want to place it under the line use zero.
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
if ( _chartItem.index ==0) // Do it only for the first chartItem
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
var g:Graphics = graphics;
g.clear();
g.beginFill(0xFF0000); // Red line, you can select your own color
// Draw the line across the chart. This is actually a rectangle with height 1.
g.drawRect(0,0,this.parent.width, 1);
g.endFill();
//Place the label
_label.setActualSize(_label.getExplicitOrMeasuredWidth(),_label.getExplicitOrMeasuredHeight());
_label.move(unscaledWidth ,-15 );
} }
Your chart definition looks like this:
<mx:ColumnChart id="myChart" dataProvider="{dataCollection}"
showDataTips="true" type="overlaid">
<mx:horizontalAxis>
<mx:CategoryAxis dataProvider="{dataCollection}"
categoryField="Month"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="Month" yField="Income" displayName="Income"/>
<mx:ColumnSeries xField="Month" yField="AverageIncome" displayName="Average"
itemRenderer="utils.AverageLineRenderer"/>
</mx:series>
</mx:ColumnChart>