Not yet rated
Tags:



Problem

DataDrawingCanvas from Ely Greenfield does have beginFill() and beginBitmapFill(), but misses beginGradientFill() and beginShaderFill(). Same with the CartesianDataCanvas and PolarDataCanvas present in Flex since SDK 3.0 which are derived from it.

Solution

Modify the DataDrawingCanvas and OpCode classes. Add the BEGIN_GRADIENT_FILL, BEGIN_SHADER_FILL, LINE_BITMAP_STYLE, LINE_GRADIENT_STYLE and LINE_SHADER_STYLE constants to the OpCode class. Modify the collectValues() and render() methods implementation to use them. Add the beginGradientFill(), beginShaderFill(), lineBitmapStyle(), lineGradientStyle() and lineShaderStyle() methods in the DataDrawingCanvas class.

Detailed explanation


In the OpCode class, add:

public static const BEGIN_GRADIENT_FILL  :int = 14;
public static const BEGIN_SHADER_FILL    :int = 15;
public static const LINE_BITMAP_STYLE    :int = 16;
public static const LINE_GRADIENT_STYLE  :int = 17;
public static const LINE_SHADER_STYLE    :int = 18;



Edit the collectValues() method and add:

case BEGIN_GRADIENT_FILL:
                    split(params.x);
                    if(_data != undefined)
                        cache.storeX(_data,-_offset,_offset);
                    split(params.y);
                    if(_data != undefined)
                        cache.storeY(_data,-_offset,_offset);
                    break;
case BEGIN_SHADER_FILL:
                    split(params.x);
                    if(_data != undefined)
                        cache.storeX(_data,-_offset,_offset);
                    split(params.y);
                    if(_data != undefined)
                        cache.storeY(_data,-_offset,_offset);
                    break;

NB: LINE_STYLE does not need any code in collectValue(), neither do LINE_BITMAP_STYLE, LINE_GRADIENT_STYLE or LINE_SHADER_STYLE.


Edit the render() method and add:
 

public function render(target:DataDrawingCanvas,cache:DataCache):void
{
            ...
            var m:Matrix;
            var d:*;

            if(params.matrix == null)
                m = new Matrix();
            else
                m = params.matrix.clone();
          
            d = data(params.x);
            if(d != undefined)
                m.tx = cache.x(d);
            m.tx  += offset(params.x);
            d = data(params.y);
            if(d != undefined)
                m.ty = cache.y(d);
            m.ty += offset(params.y);
            ...

case BEGIN_GRADIENT_FILL:
                                      
                    g.beginGradientFill(params.type, params.colors, params.alphas, params.ratios, m, params.spreadMethod, params.interpolationMethod, params.focalPointRatio);                   
                    break;
               
case BEGIN_SHADER_FILL:
                   
                    g.beginShaderFill(params.shader, m);                   
                    break;
               
case LINE_BITMAP_STYLE:
                   
                    g.lineBitmapStyle(params.bitmapData,m,params.repeat,params.smooth);
                    break;
               
case LINE_GRADIENT_STYLE:

                    g.lineGradientStyle(params.type,params.colors,params.alphas,params.ratios,m,params.spreadMethod,params.joints,params.focalPointRatio);
                    break;
               
case LINE_SHADER_STYLE:
                   
                    g.lineShaderStyle(params.shader, m);
                    break;


In the DataDrawingCanvas class, add the beginGradientFill() , beginShaderFill(), lineBitmapStyle(), lineGradientStyle() and lineShaderStyle() methods.

public function beginGradientFill(type:String, colors:Array, alphas:Array, ratios:Array,x:* = undefined,y:* = undefined, matrix:Matrix = null, spreadMethod:String = "pad", interpolationMethod:String = "rgb", focalPointRatio:Number = 0):void {
            pushOp(EnhancedCartesianOpCode.BEGIN_GRADIENT_FILL, {type:type, x:x, y:y, colors:colors, alphas:alphas, ratios:ratios, matrix:matrix, spreadMethod:spreadMethod, interpolationMethod:interpolationMethod, focalPointRatio:focalPointRatio});            
}

public function beginShaderFill(shader:Shader,x:* = undefined,y:* = undefined, matrix:Matrix = null):void {
            pushOp(EnhancedCartesianOpCode.BEGIN_SHADER_FILL, {shader:shader, x:x, y:y, matrix:matrix});            
}
public function lineBitmapStyle(bitmapData:BitmapData, matrix:Matrix, repeat:Boolean, smooth:Boolean):void
{
            pushOp(OpCode.LINE_BITMAP_STYLE,{bitmapData:bitmapData, matrix:matrix, repeat:repeat, smooth:smooth} );
}
public function lineGradientStyle(type:String, colors:Array, alphas:Array, ratios:Array, matrix:Matrix, spreadMethod:String, joints:String, focalPointRatio:Number):void
{
            pushOp(OpCode.LINE_GRADIENT_STYLE,{type:type, colors:colors, alphas:alphas, ratios:ratios, matrix:matrix, spreadMethod:spreadMethod, joints:joints, focalPointRatio:focalPointRatio} );
}
public function lineShaderStyle(shader:Shader, matrix:Matrix):void
{
            pushOp(OpCode.LINE_SHADER_STYLE,{shader:shader, matrix:matrix} );
}

It is easy to copy Ely Greenfield's classes and modify the DataDrawingCanvas and OpCode classes implementation. But now, what if tou want to apply the same modifications to the CartesianDataCanvas and PolarDataCanvas classes in the Flex SDK ? You can either 1. Extend these classes or 2. Copy them, modify them and use registerClass in your application preloader in order to register your own implementation of these classes before the Flex framework initializes (use a static initializer in that case).


NB: The documentation states that beginGradientFill() exists in CartesianDataCanvas and PolarDataCanvas but this is still not true as of Flex SDK 4.5.1


Example of use:

// The DataDrawingCanvas instance allows you draw graphics in the data background using data coordinates as opposed to pixel ones
        public var background:DataDrawingCanvas;

            var matrix:Matrix = new Matrix();
            matrix.createGradientBox(this.width, this.height, Math.PI / 2, 0, 0);
           
            if(topSectionFillColorsData && topSectionFillAlphasData && topSectionFillRatiosData && isTopSectionFillChanged)
            {                
                background.beginGradientFill(GradientType.LINEAR, topSectionFillColorsData, topSectionFillAlphasData, topSectionFillRatiosData, Edge.LEFT, physicalLimit, matrix);
                background.moveTo(Edge.LEFT, physicalLimit);
                background.lineTo(Edge.RIGHT, physicalLimit);
                background.lineTo(Edge.RIGHT, safeOperationLevel);
                background.lineTo(Edge.LEFT, safeOperationLevel);
                background.lineTo(Edge.LEFT, physicalLimit);
                background.endFill();
            }

Links:

DataDrawingCanvas
http://flexsamples.blogspot.com/2008/04/flex-easy-custom-charts.html


CartesianDataCanvas
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/chartClasses/CartesianDataCanvas.html


PolarDataCanvas
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/charts/chartClasses/PolarDataCanvas.html

 


+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes