What should the LineChart do in this situation?
How can you draw a line with only 1 data point much less extrapolate the data??

Turns out that the Flex chart does not handle that very well. The solution?? Write your own lineSegmentRenderer.

Here is an example of a lineSegementRenderer that will just draw a circle for this case.

MyLineRenderer.as:

package
{
    import mx.charts.renderers.LineRenderer;
    import mx.charts.series.items.LineSeriesItem;   
    import mx.charts.series.renderData.LineSeriesRenderData;
    import mx.charts.series.items.LineSeriesSegment;   
    import mx.charts.renderers.CircleItemRenderer
    import flash.display.Graphics;
    import flash.geom.Rectangle;
    import mx.charts.ChartItem;
    import mx.charts.chartClasses.GraphicsUtilities;
    import mx.core.IDataRenderer;
    import mx.graphics.IFill;
    import mx.graphics.IStroke

    public class MyLineRenderer extends LineRenderer
    {
        private static var rcFill:Rectangle = new Rectangle();     
       
        public function MyLineRenderer()
        {
            super();
        }
       
        override protected function updateDisplayList(unscaledWidth:Number,
                                                      unscaledHeight:Number):void
        {
            var l:int=(data as LineSeriesSegment).items.length;
            if(l==1){          
                var item:LineSeriesItem=((data as LineSeriesSegment).items[0] as LineSeriesItem)
                var fill:IFill = GraphicsUtilities.fillFromStyle(getStyle("fill"));
                var stroke:IStroke = getStyle("stroke");
                       
                var w:Number = stroke ? stroke.weight / 2 : 0;
       
                rcFill.right = 2;
                rcFill.bottom = 2;
       
                var g:Graphics = graphics;
                g.clear();     
                if (stroke)
                    stroke.apply(g);
                if (fill)
                    fill.begin(g, rcFill);
                g.drawCircle(item.x, item.y, 3);
                if (fill)
                    fill.end(g);
            }
            else{
                super.updateDisplayList(unscaledWidth, unscaledHeight);        
            }   
        }      
    }
}
 

Read the rest of this post»


4 Comments »

September 6th, 2007 by Kyle
Tags: , , , , , , ,
Posted in: Flex

I worked on this sample with a customer to help debug some issues. I must confess, I don’t remember what I did and haven’t review the code to recall how this works, but it is a nice little sample. When you mouse over an item in the legend, the series in the chart glows and vice versa, when you mouse over an item in the chart, the corresponding item in the legend glows. Neato!

Here is the extension to the Legend class.

package{
import mx.charts.LegendItem;
import flash.events.MouseEvent;
import mx.containers.Canvas;
import flash.geom.Rectangle;
import flash.display.DisplayObject;
import flash.display.Sprite;

public class myLegendItem extends LegendItem
{
     private var bgElement:Canvas;
     private var _highlight:Boolean;
   
     public function myLegendItem()
     {
         super();

         addEventListener(MouseEvent.MOUSE_OVER, handleEvent);
         addEventListener(MouseEvent.MOUSE_OUT, handleEvent);
       
     }
     
     override protected function createChildren():void {
        super.createChildren();
        bgElement = new Canvas();
        bgElement.setStyle("backgroundColor", 0×00ff00);
        addChildAt(bgElement,0);
    }
   
    private function handleEvent(event:MouseEvent):void{
        if(event.type == MouseEvent.MOUSE_OVER)
            highlight = true;
        else if(event.type == MouseEvent.MOUSE_OUT)
            highlight = false;
    }
   
   
    public function set highlight(value:Boolean):void{
        _highlight = value;
        invalidateDisplayList()
    }
   
     protected override function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void{
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        graphics.clear();
        graphics.beginFill(0,0);
        graphics.drawRect(0,0,unscaledWidth,unscaledHeight);
        graphics.endFill();        

         name = label;
         bgElement.setActualSize(unscaledWidth, unscaledHeight);
         if(_highlight)
            bgElement.visible = true;
        else
            bgElement.visible = false;
            
               }
       }
}
 

Read the rest of this post»


1 Comment »