I'm using Flex for charting time series data. the data range is from 2002 to 2009, however the data is not available for some periods of time (i.e from 4/2004 to 8/2005). The following lines show the tags I'm using for the chart:
<mx:Canvas id="cp" backgroundColor="#ffffff" fontFamily="Verdana" fontSize="12" color="#093A89" fontWeight="bold" width="100%" height="100%" alpha="1" creationComplete="init()">
<mx:LineChart id="cChart" showDataTips="true" paddingRight="40" paddingLeft="30" width="100%" height="85%">
<mx:verticalAxis>
<mx:LinearAxis id="linearAxis" baseAtZero="false" title="{parameterLabel}" minorInterval="0.5" interval="1.0"/>
</mx:verticalAxis>
<mx:verticalAxisRenderers>
<mx:AxisRenderer axis="{linearAxis}" fontSize="10">
<mx:axisStroke>
<mx:SolidColorStroke weight="6" color="#BBCCDD" alpha="1" caps="square"/>
</mx:axisStroke>
</mx:AxisRenderer>
</mx:verticalAxisRenderers>
<mx:horizontalAxis>
<mx:DateTimeAxis id="ca" minimum="{sDate}" maximum="{eDate}" title="Date" dataUnits="days" dataInterval="1" labelUnits="days"/>
</mx:horizontalAxis>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer axis="{ca}" canDropLabels="true" fontSize="10" labelRotation="45">
<mx:axisStroke>
<mx:SolidColorStroke weight="6" color="#BBCCDD" alpha="1" caps="square"/>
</mx:axisStroke>
</mx:AxisRenderer>
</mx:horizontalAxisRenderers>
<mx:series>
<mx:LineSeries id="l1" visible="false"/>
</mx:series>
</mx:LineChart>
<mx:Legend id="mylgn" horizontalCenter="0" bottom="32"/>
<s:Label id="lblChart1" text="{dataType} {parameterLabel} at {streamLabel}" horizontalCenter="0" bottom="20"/>
<s:Label id="lblChart2" text="{optionalText}" horizontalCenter="0" bottom="5"/>
The following image illustrates the chart created by the above code:
As you can see there are gaps for the intervals with no data. Is there any way to remove/cut the intervals with no data? What is the best practice for this type of data?
Any thoughts or recommendation would be much appreciated
This is accomplished via an adapter to your dataProvider
.
To show a horizontal line between missing samples, you must add an additional sample to your data provider with value equal to the last sample.
If you had time series data of:
timestamp value
4/2004 3
8/2005 23
You would add an additional sample immediately before 8/2005 equal to the previous value of 3.
timestamp value
4/2004 3
7/2005 3 <-- insert sample
8/2005 23
Instead of interpolating between values 3 and 23, a flat horizontal line is displayed.
Sample data model
package
{
public class TrendData
{
public var timestamp:Date;
public var value:Number;
}
}
Static adapter utility
package
{
import mx.collections.ArrayList;
public class TimeSeriesDataAdapter
{
public static function interpolate(data:ArrayList):ArrayList
{
var set:ArrayList = new ArrayList();
var timespan:Number;
// add first sample:
set.addItem(data[0]);
for (var i:uint = 1; i < data.length; i++)
{
// measure timestamp between current sample and last sample
timespan = TrendData(data[i]).timestamp.time - TrendData(data[i-1]).timestamp.time;
// if the timespan is greater than desired range (1-day), add a sample
if(timespan >= 86400000)
{
var trendData:TrendData = new TrendData();
// set timestamp just before sample
trendData.timestamp = new Date(TrendData(data[i]).timestamp.time - 1);
// set value to previous value
trendData.value = TrendData(data[i-1]).value;
set.addItem(trendData);
}
set.addItem(data[i]);
}
return set;
}
}
}
Data Visualization implementation
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
[Bindable]
[ArrayElementType("TrendData")]
public var data:ArrayList
]]>
</fx:Script>
<mx:LineChart dataProvider="{TimeSeriesDataAdapter.interpolate(data)}" />
</s:Application>