Archive

Archive for September, 2010

GridLines, horizontalStroke with verticalFill problem.

September 29, 2010 Leave a comment

So the problem :

A chart with a GrileLines as backgroundElements. You want to display verticalFill and horizontal lines (by setting the style horizontalStroke), weird behaviour : the horizontal lines don’t appear…
After playing a couple of hours with all the styles and properties of the GridLines class, I finally got inside of the class and found the problem.

Explanations : GridLines draws first the horizontalFill, and the horizontal lines, and then on top of that draws the verticalFill and the vertical Lines. So, in some cases (depending on the color of the verticalFill and the alpha/color of the horizontal lines), the verticalFill hides the horizontal lines.

To solve the problem I overrided the updateDisplayList method of the GridLines class in order to draw the fills first, and the lines afterward.
Here the code :


import mx.charts.GridLines;
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.charts.chartClasses.CartesianChart;
import mx.charts.chartClasses.ChartElement;
import mx.charts.chartClasses.ChartState;
import mx.charts.chartClasses.GraphicsUtilities;
import mx.charts.chartClasses.IAxisRenderer;
import mx.charts.styles.HaloDefaults;
import mx.core.mx_internal;
import mx.graphics.IFill;
import mx.graphics.IStroke;
import mx.graphics.Stroke;
import mx.styles.CSSStyleDeclaration;

use namespace mx_internal;

/**
* Override of the GridLines class to correct a big.
* If an horizontal and vertical fill are applyed at the same time, and the horizontal and vertical lines drawn,
* the horizontal lines diseapear under the vertical fill.
*
* */
public class MyGridLines extends GridLines
{
public function MyGridLines()
{
super();
}

override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);

var len:int;
var c:Object;
var stroke:IStroke;
var changeCount:int;
var ticks:Array /* of Number */;
var spacing:Array /* of Number */;
var axisLength:Number;
var colors:Array /* of IFill */;
var rc:Rectangle;
var originStroke:IStroke;
var addedFirstLine:Boolean;
var addedLastLine:Boolean;

if (!chart||
chart.chartState == ChartState.PREPARING_TO_HIDE_DATA ||
chart.chartState == ChartState.HIDING_DATA)
{
return;
}

var g:Graphics = graphics;
g.clear();

var direction:String = getStyle("direction");
if (direction == "horizontal" || direction == "both")
{
stroke = getStyle("horizontalStroke");

changeCount = Math.max(1, getStyle("horizontalChangeCount"));
if ((changeCount * 0 != 0) || changeCount <= 1)
changeCount = 1;

var verticalAxisRenderer:IAxisRenderer;

if(!(CartesianChart(chart).verticalAxisRenderer))
{
verticalAxisRenderer = CartesianChart(chart).getLeftMostRenderer();
if(!verticalAxisRenderer)
verticalAxisRenderer = CartesianChart(chart).getRightMostRenderer();
}
else
verticalAxisRenderer = CartesianChart(chart).verticalAxisRenderer;

ticks = verticalAxisRenderer.ticks;

if (getStyle("horizontalTickAligned") == false)
{
len = ticks.length;
spacing = [];
for (var i:int = 1; i < len; i++)
{
spacing[i - 1] = (ticks[i] + ticks[i - 1]) / 2;
}
}
else
{
spacing = ticks;
}

addedFirstLine = false;
addedLastLine = false;

if (spacing[0] != 0)
{
addedFirstLine = true;
spacing.unshift(0);
}

if (spacing[spacing.length - 1] != 1)
{
addedLastLine = true;
spacing.push(1);
}

axisLength = unscaledHeight;

colors = [ getStyle("horizontalFill"),
getStyle("horizontalAlternateFill") ];

len = spacing.length;

if (spacing[len - 1] < 1)
{
c = colors[1];
if (c != null)
{
g.lineStyle(0, 0, 0);
GraphicsUtilities.fillRect(g, 0,
spacing[len - 1] * axisLength, unscaledWidth,
unscaledHeight, c);
}
}

for (i = 0; i < spacing.length; i += changeCount)
{
var idx:int = len - 1 - i;
c = colors[(i / changeCount) % 2];
var bottom:Number = spacing[idx] * axisLength;
var top:Number =
spacing[Math.max(0, idx - changeCount)] * axisLength;
rc = new Rectangle(0, top, unscaledWidth, bottom-top);

if (c != null)
{
g.lineStyle(0, 0, 0);
GraphicsUtilities.fillRect(g, rc.left, rc.top,
rc.right, rc.bottom, c);
}
}
}

