Displaying multiple axes for a single series in Flex charts

Subject:

Typically, this data is plotted like so, using Gnuplot or some similar plotting package.

Where one or more series are plotted where X values are wavelength/wavenumber and Y values are emissivities.

The two X-axes shown are simply different representations of the same scale where wavelength =1/wavenumber.

I was stumped as to how to render a chart with two axes for the same data, as the more common use case for multiple axes in Flex charting is to render multiple series with entirely different scales on the same chart.

It occurred to me then that while it's not possible to have multiple horizontalAxis declarations in the same chart, there's no reason you can use more than one AxisRenderer per axis.

There were three keys to duplicating the original plot in Flex, noted in the code comments below.

In the MXML:

<mx:horizontalAxisRenderers><!--
Adding multiple axes for the same lineseries isas
simple as adding multiple AxisRenderers with different
placement parameters.
--><mx:AxisRenderer axis="{primaryXaxis}" labelFunction="{primaryXaxisLabelFunc}" placement="bottom"/><mx:AxisRenderer axis="{primaryXaxis}" labelFunction="{secondaryXaxisLabelFunc}" placement="top"><!--
Because we want different titles for each X-axis we're
using a titleRenderer. Here all we want to do is change
the text of the title, so we're using an inline renderer
but you could subclass the ChartLabel class to create an
external renderer for more extensive changes.
--><mx:titleRenderer><mx:Component><mx:Label text="Wavelength (μm)"/></mx:Component></mx:titleRenderer></mx:AxisRenderer></mx:horizontalAxisRenderers>

And then to manipulate the labels for each axis, we create a custom labelFunction

/**
* To set the secondary X-axis to a different scale using the
* same data, we're applying a scaling factor to the label and
* returning it. We're also inverting as we do with the primary
* X-axis.
*
* To convert from wavenumber in cm-1 to wavelength in μm the
* formula is wavelength = 10000/wavenumber
*/privatefunction secondaryXaxisLabelFunc(axisrenderer:IAxisRenderer, label:String):String
{var labelAsNumber : Number = Number(label);if(isNaN(labelAsNumber))return label;return(axisFormatter.format(10000/labelAsNumber *-1));}