我有一个图表,X轴显示时间轴,Y轴显示对象的值。时间线值以“毫秒”为单位。我已经为用户提供了选择时间轴的方法,用户可以选择一天/周/月/月。因此,在我的图表中,我想显示所选范围的所有数据点,但希望限制X轴上显示的日期标签。对于Ex:如果用户选择一周,我想在X轴上显示Mon到Sun.如果用户选择一天,想要每隔3小时显示一个标签......
我想这是可能的,如果只是,我在运行时查看选定的时间范围,并根据开始(t1)和结束(t2)时间,我做出决定。 Flex的DateTimeAxis中是否有可用的API来实现这一目标?或者关于如何使其发挥作用的任何其他想法?
谢谢, 拉维
答案 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();
}