You can create, destroy, and manipulate charts using ActionScript just as you can any other Flex component.
When working in Script blocks or in separate ActionScript class files, you must be sure to import all appropriate classes. The following set of import statements defines the most common cases:
import mx.collections.*; import mx.charts.*; import mx.charts.series.*; import mx.charts.renderers.*; import mx.charts.events.*;
To create a chart in ActionScript, use the new keyword. You can set properties on the chart object as you would in MXML. You assign a data provider with the dataProvider property. To add a data series to the chart, you define a new data series of the appropriate type. To apply the series to your chart, use the chart's series property. You can specify the category axis settings using the CategoryAxis class. The following example defines a BarChart control with two series:
<?xml version="1.0"?>
<!-- charts/CreateChartInActionScript.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="init()">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
import mx.charts.BarChart;
import mx.charts.series.BarSeries;
import mx.charts.CategoryAxis;
import mx.charts.Legend;
[Bindable]
public var expenses:ArrayCollection = new ArrayCollection([
{Month:"Jan", Profit:2000, Expenses:1500},
{Month:"Feb", Profit:1000, Expenses:200},
{Month:"Mar", Profit:1500, Expenses:500}
]);
public var myChart:BarChart;
public var series1:BarSeries;
public var series2:BarSeries;
public var legend1:Legend;
public function init():void {
// Create the chart object and set some
// basic properties.
myChart = new BarChart();
myChart.showDataTips = true;
myChart.dataProvider = expenses;
// Define the category axis.
var vAxis:CategoryAxis = new CategoryAxis();
vAxis.categoryField = "Month" ;
vAxis.dataProvider = expenses;
myChart.verticalAxis = vAxis;
// Add the series.
var mySeries:Array=new Array();
series1 = new BarSeries();
series1.xField="Profit";
series1.yField="Month";
series1.displayName = "Profit";
mySeries.push(series1);
series2 = new BarSeries();
series2.xField="Expenses";
series2.yField="Month";
series2.displayName = "Expenses";
mySeries.push(series2);
myChart.series = mySeries;
// Create a legend.
legend1 = new Legend();
legend1.dataProvider = myChart;
// Attach chart and legend to the display list.
p1.addChild(myChart);
p1.addChild(legend1);
}
]]></mx:Script>
<mx:Panel id="p1" title="Bar Chart Created in ActionScript"/>
</mx:Application>
The executing SWF file for the previous example is shown below:
This example replaces the existing Array of series with the new series.
You can use a similar technique to add data series to your charts rather than replacing the existing ones. The following example creates two ColumnSeries and sets their data providers. It then creates an Array that holds the existing chart series, and pushes the new series into that Array. Finally, it sets the value of the chart's series property to be the new Array of series.
<?xml version="1.0"?>
<!-- charts/AddingSeries.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
import mx.charts.series.ColumnSeries;
[Bindable]
private var profit04:ArrayCollection = new ArrayCollection([
{Month: "Jan", Profit: 2000},
{Month: "Feb", Profit: 1000},
{Month: "Mar", Profit: 1500}
]);
[Bindable]
private var profit05:ArrayCollection = new ArrayCollection([
{Month: "Jan", Profit: 2200},
{Month: "Feb", Profit: 1200},
{Month: "Mar", Profit: 1700}
]);
[Bindable]
private var profit06:ArrayCollection = new ArrayCollection([
{Month: "Jan", Profit: 2400},
{Month: "Feb", Profit: 1400},
{Month: "Mar", Profit: 1900}
]);
private var series1:ColumnSeries;
private var series2:ColumnSeries;
private function addMoreSeries():void {
if (!series1 || !series2) {
series1 = new ColumnSeries();
series1.dataProvider = profit05;
series1.yField = "Profit";
series1.xField = "Month";
series1.displayName = "2005";
series2 = new ColumnSeries();
series2.dataProvider = profit06;
series2.yField = "Profit";
series2.xField = "Month";
series2.displayName = "2006";
var currentSeries:Array = myChart.series;
currentSeries.push(series1);
currentSeries.push(series2);
myChart.series = currentSeries;
}
}
private function resetApp():void {
myChart.series = [ series0 ];
series1 = null;
series2 = null;
}
]]></mx:Script>
<mx:Panel title="Column Chart">
<mx:ColumnChart id="myChart" dataProvider="{profit04}" showDataTips="true">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="Month"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries dataProvider="{profit04}"
id="series0"
yField="Profit"
xField="Month"
displayName="2004"
/>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{myChart}"/>
</mx:Panel>
<mx:HBox>
<mx:Button id="b1" label="Add More Series To Chart" click="addMoreSeries()"/>
<mx:Button id="b2" label="Reset" click="resetApp()"/>
</mx:HBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
By using ActionScript, you can also define a variable number of series for your charts. The following example uses E4X syntax to extract an Array of unique names from the data. It then iterates over this Array and builds a new LineSeries for each name.
<?xml version="1.0"?>
<!-- charts/VariableSeries.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp();">
<mx:Script><![CDATA[
import mx.charts.series.LineSeries;
import mx.charts.DateTimeAxis;
[Bindable]
private var myXML:XML =
<dataset>
<item>
<who>Tom</who>
<when>08/22/2006</when>
<hours>5.5</hours>
</item>
<item>
<who>Tom</who>
<when>08/23/2006</when>
<hours>6</hours>
</item>
<item>
<who>Tom</who>
<when>08/24/2006</when>
<hours>4.75</hours>
</item>
<item>
<who>Dick</who>
<when>08/22/2006</when>
<hours>6</hours>
</item>
<item>
<who>Dick</who>
<when>08/23/2006</when>
<hours>8</hours>
</item>
<item>
<who>Dick</who>
<when>08/24/2006</when>
<hours>7.25</hours>
</item>
<item>
<who>Jane</who>
<when>08/22/2006</when>
<hours>6.5</hours>
</item>
<item>
<who>Jane</who>
<when>08/23/2006</when>
<hours>9</hours>
</item>
<item>
<who>Jane</who>
<when>08/24/2006</when>
<hours>3.75</hours>
</item>
</dataset>;
public function initApp():void {
var wholist:Array = new Array();
for each(var property:XML in myXML.item.who) {
// Create an Array of unique names.
if (wholist[property] != property)
wholist[property] = property;
}
// Iterate over names and create a new series
// for each one.
for (var s:String in wholist) {
// Use all items whose name matches s.
var localXML:XMLList = myXML.item.(who==s);
// Create the new series and set its properties.
var localSeries:LineSeries = new LineSeries();
localSeries.dataProvider = localXML;
localSeries.yField = "hours";
localSeries.xField = "when";
// Set values that show up in dataTips and Legend.
localSeries.displayName = s;
// Back up the current series on the chart.
var currentSeries:Array = myChart.series;
// Add the new series to the current Array of series.
currentSeries.push(localSeries);
// Add the new Array of series to the chart.
myChart.series = currentSeries;
}
// Create a DateTimeAxis horizontal axis.
var hAxis:DateTimeAxis = new DateTimeAxis();
hAxis.dataUnits = "days";
// Set this to false to display the leftmost label.
hAxis.alignLabelsToUnits = false;
// Take the date in its current format and create a Date
// object from it.
hAxis.parseFunction = createDate;
myChart.horizontalAxis = hAxis;
}
public function createDate(s:String):Date {
// Reformat the date input to create Date objects
// for the axis.
var a:Array = s.split("/");
// The existing String s is in the format "MM/DD/YYYY".
// To create a Date object, you pass "YYYY,MM,DD",
// where MM is zero-based, to the Date() constructor.
var newDate:Date = new Date(a[2],a[0]-1,a[1]);
return newDate;
}
]]></mx:Script>
<mx:Panel title="Line Chart with Variable Number of Series">
<mx:LineChart id="myChart" showDataTips="true"/>
<mx:Legend dataProvider="{myChart}"/>
</mx:Panel>
</mx:Application>
The executing SWF file for the previous example is shown below: