An Oracle blog about BI Publisher

  • Flex
    April 28, 2008

Back and Flexing

Apologies to regular readers may be wondering where I have been. I took a week off after OAUG to sit on a San Diego beach to get toasted to a crisp and to avoid any sharks. We were on that same beach the day before it happened! Needless to say my wife was constantly telling me to watch the kids in the surf, checking for any big gray fins in the water and if seen to run or swim like hell!

While I was away, Noelle has been working on some Flex template goodies. We got a requirement a while back to produce a report similar to this:


Its nothing to 'write home about' standard table stuff but the interesting feature is the 'percentage bar' embedded in the table. Two issues to solve here:

1. Building the 'bar' component - its not an out of the box feature.
2. Getting the bar to render inside the table

Noelle, being very cunning, solved both!


Its not exactly the same look and feel but we were after the functionality - the look can be tweaked quite easily.

Tackling the 'bar' component first, Noelle first needed to build the 'percentage bar'. To do this, Noelle used an ActionScript class to create and render the bar. It basically takes a label object and extends it to render the text value and a rectangle shape, calculates the percentage fill to be used based on the data.

Here's the script

// ActionScript file

package {

// Need these packages for rendering and drawing

import flash.display.*;
import flash.geom.*;
import flash.text.TextField;
import mx.controls.Label;

// We are going to extend the label object

public class PercentageBar extends Label {
 override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

super.updateDisplayList(unscaledWidth, unscaledHeight);

  // Create rectangle shape and width

  var rndedRect:Shape = new Shape();
var rectWidth:Number=100;
var rectHeight:Number=15;
// Fill for the rectangle is derived from value in the main.mxml ie the parent application

  var rectFill:Number=this.parentApplication.percentCalculated;

  //Set the fill type, colors, alphas and ratios

  var fillType:String = GradientType.LINEAR;
var colors:Array = [0xFF0000,0xFFFFFF];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];

// matrix - not required but allows you to specify the fill
var matr:Matrix = new Matrix();
  matr.createGradientBox(rectFill, rectHeight, 0, 0, 0);
var spreadMethod:String = SpreadMethod.PAD;
  //Start rendering the rectangle
  rndedRect.graphics.drawRoundRect(2, 0, rectWidth, rectHeight, 10, 20);
  // Add the rectangle to the label object

  //Create the label for the rectangle
  // Value drawn from the percentCalculated value in the main.mxml

  var label:TextField = new TextField;
  label.width = 26;
  label.text = (
this.parentApplication.percentCalculated+ "%");
  label.x = 105;
  label.y = 0;
  //Add the text field to the label

Those familiar with java should not be too scared of the code - if you spend some time with it its not that tough to understand. Its code yes! but it adds a huge layer of flexibility to the flex reports.

Thats the 'bar' component, so how to bring it into the main table layout. Thats pretty easy too ...

Remember that the bar component needed the 'percentCalculated' value from the parent application ie the main flex template? Well, we need a function to calculate that:

[Bindable] public var percentCalculated:Number;

// determine the percent of the target number - round before passing back
private function calcPercent(row:Object, column:DataGridColumn ):void
 var a:Number;
  var t:Number;
  a = row.actual;
  t = row.target;
  percentCalculated = Math.round((a/t) * 100);

Notice we need to declare the 'percentCalculated' variable as public and bindable so the action script class can access it. Its a simple calculation to get the percentage based on the rendered table data.

To get the 'bar' to render we just need to set the last column to use its own renderer ie the PercentageBar AS class that was created.

<mx:DataGrid id="myDatagrid" width="500" height="300" dataProvider="{dataXML.product}" editable="false" enabled="false">
   <mx:DataGridColumn dataField="name" headerText="Product Category"/>
   <mx:DataGridColumn dataField="actual" headerText="Units Sold Actual" id="actual"/>
   <mx:DataGridColumn dataField="target" headerText="Units Sold Planned" id="target"/>
   <mx:DataGridColumn itemRenderer="PercentageBar" width="135" headerText="% of Target" labelFunction="calcPercent"/>

You can get the complete source to the flex project here. Thanks again to Noelle for the research and code.

So, a little effort but hopefully you get an idea of how you can take existing Flex objects and extend them to create your own visualizations of the data. You can now tell your users that the 'world is their oyster' when it comes to reporting ... or may be not!   

Join the discussion

Comments ( 3 )
  • bernadette Friday, December 11, 2009
    Nice one, there are actually some good points on this blog some of my subscribers will find this relevant, I must send them a link, many thanks.
  • Shana Bartram Sunday, September 26, 2010
  • Enrique Kry Monday, October 11, 2010
    Atkins' New Diet Revolution by Dr. Atkins. This weight loss program encourages high protein diet and a trim down on the carbs. One can feast on vegetables and meat but should fast on bread and pasta. One is also not restricted against fat intake so it is okay to pour in the salad dressing and freely spread on the butter. However, after the diet, one may find himself lacking on fiber and calcium yet high in fat. Intake of grains and fruits are also limited.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.