One potential problem when using more than one data series
in a single chart is that if the scales of the data are very different,
the data points might be plotted in very different areas on the
chart’s canvas. For example, one stock price could trade in the
range of $100 to $150, while another stock price could fluctuate
from $2 to $2.50. If you plot both stocks in the same chart, it
would be difficult to see any correlation between the prices, even
with a logarithmic axis.
To work around this problem, you can use multiple axes in your
charts so that each data series is positioned relative to its own
axis. All chart controls that are subclasses of CartesianChart support
adding additional sets of data on a additional scales in the horizontal
axis, vertical axis, or both. (This applies to all charts except
the PieChart control.)
You can use values on the additional axes to compare multiple sets
of data that are on different scales, such as stock prices that
trade in different ranges.
The following example shows a stock price that trades within
a $40 to $45 range, and another stock price that trades within a
$150 to $160 range. The values of the axis on the left show the
range of values of the first stock, and the values of the axis on
the right show the range of values of the second stock.
To use multiple axes in a chart, you first define the chart’s
series and their axes. For example, for a chart that mixes columns
with a line, you would have a ColumnSeries and LineSeries. For each
of these, you would likely also define the vertical axis, as the
following example shows:
You then define the axis renderers, and bind their axis properties
to the series’ axes. In this case, you define two vertical axis
renderers, and bind them to the LinearAxis objects.
Note that you control the location of the axis by using the placement property of
the AxisRenderer. For vertical axis renderers, valid values are left and right. For
horizontal axis renderers, valid values are top and bottom.
Axes can be independent of the series definition, too. For example,
you can also point more than one series to the same axis. In this
case, you could define a horizontal axis, as follows:
The final result is a chart with multiple axes, but whose series
share some of the same properties defined by common axis renderers.
<?xml version="1.0"?>
<!-- charts/MultipleAxes.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="srv_fe.send();srv_strk.send()"
height="600">
<fx:Declarations>
<!-- To see data in an HTML table, go to http://aspexamples.adobe.com/chart_examples/stocks.aspx -->
<!-- View source of the following pages to see the structure of the data that Flex uses in this example. -->
<mx:HTTPService id="srv_fe" url="http://aspexamples.adobe.com/chart_examples/stocks-xml.aspx?tickerSymbol=FE"/>
<mx:HTTPService id="srv_strk" url="http://aspexamples.adobe.com/chart_examples/stocks-xml.aspx?tickerSymbol=STRK"/>
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:Panel title="Multiple Axes with Multiple Data Series"
width="400" height="400">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<mx:ColumnChart id="myChart"
showDataTips="true"
height="250"
width="350">
<mx:horizontalAxis>
<mx:DateTimeAxis id="h1" dataUnits="days"/>
</mx:horizontalAxis>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer placement="bottom" axis="{h1}"/>
</mx:horizontalAxisRenderers>
<mx:verticalAxisRenderers>
<mx:AxisRenderer placement="left" axis="{v1}"/>
<mx:AxisRenderer placement="right" axis="{v2}"/>
</mx:verticalAxisRenderers>
<mx:series>
<mx:ColumnSeries
dataProvider="{srv_fe.lastResult.data.result}"
xField="date"
yField="close"
displayName="FE">
<mx:verticalAxis>
<mx:LinearAxis id="v1" minimum="2" maximum="5"/>
</mx:verticalAxis>
</mx:ColumnSeries>
<mx:LineSeries
dataProvider="{srv_strk.lastResult.data.result}"
xField="date"
yField="close"
displayName="STRK">
<mx:verticalAxis>
<mx:LinearAxis id="v2" minimum="40" maximum="50"/>
</mx:verticalAxis>
</mx:LineSeries>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{myChart}"/>
</s:Panel>
</s:Application>
The executing SWF file for the previous example is shown below:
Even if the verticalAxisRenderers or horizontalAxisRenderers properties
have not been specified, Cartesian charts will create default horizontal and
vertical axis renderers based on the default axes of the chart.
When using multiple axes, it is important to recognize that it
will not necessarily be immediately apparent which axis applies
to which data set in the chart. As a result, you should try to style
the axes so that they match the styles of the chart items.
The following example defines two colors and then uses those
colors in the axis renderers and in the strokes and fills for the
chart items:
<?xml version="1.0"?>
<!-- charts/StyledMultipleAxes.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="srv_fe.send();srv_strk.send()"
height="600">
<fx:Script>
<![CDATA[
[Bindable]
public var c1:Number = 0x224488;
[Bindable]
public var c2:Number = 0x884422;
]]>
</fx:Script>
<fx:Declarations>
<!-- To see data in an HTML table, go to http://aspexamples.adobe.com/chart_examples/stocks.aspx -->
<!-- View source of the following pages to see the structure of the data that Flex uses in this example. -->
<mx:HTTPService id="srv_fe" url="http://aspexamples.adobe.com/chart_examples/stocks-xml.aspx?tickerSymbol=FE"/>
<mx:HTTPService id="srv_strk" url="http://aspexamples.adobe.com/chart_examples/stocks-xml.aspx?tickerSymbol=STRK"/>
<mx:SolidColorStroke id="h1Stroke" color="{c1}"
weight="8" alpha=".75" caps="square"/>
<mx:SolidColorStroke id="h2Stroke"
color="{c2}" weight="8" alpha=".75" caps="square"/>
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:Panel title="Multiple Axes with Multiple Data Series"
width="400" height="400">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<mx:ColumnChart id="myChart"
showDataTips="true"
height="250" width="350">
<mx:horizontalAxis>
<mx:DateTimeAxis id="h1" dataUnits="days"/>
</mx:horizontalAxis>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer placement="bottom" axis="{h1}"/>
</mx:horizontalAxisRenderers>
<mx:verticalAxisRenderers>
<mx:AxisRenderer placement="left" axis="{v1}">
<mx:axisStroke>{h1Stroke}</mx:axisStroke>
</mx:AxisRenderer>
<mx:AxisRenderer placement="right" axis="{v2}">
<mx:axisStroke>{h2Stroke}</mx:axisStroke>
</mx:AxisRenderer>
</mx:verticalAxisRenderers>
<mx:series>
<mx:ColumnSeries
dataProvider="{srv_fe.lastResult.data.result}"
xField="date" yField="close"
displayName="FE">
<mx:verticalAxis>
<mx:LinearAxis id="v1" minimum="2" maximum="5"/>
</mx:verticalAxis>
<mx:fill>
<mx:SolidColor color="{c1}"/>
</mx:fill>
</mx:ColumnSeries>
<mx:LineSeries
dataProvider="{srv_strk.lastResult.data.result}"
xField="date" yField="close"
displayName="STRK">
<mx:verticalAxis>
<mx:LinearAxis id="v2" minimum="40" maximum="50"/>
</mx:verticalAxis>
<mx:lineStroke>
<mx:SolidColorStroke color="{c2}" weight="4" alpha="1"/>
</mx:lineStroke>
</mx:LineSeries>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{myChart}"/>
</s:Panel>
</s:Application>
The executing SWF file for the previous example is shown below:
You can customize labels by using the labelFunction property
of the AxisRenderer class. This lets you control the labels if you
use multiple axes. For more information, see Customizing axis labels.
For CartesianChart controls, there is no limit to the number
of axes you can have.
For PolarChart controls, such as a PieChart, you generally do
not use multiple axes because even though each series could have
its own angular axis, the angular axis is always from 0 to 360 (the
size of the wedge).