ILOG Elixir gauges with variable tick sizes or how IDataRender can help

Most of the time, gauges scales are displayed with two types of ticks, the major ticks, that are usually the bigger ones and the minor optional smaller ticks. So you finally get two sizes of ticks and that’s enough. However in some cases you might want to emphasize the fact that the scale is going from small to bigger values by rendering ticks with an increasing size along the scale as in the following example:

Fortunately ILOG Elixir is not just providing you with predefined gauges, but with a gauge framework that allows you to do that pretty easily.

What you need to do is to take an existing tick renderer and extend it to make sure it will draw with a variable size depending on the value it represents along the scale.

Let’s take the example of the CircleTickRenderer. You first need to create a VariableCircleTickRenderer subclass:

package
{
  import ilog.gauges.CircleTickRenderer;
  import ilog.gauges.TickItem;
  import ilog.gauges.gaugesClasses.NumericScale;

  public class VariableCircleTickRenderer extends CircleTickRenderer
  {
    protected override function updateDisplayList(unscaledWidth:Number,
                                    unscaledHeight:Number):void {
      super.updateDisplayList(unscaledWidth, unscaledHeight);
    }
  }
}

You can see that for now, we just redefined the updateDisplayList method and we call the base class method with the initial parameters.

What we will do now is to make sure we computed a width and height that are varying. For that we need to multiply the initial values by a ratio that is depending on the value the tick is rendering. The bigger the value will be the closer to 1 will be the ratio, and the smaller the value will be the closer to 0 will be the ratio.

We can get the information about the value we are rendering in the data property of the tick renderer as it is implementing the IDataRenderer interface from the Flex framework. The data property contains an instance of the TickItem class that contains a value property. So let’s modify the updateDisplayList method as this:

    protected override function updateDisplayList(unscaledWidth:Number,
                                    unscaledHeight:Number):void {
      var value:Number = TickItem(data).value as Number;
      super.updateDisplayList(unscaledWidth, unscaledHeight);
    }

Note that the value is cast as a Number as in this case as we intend to use a numeric scale.

So, we now have available the value and we need to get a ratio. For that we need to know the minimum and maximum values the scale is supposed to display. And divide the relative value by the scale extend. The scale can one more time be reached through the data property. Once we have the ratio we use it to adjust the width and height, but still preserving a minimum size (5px) so that all ticks are visible:

    protected override function updateDisplayList(unscaledWidth:Number,
                                    unscaledHeight:Number):void {
      var value:Number = TickItem(data).value as Number;
      var scale:NumericScale = TickItem(data).scale as NumericScale;
      var delta:Number = scale.maximum - scale.minimum;
      var ratio:Number = (value - scale.minimum) /delta;
      super.updateDisplayList(Math.max(5, unscaledWidth*ratio),
                              Math.max(5, unscaledHeight*ratio));
    }

You can now use that specific tick renderer in your ILOG Elixir application:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                xmlns:ilog="http://www.ilog.com/2007/ilog/flex"
                xmlns:local="*">
  <ilog:BlackHorizontalGauge showMinorTicks="false" value="50"
                             editable="true">
    <ilog:scaleRenderer>
      <ilog:RectangularScaleRenderer majorTickWidth="30"
                                     clipTicks="true">
        <ilog:majorTickRenderer>
          <mx:Component>
            <local:VariableCircleTickRenderer/>
          </mx:Component>
        </ilog:majorTickRenderer>
      </ilog:RectangularScaleRenderer>
    </ilog:scaleRenderer>
  </ilog:BlackHorizontalGauge>
</mx:Application>

A nice addition to the variable tick renderer is to replace the linear distribution of the size of ticks along the gauge by a logarithmic distribution. You can do by taking the existing ratio and applying a logarithm:

ratio = Math.log(ratio * 9 + 1)*Math.LOG10E;

If you want to look at the code you can download the Flex Builder project here. In addition if you want to run it you’ll need an ILOG Elixir installation.

Bookmark: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Furl
  • Slashdot
  • StumbleUpon
  • Technorati

Tags: , , ,

Leave a Reply