在Flex中创建动态DateTimeAxis

时间:2012-01-12 06:53:02

标签: flex actionscript charts

我有一个图表,X轴显示时间轴,Y轴显示对象的值。时间线值以“毫秒”为单位。我已经为用户提供了选择时间轴的方法,用户可以选择一天/周/月/月。因此,在我的图表中,我想显示所选范围的所有数据点,但希望限制X轴上显示的日期标签。对于Ex:如果用户选择一周,我想在X轴上显示Mon到Sun.如果用户选择一天,想要每隔3小时显示一个标签......

我想这是可能的,如果只是,我在运行时查看选定的时间范围,并根据开始(t1)和结束(t2)时间,我做出决定。 Flex的DateTimeAxis中是否有可用的API来实现这一目标?或者关于如何使其发挥作用的任何其他想法?

谢谢, 拉维

2 个答案:

答案 0 :(得分:0)

我在尝试将DateTimeAxis弯曲到我的意愿时遇到了很多困难:-P

我发现的更常用于此类特殊情况的工作是extend CategoryAxis。您始终可以生成仅包含您关注的日期的数组,并将其用作类别轴。我不确定这是否适合你的情况,但这是我看的第一个地方。

这当然需要付出更多的努力,因为你需要自定义轴项目的显示看起来像日期或时间,但我认为它适用于自定义情况。

答案 1 :(得分:0)

好的,我在这里找到了解决问题的方法。类似于上面提到的@fotomut。我已经复制了'CategoryAxis'中的所有代码,除了重写'udpate()'方法。这是标签生成的地方。这是我的更新方法的实现,可能不是一个完美的解决方案....

但是,我在这里面临一个问题。出于某种原因,图形和标签看起来有点向右侧移动。我无法发布一张图片,比较我的CustomDateAxis和flex提供的CategoryAxis以更好地解释这一点,因为我被限制不上传任何文件。我想解决这个问题,但要找到解决方案......

if (!_labelSet)
{

    //I do not need label for each item in my dataprovider.
    //Hence creating a 'categoryValues' array with limited labels.
    var chartDP:ArrayCollection = this.dataProvider as ArrayCollection;
    var axisLabels:Array /* of AxisLabel */ = [];
    var labelsArr:Array = [];
    var categoryItems:Array = [];
    var dataMap:Object = {};
    _catMap = {};
    _categoryValues = [];
    _labelsMatchToCategoryValuesByIndex = [];

    if(chartDP.length != 0) {

        for(var indx:int=0; indx<chartDP.length; indx++){

            // Add each item to the map.
            //This is mandatory as it's being used internally to draw the Y-value
            _catMap[chartDP.getItemAt(indx).timeStamp.toString()] = indx;
        }

        var firstItem:Object = chartDP.getItemAt(0);
        var lastItem:Object = chartDP.getItemAt(chartDP.length - 1);
        var incrCounter:int; 

        var timeDiffInMillis:Number = (lastItem.timeStamp) - (firstItem.timeStamp);
        var arrIndx:int=0;
        if(timeDiffInMillis <= MILLISECONDS_IN_HOUR){
            LIMIT_LABEL_CNT = 12;
            INT_LBL_UNITS = "MINUTES";
        }else if(timeDiffInMillis > MILLISECONDS_IN_HOUR && timeDiffInMillis <= MILLISECONDS_IN_DAY){
            LIMIT_LABEL_CNT = 12;
            INT_LBL_UNITS = "HOURS";
        }else if(timeDiffInMillis > MILLISECONDS_IN_DAY && timeDiffInMillis <= MILLISECONDS_IN_WEEK){
            LIMIT_LABEL_CNT = 7;
            INT_LBL_UNITS = "DAYS";
        }else if(timeDiffInMillis > MILLISECONDS_IN_WEEK && timeDiffInMillis <= MILLISECONDS_IN_MONTH){
            LIMIT_LABEL_CNT = 4;
            INT_LBL_UNITS = "WEEKS";
        }else if(timeDiffInMillis > MILLISECONDS_IN_MONTH && timeDiffInMillis <= MILLISECONDS_IN_YEAR) {
            LIMIT_LABEL_CNT = 12;
            INT_LBL_UNITS = "MONTHS"
        }

        if(chartDP.length <= LIMIT_LABEL_CNT)
            incrCounter = 1;
        else
            incrCounter = chartDP.length/LIMIT_LABEL_CNT;
        var i:int=0;
        for(i=0,arrIndx=0; i<chartDP.length; i=i+incrCounter){

            arrIndx = i;
            _categoryValues[arrIndx] = chartDP.getItemAt(i).timeStamp; 
            dataMap[arrIndx] = chartDP.getItemAt(i);

            //There is a very good chance for the incrCounter to omit
            //the last items in the DataProvider.
            if((chartDP.length-i) <= incrCounter){
                arrIndx=arrIndx+incrCounter;
                _categoryValues[arrIndx] = chartDP.getItemAt(chartDP.length-1).timeStamp; 
                dataMap[arrIndx] = chartDP.getItemAt(chartDP.length-1);
            }
        }

        var min:Number = -_padding;
        var max:Number = _categoryValues.length - 1 + _padding;
        var alen:Number = max - min;
        var label:AxisLabel;

        var n:int = _categoryValues.length;
        if (_labelFunction != null)
        {
            var previousValue:Object = null;
            for (i=0; i<n; i++)
            {
                if (_categoryValues[i] == null)
                    continue;

                if(previousValue != null && _categoryValues[i] != null){
                    if(previousValue == _categoryValues[i])
                        continue;
                }
                label = new AxisLabel((i - min) / alen, _categoryValues[i],
                    timeLblFormatFunction(_categoryValues[i], previousValue,
                        this, dataMap[i]));
                _labelsMatchToCategoryValuesByIndex[i] = label;
                axisLabels.push(label);

                previousValue = _categoryValues[i];
            }
        }
        else
        {
            for (i = 0; i < n; i++)
            {
                if (!_categoryValues[i])
                    continue;

                label = new AxisLabel((i - min) / alen, _categoryValues[i],
                    _categoryValues[i].toString());
                _labelsMatchToCategoryValuesByIndex[i] = label;
                axisLabels.push(label);
            }               
        }
    }

    _labelSet = new AxisLabelSet();
    _labelSet.labels = axisLabels;
    _labelSet.accurate = true;
    _labelSet.minorTicks = minorTicks;
    _labelSet.ticks = generateTicks();          
}