The data canvas classes also let you add offsets to the position of data graphics. You do this by defining the data coordinates with the CartesianCanvasValue constructor rather than passing a data coordinate to the drawing or addDataChild() methods. When you define a data coordinate with the CartesianCanvasValue, you pass the data coordinate as the first argument, but you can pass an offset as the second argument.
The following example lets you specify an offset with an HSlider control. This offset is used when adding a data child to the canvas.
<?xml version="1.0"?>
<!-- charts/AddLabelsWithOffsetLines.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
import mx.charts.series.items.ColumnSeriesItem;
import mx.charts.ChartItem;
import mx.charts.chartClasses.CartesianCanvasValue;
[Bindable]
public var profits:ArrayCollection = new ArrayCollection([
{Month:"Jan", Profit:1300},
{Month:"Feb", Profit:750},
{Month:"Mar", Profit:1100},
{Month:"Apr", Profit:1000},
{Month:"May", Profit:980},
{Month:"Jun", Profit:1500},
{Month:"Jul", Profit:2060},
{Month:"Aug", Profit:1700},
{Month:"Sep", Profit:1690},
{Month:"Oct", Profit:2200},
{Month:"Nov", Profit:2550},
{Month:"Dec", Profit:3000}
]);
private function connectTwoPoints(month1:String,
value1:Number,
month2:String,
value2:Number
):void {
canvas.clear();
canvas.lineStyle(4,
0xCCCCCC,
.75,
true,
LineScaleMode.NORMAL,
CapsStyle.ROUND,
JointStyle.MITER,
2
);
canvas.moveTo(month1, value1);
canvas.lineTo(month2, value2);
l1.text = "Month: " + month1;
l2.text = "Profit: " + value1;
l3.text = "Month: " + month2;
l4.text = "Profit: " + value2;
chartHasLine = true;
}
private var s1:String = new String();
private var s2:String = new String();
private var v1:Number = new Number();
private var v2:Number = new Number();
// Set this to true initially so that the chart doesn't
// draw a line when the first item is clicked.
private var chartHasLine:Boolean = true;
private function handleChange(event:Event):void {
var sci:ColumnSeriesItem =
ColumnSeriesItem(myChart.selectedChartItem);
if (chartHasLine) {
canvas.clear();
s1 = sci.item.Month;
v1 = sci.item.Profit;
addLabelsToColumn(s1,v1);
chartHasLine = false;
} else {
s2 = sci.item.Month;
v2 = sci.item.Profit;
addLabelsToColumn(s2,v2);
connectTwoPoints(s1, v1, s2, v2);
}
}
[Bindable]
public var labelOffset:Number = 0;
[Bindable]
public var columnLabel:Label;
private function addLabelsToColumn(s:String, n:Number):void {
columnLabel = new Label();
columnLabel.setStyle("fontWeight", "bold");
columnLabel.setStyle("color", "0x660000");
columnLabel.text = s + ": " + "$" + n;
// Use the CartesianCanvasValue constructor to specify
// an offset for data coordinates.
canvas.addDataChild(columnLabel,
new CartesianCanvasValue(s, labelOffset),
new CartesianCanvasValue(n, labelOffset)
);
}
]]></mx:Script>
<mx:Panel title="Column Chart">
<mx:ColumnChart id="myChart"
dataProvider="{profits}"
selectionMode="single"
change="handleChange(event)"
>
<mx:annotationElements>
<mx:CartesianDataCanvas id="canvas" includeInRanges="true"/>
</mx:annotationElements>
<mx:horizontalAxis>
<mx:CategoryAxis
dataProvider="{profits}"
categoryField="Month"
/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries
id="series1"
xField="Month"
yField="Profit"
displayName="Profit"
selectable="true"
/>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{myChart}"/>
<mx:Button id="b1"
label="Connect Two Points"
click="connectTwoPoints('Jan', 1300, 'Dec', 3000);"
/>
<mx:HBox>
<mx:VBox>
<mx:Label text="First Item"/>
<mx:Label id="l1"/>
<mx:Label id="l2"/>
</mx:VBox>
<mx:VBox>
<mx:Label text="Second Item"/>
<mx:Label id="l3"/>
<mx:Label id="l4"/>
</mx:VBox>
</mx:HBox>
<mx:HSlider id="hSlider" minimum="-50" maximum="50" value="0"
dataTipPlacement="top"
tickColor="black"
snapInterval="1" tickInterval="10"
labels="['-50','0','50']"
allowTrackClick="true"
liveDragging="true"
change="labelOffset=hSlider.value"
/>
</mx:Panel>
</mx:Application>
The executing SWF file for the previous example is shown below:
A CartesianDataCanvas is specific to a certain data space, which is defined by the bounds of the axis. If no axis is specified, the canvas uses the primary axes of the chart as its bounds. If you have a chart with multiple axes, you can specify which axes the data canvas should use by setting the values of the horizontalAxis or verticalAxis properties, as the following example illustrates:
<ColumnChart width="100%" height="100%" creationComplete="createLabel();">
<annotationElements>
<CartesianDataCanvas id="canvas"
includeInRanges="true"
horizontalAxis={h1}
verticalAxis={v1}/>
</annotationElements>
...
</ColumnChart>