if (direction == "vertical" || direction == "both")
{

stroke = getStyle("verticalStroke");
changeCount = Math.max(1,getStyle("verticalChangeCount"));

if (isNaN(changeCount) || changeCount <= 1)
changeCount = 1;

var horizontalAxisRenderer:IAxisRenderer;

if(!(CartesianChart(chart).horizontalAxisRenderer))
{
horizontalAxisRenderer = CartesianChart(chart).getBottomMostRenderer();
if(!horizontalAxisRenderer)
horizontalAxisRenderer = CartesianChart(chart).getTopMostRenderer();
}
else
horizontalAxisRenderer = CartesianChart(chart).horizontalAxisRenderer;

ticks = horizontalAxisRenderer.ticks.concat();

if (getStyle("verticalTickAligned") == false)
{
len = ticks.length;
spacing = [];
for (i = 1; i < len; i++)
{
spacing[i - 1] = (ticks[i] + ticks[i - 1]) / 2;
}
}
else
{
spacing = ticks;
}

addedFirstLine = false;
addedLastLine = false;

if (spacing[0] != 0)
{
addedFirstLine = true;
spacing.unshift(0);
}

if (spacing[spacing.length - 1] != 1)
{
addedLastLine = true;
spacing.push(1);
}

axisLength = unscaledWidth;

colors = [ getStyle("verticalFill"),
getStyle("verticalAlternateFill") ];

for (i = 0; i < spacing.length; i += changeCount)
{
c = colors[(i / changeCount) % 2];
var left:Number = spacing[i] * axisLength;
var right:Number =
spacing[Math.min(spacing.length - 1,
i + changeCount)] * axisLength;
rc = new Rectangle(left, 0, right - left, unscaledHeight);
if (c != null)
{
g.lineStyle(0, 0, 0);
GraphicsUtilities.fillRect(g, rc.left, rc.top,
rc.right, rc.bottom, c);
}
}
}

// ------------------------- after drawing the fills, we draw the lines, which solve a bug on the horizontalLines disapearing under the vertical fill !
if (direction == "horizontal" || direction == "both")
{
stroke = getStyle("horizontalStroke");

changeCount = Math.max(1, getStyle("horizontalChangeCount"));
if ((changeCount * 0 != 0) || changeCount <= 1)
changeCount = 1;

var verticalAxisRenderer:IAxisRenderer;

if(!(CartesianChart(chart).verticalAxisRenderer))
{
verticalAxisRenderer = CartesianChart(chart).getLeftMostRenderer();
if(!verticalAxisRenderer)
verticalAxisRenderer = CartesianChart(chart).getRightMostRenderer();
}
else
verticalAxisRenderer = CartesianChart(chart).verticalAxisRenderer;

ticks = verticalAxisRenderer.ticks;

if (getStyle("horizontalTickAligned") == false)
{
len = ticks.length;
spacing = [];
for (var i:int = 1; i < len; i++)
{
spacing[i - 1] = (ticks[i] + ticks[i - 1]) / 2;
}
}
else
{
spacing = ticks;
}

addedFirstLine = false;
addedLastLine = false;

if (spacing[0] != 0)
{
addedFirstLine = true;
spacing.unshift(0);
}

if (spacing[spacing.length - 1] != 1)
{
addedLastLine = true;
spacing.push(1);
}

axisLength = unscaledHeight;

colors = [ getStyle("horizontalFill"),
getStyle("horizontalAlternateFill") ];

len = spacing.length;

if (spacing[len - 1] < 1)
{
c = colors[1];
if (c != null)
{
g.lineStyle(0, 0, 0);
}
}

for (i = 0; i = -1) //round off errors
{
if (addedFirstLine && idx == 0)
continue;
if (addedLastLine && idx == (spacing.length-1))
continue;

stroke.apply(g);
g.moveTo(rc.left, rc.bottom);
g.lineTo(rc.right, rc.bottom);

}
}
}

if (direction == "vertical" || direction == "both")
{

stroke = getStyle("verticalStroke");
changeCount = Math.max(1,getStyle("verticalChangeCount"));

if (isNaN(changeCount) || changeCount <= 1)
changeCount = 1;

var horizontalAxisRenderer:IAxisRenderer;

if(!(CartesianChart(chart).horizontalAxisRenderer))
{
horizontalAxisRenderer = CartesianChart(chart).getBottomMostRenderer();
if(!horizontalAxisRenderer)
horizontalAxisRenderer = CartesianChart(chart).getTopMostRenderer();
}
else
horizontalAxisRenderer = CartesianChart(chart).horizontalAxisRenderer;

ticks = horizontalAxisRenderer.ticks.concat();

if (getStyle("verticalTickAligned") == false)
{
len = ticks.length;
spacing = [];
for (i = 1; i < len; i++)
{
spacing[i - 1] = (ticks[i] + ticks[i - 1]) / 2;
}
}
else
{
spacing = ticks;
}

addedFirstLine = false;
addedLastLine = false;

if (spacing[0] != 0)
{
addedFirstLine = true;
spacing.unshift(0);
}

if (spacing[spacing.length - 1] != 1)
{
addedLastLine = true;
spacing.push(1);
}

axisLength = unscaledWidth;

colors = [ getStyle("verticalFill"),
getStyle("verticalAlternateFill") ];

for (i = 0; i 0 && cache[0].y 0 && cache[0].x < unscaledWidth)
{
originStroke = getStyle("verticalOriginStroke");
originStroke.apply(g);
g.moveTo(cache[0].x - sWidth / 2, 0);
g.lineTo(cache[0].x - sWidth / 2, $height);
}
}
}
}

Categories: Uncategorized