Welcome, Guest. Please login or register.
Did you miss your activation email?
31 Jul 2010, 11:40:58 UTC
Forum home
+  flexdeveloper.eu Forum
|-+  Flex and ActionScript 3.0
| |-+  Flex Charting (Moderators: JMWhittaker, Jan K, thewarpedcoder, James)
| | |-+  How to Customize a Datapoint in a Line Series
« previous next »
Pages: [1] Print
Author Topic: How to Customize a Datapoint in a Line Series (Read 1403 times)
klmanion
Newbie FD
*
Posts: 6


« on: 03 Mar 2010, 02:50:33 UTC »

I need to be able to customize/style a series datapoint in my line chart.  For each series I'm displaying, I need to enlarge or highlight (with different color) the newest datapoint based on the time the data was entered in the database.  

I've been trying to pick through the LineSeries.as file to figure out how flex plots each datapoint.  I thought that if I could find the location in the code where the points get plotted, I could customize the style applied to the point if a flag that I pass in from the database is set to yes for that point.  But so far, I haven't been able to find where this occurs.  

Has anybody out there had success styling a single datapoint of a line series?  Thanks in advance!

Kevin
« Last Edit: 03 Mar 2010, 02:52:37 UTC by klmanion » Logged
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #1 on: 03 Mar 2010, 13:29:56 UTC »

dataTipRenderer is your friend  Smiley

http://www.flexdeveloper.eu/forums/flex-charting/formatting-datatips/
Logged

klmanion
Newbie FD
*
Posts: 6


« Reply #2 on: 04 Mar 2010, 02:17:42 UTC »


But how do I go about using the dataTipRenderer for one specific point?  My points are automatically drawn by setting the series.dataProvider to the incoming arrayCollection.  How do I isolate the one point to use a custom dataTipRenderer without applying it to all the points in the series?
Logged
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #3 on: 04 Mar 2010, 14:29:23 UTC »

Hmm, chart.dataTipRenderer applies to all data points in a chart. What you could try doing is having 2 drawing routines in your dataTipRenderer object, then depending on the data sent into the renderer, you could draw the tip differently.
Logged

klmanion
Newbie FD
*
Posts: 6


« Reply #4 on: 04 Mar 2010, 23:21:27 UTC »

Thanks Flexy.  I'll give that a try tomorrow. 
For what it's worth to others out there, I had success today getting control of the newest point in my line series by using this line of code:

myLineChart.series[0].items[0]

I have lots of line series in my chart that I'm looping through, but for sake of example, the line above (without the looping code around it) gives me control of the first data point of the first series.  The first datapoint just happens to be the last point entered into the database because  I'm ordering the query according to time_entered descending.  After initializing the line above to an object variable, I can then display any of the data associated with that point.

My challenge now though is to control the dataTipRenderer based on whether it's the newest point in the series or not.
Logged
klmanion
Newbie FD
*
Posts: 6


« Reply #5 on: 06 Mar 2010, 14:14:54 UTC »

Just an update to my last post.  I didn't include all the necessary code.

The line:  myLineChart.series[0].items[0] should actually be...

var myPointObject:LineSeriesItem;
myPointObject = LineSeriesItem(myLineChart.series[0].items[0]);


Again, this gives me access to all of the data associated with the first datapoint in the first line series of the chart.

I've since figured out how to apply a custom style to just one point in a series, which was my reason for creating this whole thread in the first place.  I'll add another post here in case others want to know.
Logged
klmanion
Newbie FD
*
Posts: 6


« Reply #6 on: 27 Mar 2010, 03:06:44 UTC »

Probelm Solved!

In order to format one lineseries datapoint differently from the others, I created a custom CircleItemRenderer class, based on the one that Flex Builder provides.  This class gives you the ability to change the size and color of a datapoint.

Hopefully there are no spelling errors here.  I had to retype all this content at home because my office network is not connected to the internet and I also could not store it on any removable media.  I hope my retyping effort is useful for someone out there!

