当前位置: 动力学知识库 > 问答 > 编程问答 >

actionscript - Create Dynamic DateTimeAxis in Flex

问题描述:

I have a chart with X-axis showing timeline and Y-axis showing value for an object. The time line values are in 'milliseconds'. I have give the user a way to select timeline, user can select a day/week/month/months. So, in my Chart I want to show all the data points for the selected range but want to limit the date labels displayed on the X-axis. For Ex: if user selects a week, I want to display Mon to Sun on the X-axis. And if user selects a day, want to display a label for every 3 hrs like that...

I guess it is possible if only, I look at the selected time range at run-time and based on the starting (t1) and end (t2) time, I make a decision. Is there any API available in Flex's DateTimeAxis to achieve this ? Or any other ideas on how to get this working ?

Thanks,

Ravi

网友答案:

I have had a lot of difficulty trying to bend the DateTimeAxis to my will :-P

What I have found works more often for specialized situations like this is to extend the CategoryAxis. You can always generate an array of only the dates that you care about and use those as the category axis. I am not sure if this will work for your situation, but it is the first place I would look.

This will of course require a lot more effort, because you need to customize the display of the axis items to look like dates or times, but I think it works for custom situations.

网友答案:

Okay, Here I found a solutions for the problem. Similar to what @fotomut mentioned above. I have copied all the code from 'CategoryAxis' except rewrote the 'udpate()' method. This is where the labels get generated. Here is my implementation of update method, may not be a perfect solution....

But, I am facing an issue here. For some reason, the graph and labels looks a bit shifted towards the right hand side. I am unable to post a picture comparing my CustomDateAxis to flex provided CategoryAxis to better explain this, as I am restricted not to upload any files. I am trying to fix this, yet to find a solution...

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();          
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: