I have a chart with a DateTime axis as my horizontal and a Linear Axis for my vertical inside a Adobe Flex Line Chart. I want to use a Cartesian Data Canvas as a background element and draw custom set of background graphics mostly rectangles. When I have more than a single data point, the graphics work perfectly since they are supposed to span the width of the entire chart.

When I have only a single data point, however, I can't seem to get the rectangles to draw. Since I want my rectangles to span the entire width of the chart, I was thinking that I could get the x-coordinates from my axis, but this isn't working.

var canvasWidth:Number = chtCanvas.width;
var canvasHeight:Number = chtCanvas.height; 
var minPt:Array;
var maxPt:Array;
var minPtDate:Date;
var maxPtDate:Date;
var minPtComplete:Point;
var maxPtComplete:Point;

// This works fine when there is more than 1 data point
minPt = chtCanvas.localToData(new Point(0, 0));
maxPt = chtCanvas.localToData(new Point(canvasWidth,canvasHeight));

//This does return a date object, but wont draw below 
minPtDate = axisDate.minimum;
maxPtDate = axisDate.maximum;

//This returns NaN for the x
minPtComplete = chtCanvas.dataToLocal(minPtDate, axisSalary.minimum);
maxPtComplete = chtCanvas.dataToLocal(maxPtDate, axisSalary.maximum);

// Also tried this.  Also returns NaN for the x value
//minPtComplete = chtCanvas.dataToLocal(axisDate.minimum, axisSalary.minumum);
//maxPtComplete = chtCanvas.dataToLocal(axisDate.maximum, axisSalary.maximum);

My actual drawing method is as follows:

// Tried this, works with points >2, does not draw with single data point
chtCanvas.drawRect(minPt[0], detail[i].MaxValue, maxPt[0], detail[i].MinValue);

//tried this, no effect with single point
//chtCanvas.drawRect(minPtDate, detail[i].MaxValue, maxPtDate, detail[i].MinValue);

// Tried this, no effect with single point
//chtCanvas.drawRect(minPtDate, minPt[1], maxPtDate, detail[i].MinValue);

// Tried this also
//chtCanvas.drawRect(minPtComplete.x, detail[i].MaxValue, maxPtComplete.x, detail[i].MinValue);

In this example, detail is an array collection of salary values and Im using the data value in the array to determine the vertical bounds of my rectangles.

I need to draw the rectangles the entire width of the chart (even when there is only a single data point). Thanks

1

There are 1 answers

0
Shawn On BEST ANSWER

Thanks to Heikki for his help. The following code works to use the axis values to draw on your Cartesian Data Canvas:

chtCanvas.drawRect(axisDate.minimum as Date, axisSalary.maximum, axisDate.maximum as Date, axisSalary.minimum);

Casting the values as Date really helped. The rest of the code used above is unecessary.

One thing to note, I was using a DateFormatter to format the date values from my data. What I didn't consider was that when using a DateTimeAxis, Flex will automatically add in extra dates to display on the axis. In my case, I was using a custom parse function to create MY points, but wasnt considering the points Flex was creating and also passing to my parse function (Therefore, they were not getting parsed correctly). Once I corrected this, the values laid out correctly in the case of multiple data points. I'm still having a bit of an issue with single data points and them not filling the chart entirely, but they are now drawing.

UPDATE: Although there are signs of life, the minimum and maximum are still not drawing the entire width of the chart in some cases depending on the dataUnits and labelUnits combination.

UPDATE #2: SOLVED Ok, so the axis does work as minimum/maximum values for the Cartesian Data Canvas but there is something important to remember. For a single point (and probably for multiple points as well, I just couldnt visually see the difference), when using a custom DateTimeAxis parse function such as what was in the Adobe Flex ASDoc tutorials:

private function axisDateParseFunction(item:String):Date
{   
     var inputDate:String = item;
     inputDate = fmtDate.format(inputDate);

     var newDate:Date = new Date();
     if(inputDate)
     {
        var a:Array = inputDate.split('/');
        newDate.fullYear = a[2];
        newDate.month = a[0] - 1;
        newDate.date = a[1];
        newDate.hours = 0;
        newDate.hoursUTC = 0;
        newDate.minutes = 0;
        newDate.minutesUTC = 0;
        newDate.seconds = 0;
        newDate.secondsUTC = 0;
        newDate.milliseconds = 0;
        newDate.millisecondsUTC = 0;

     }
     return newDate;

}

You MUST remember to set the UTC values as shown above also. Since the DateTimeAxis uses date AND time, when you create new Date objects, their time values also get set to the local system time. Remember to set those values to zero also or you will get points that dont exactly line up with your axis labels.