----------------------------------------------
----------------------------------------------
MY CLASS FILE:
----------------------------------------------
----------------------------------------------
package myComponents
{
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.charts.ChartItem;
import mx.charts.chartClasses.GraphicsUtilities;
import mx.charts.series.items.LineSeriesItem;
import mx.controls.Alert;
import mx.core.IDataRenderer;
import mx.graphics.IFill;
import mx.graphics.IStroke;
import mx.graphics.SolidColor;
import mx.skins.ProgrammaticSkin;
import mx.StyleManager;
import mx.utils.ColorUtil;

public class MyCircleItemRenderer extends ProgrammaticSkin implements IDataRenderer
{

   include "../Version.as";
   //-----------------------------------------------------
   // Class Variables
   //-----------------------------------------------------

   /**
    * @private
    */
   private static var rcFill:Rectangle = new Rectangle();

   //-----------------------------------------------------
   // Constructor
   //-----------------------------------------------------
   
   /**
    * Constructor.
    */
   public function MyCircleItemRender()
   {
      super();
   }

   //-----------------------------------------------------
   // Properties
   //-----------------------------------------------------

   /**
    * @private
    * Storage for the data property.
    */   
   private var _chartItem:Object;

   [Inspectable(environment="none")]

   /**
    * The chartItem that this itemRenderer displays.
    * This value is assigned by the owning series.
    */
   public function get data():Object
   {
      return _chartItem;
   }

   /**
    * @private
    */
   public function set data(value:Object):void
   {
      if (_chartItem == value)
         return;
      _chartItem = value;
   }

   //-------------------------------------------------
   // overridden methods
   //-------------------------------------------------

   /**
    * @private
    */
   override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
   {
      super.updateDisplayList(unscaledWidth, unscaledHeight);
      var fill:IFill;
      var state:String = "";
      var :uint;
      var adjustedRadius:NUmber = 0;
      var bgColor:uint = 0xFFFFFF;    //defaults datapoint fill color to white

      if (_chartItem is ChartItem && _chartItem.hasOwnProperty('fill'))
      {
         //Determine if the item is a line series item so we know whether or not it's a datapoint
         if (_chartItem is LineSeriesItem)
         {
            var myItem:LineSeriesItem = LineSeriesItem(_chartItem);
            if (myItem.index == 0)
            {  //it's the first datapoint in the series, so make it bigger.  The first series datapoint is always the newest based on how the database query is ordered
               adjustedRadius = 4;
               bgColor = 0xFEA100;  //sets datapoint fill color to orange
            }
         }
         fill = _chartItem.fill;
         state = _chartItem.currentState;
      }
      else
         fill = GraphicsUtilities.fillFromStyle(getStyle('fill'));

      switch(state)
      {
         case ChartItem.FOCUSED:
         case ChartItem.ROLLOVER:
            if(StyleMananger.isValidStyleValue(getStyle('itemRollOverColor')))
               color = getStyle('itemRollOverColor');
            else
               color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),-20);
            fill = new SolidColor(color);
            adjustedRadius = getStyle('adjustedRadius');
            if(!adjustedRadius)
               adjustedRadius = 0;
            break;
         case ChartItem.DISABLED:
            if(StyleMananger.isValidStyleValue(getStyle('itemDisabledColor')))
               color = getStyle('itemDisabledColor');
            else
               color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),20);

            fill = new SolidColor(GraphicsUtilities.colorFromFill(fill));
            break;
         case ChartItem.FOCUSEDSELECTED:
         case ChartItem.SELECTED:
            if(StyleMananger.isValidStyleValue(getStyle('itemSelectionColor')))
               color = getStyle('itemSelectionColor');
            else
               color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),-30);
            fill = new SolidColor(color);
            adjustedRadius = getStyle('adjustedRadius');
            if(!adjustedRadius)
               adjustedRadius = 0;
            break;
      }

      var stroke:IStroke = getStyle("stroke");
      var w:Number = stroke ? stroke.weight / 2 : 0;
      rcFill.right = unscaledWidth;
      rcFill.bottom = unscaledHeight;
      var g:Graphics = graphics;
      g.clear();
      if (stroke)
         stroke.apply(g);
      g.beginFill(bgColor);  //set the background color for the datapoint
      g.drawEllipse(w - adjustedRadius, w - adjustedRadius, unscaledWidth - 2 * w + adjustedRadius * 2, unscaledHeight - 2 * w + adjustedRadius * 2);
      g.endFill();
   }
}

}

         

--------------------------------------------------------------------
And here's how to apply the MyCircleItemRenderer class defined above
to the line series in your chart, using ActionScript.
I am plotting all my Line Series from a curveList array being passed to
Flex from a ColdFusion CFC.  I loop through this array and add each
curve (line series) to the chart, setting the itemRenderer to the custom class.
-----------------------------------------------------------------------------

private function curveListHandler(evnet:ResultEvent) {
   var curveList:ArrayCollection;  //array of curves to be plotted
   var curve:Object  //current curve in the loop
   var newSeries:LineSeries;
   curveList = new ArrayCollection(event.result as Array);
   for (var idx:Object in CurveList) {
      curve = curveList[idx];  //make a reference to the current curve
      newSeries = new LineSeries();
      newSeries.id = curve.ID;  //ID is a DB column in the curve result set from my CFC file
      newSeries.name = curve.NAME  //NAME is a DB column in the curve result set from my CFC file
      newSeries.dataProvider = curve.DATAPOINTS  //DATAPOINTS is an array of DB data from my CFC file   
      newSeries.yField = "YVAL"  //maps data to y-axis
      newSeries.yField = "XVAL"  //maps data to x-axis
      newSeries.sortOnXField = false;  //connect the points in order received instead of left to right
      newSeries.setStyle("itemRenderer", new ClassFactory(myComponents.MyCircleItemRenderer));  //assigns the custom class defined above
      //add new series to the chart
      var currentSeries:Array = myLineChart.series;
      currentSeries.push(newSeries);
      myLineChart.series = currentSeries;
   }
}




Logged
Pages: [1] Print
« previous next »
Share this on: Twitter Twitter Del.icio.us del.icio.us Digg Digg
Jump to:

©2006-2010 Flexdeveloper.eu/Jodie O'Rourke. All rights reserved.
Adobe®, Adobe® Flash™, Adobe® AIR™ and Adobe® Flex™ are registered trademarks of Adobe Systems Incorporated in the United States and other countries. All rights reserved.

Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC