1

我正在使用 Flex 绘制时间序列数据图表。数据范围为 2002 年至 2009 年,但在某些时间段(即 4/2004 至 8/2005)数据不可用。以下几行显示了我用于图表的标签:

<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"/>

下图说明了上述代码创建的图表: 在此处输入图像描述

如您所见,没有数据的间隔存在间隙。有没有办法在没有数据的情况下删除/减少间隔?此类数据的最佳做法是什么?

任何想法或建议将不胜感激

4

2 回答 2

1

这是通过您的dataProvider.

要在缺失样本之间显示一条水平线,您必须向数据提供者添加一个附加样本,其值等于最后一个样本。

如果您有以下时间序列数据:

timestamp    value
4/2004       3
8/2005       23

您将在 8/2005 之前添加一个额外的样本,等于之前的值 3。

timestamp    value
4/2004       3
7/2005       3 <-- insert sample
8/2005       23

不是在值 3 和 23 之间进行插值,而是显示一条平坦的水平线。

样本数据模型

package
{
    public class TrendData
    {
        public var timestamp:Date;
        public var value:Number;
    }
}

静态适配器实用程序

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;
        }

    }
}

数据可视化实现

<?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>
于 2012-07-06T02:35:55.473 回答
0

我使用 Jason 的回答来解决图表中的差距问题。但是,为了使代码适合我的应用程序,我应用了以下更改。1- 我将 ArryList 替换为 ArrayCollection 2- 我没有使用 TrendData 类 3- 由于我提交的日期是字符串,我必须先将其转换为日期 4- 我认为 7 天或更长时间是一个间隔 5- 我必须在创建过多点之前对我的 ArrayCollection 进行排序。

下面显示了我的 TimeSeriesDataAdapter.interpolate 函数版本:

 public static function interpolate(data:ArrayCollection):ArrayCollection
 {
      var set:ArrayCollection = new ArrayCollection();
      var timespan:Number;
      var oneDayTime:Number = 86400000; // 1000*60*60*24 = 1 day
      for (var j:uint = 1; j < data.length; j++)
      {
           // measure timestamp between current sample and last sample
           data[j].formattedDate  = DateField.stringToDate(data[j].Date,"MM/DD/YYYY");
           data[j].time  = data[j].formattedDate.time;
      }
      var dataSortField:SortField = new SortField(); 
      dataSortField.name = "time"; 
      var numericDataSort:Sort = new Sort(); 
      numericDataSort.fields = [dataSortField]; 
      data.sort = numericDataSort; 
      data.refresh(); 
      // 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 = data[i].time - data[i-1].time;
           // if the timespan is greater than desired range (7-days), add a sample
           if(timespan >= oneDayTime*7) 
           {
                var trendData:Object = new Object();
                var timestamp:Date = new Date();
                trendData = data[i-1];
                // set timestamp just before sample
                timestamp.time = data[i].time - 1;
                trendData.Date = DateField.dateToString(timestamp,"MM/DD/YYYY");
                set.addItem(trendData);
           }
           set.addItem(data[i]);
      }
      return set;
 }
于 2012-07-06T23:34:31.073 回答