Avg. Rating 3.8

Problem

You want to set the color of your columnSeries in your ColumnChart based on your data.

Solution

Use an ItemRenderer in your columnSeries that extends the UIComponent class and implement the IDataRenderer interface

Detailed explanation

  Flex assigns different colors to the columnSeries in a ColumnChart by default. For example the chart below shows a columnChart with two columnSeries. Flex assigns orange and green to the columns respectively.

 

You can select your own colors by using a CSS. For example a CSS like this:

   <mx:Style>
   ColumnChart {
       chartSeriesStyles: Series1, Series2;
   }
   .Series1 {
       fill: #F09905;
   }
   .Series2 {
       fill: #221133;
   }
   </mx:Style>

 

  would make the columnChart to look like this:

 

 

However if you want to set the colors based on some conditional criteria using the data in the chart dataProvider, you need to use a custom ItemRenderer. 

In the ItemRenderer you need to do two things, get access to the data in the dataProvider sent to the ItemRender using the  chartItem class , and in second place you need to draw the column and choose a color for it based on your data.

To accomplish the first step your ItemRenderer needs to implement IDataRenderer interface and you need to define the setData and getData methods. As for the second one, your ItemRenderer  should extend the UIComponent class and override the UpdateDisplayList method.

To continue with our example, let’s say that your have the following arrayCollection as dataProvider:

 [Bindable]
    public var dataCollection:ArrayCollection = new ArrayCollection([
        {Month: "Jan", Income: 2000, Expenses: 1500 },
        {Month: "Feb", Income: 600, Expenses: 1200},
        {Month: "Mar", Income: 1500, Expenses: 1500},
       {Month: "Apr", Income: 2500, Expenses: 1500},
       {Month: "May", Income: 1500, Expenses: 500}]);

And  you want to set the color of the column on the left (income) based on these criteria:

If Income > Expenses then color = Green

If Income = Expenses then color = Yellow

If Income < Expenses then color = Red

Let’s take a look at the setData and getData methods in your ItemRenderer in this example ColorColumnChartRenderer.as:

public function set data(value:Object):void
     {
         if (_chartItem == value)
             return;
           // setData also is executed if there is a Legend Data
           //defined for the chart. We validate that only chartItems are
           //assigned to the chartItem class.
         if (value is LegendData)
          return;
         _chartItem = ChartItem(value);
        
     } 
     public function get data():Object
     {
         return _chartItem;
     }

 As you can see, we are saving the data in a chartItem class variable. The chartItem gives you access to the data  of a specific columnSeries using something like this:

                           myChartItem.item.fieldName

Let’s see how this is now used in the UpdateDisplayList method to set a specific color based on the criteria above:

   override protected function 
    updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
               
        var rc:Rectangle = new Rectangle(0, 0, width , height );
        var columnColor:uint;
        var g:Graphics = graphics;
         g.clear();       
         g.moveTo(rc.left,rc.top);
            // Only if the _chartItem has data
         if (_chartItem == null)
            return;
            // Only if the _chartItem has the attributes
         if( _chartItem.item.hasOwnProperty("Income")
             && _chartItem.item.hasOwnProperty("Expenses"))
         {
           // Choose a color based on your data
          if ( Number(_chartItem.item.Income) > 
              Number(_chartItem.item.Expenses) )
          {
            // Green
            g.beginFill(colors[1]);     
          }
          else   if ( Number(_chartItem.item.Income) == 
              Number(_chartItem.item.Expenses) )
          {
            // Yellow
            g.beginFill(colors[0]);     
          }
          else if ( Number(_chartItem.item.Income) < 
             Number(_chartItem.item.Expenses) )
          {
            // RED
            g.beginFill(colors[2]);     
          }
          else
             // WHITE
            g.beginFill(colors[3]); 
         }else
             // WHITE
            g.beginFill(colors[3]);  
          
   // Draw the column 
         g.lineTo(rc.right,rc.top);
         g.lineTo(rc.right,rc.bottom);
         g.lineTo(rc.left,rc.bottom);
         g.lineTo(rc.left,rc.top);
         g.endFill();   
  }

 

Finally, your can use your ItemRenderer in your columnSeries like this:

<mx:ColumnSeries  xField="Month" yField="Income"   displayName="Income"  itemRenderer="utils.ColorColumnChartRenderer"/>

 

Your chart should look something like this:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ColumnColorChart.zip
[Unzip ColoringChartColumns.zip and run ColorColumnChart.mxml.]
fig11.JPG
fig21.JPG
fig31.JPG
Report abuse

Related recipes