Blogs

About this blog

This community site is for software developers interested in topics related to Web 2.0 and mobile device user interface development. This includes both general trends and technology discussions, as well as specific discussions and other resources involv

Tags

Recent tweets

Creating Bullet Graphs in Dojo with the gauges package

A while ago I wrote a series of blog posts about a data visualization component called the Bullet Graph that I had developed on top of IBM ILOG Elixir gauges framework. This component is basically trying to mix
some of the bar graph and horizontal gauge concepts to take the best of
both worlds and convey data information in a more efficient way. The
component was first described by Stephen Few in its Information Dashboard Design book. You will find more information on the bullet graph on its Wikipedia page or in its specification. In this new blog post I will show how you can easily create the same bullet graph component using an open web technologies stack and in particular the new gauges framework from Dojo 1.8 release which are also provided as part of WebSphere Application Server 8 and Web 2.0 and Mobile Feature Pack 1.1.0.2. This will allow you to easily deploy this component either on regular Web application or in mobile applications base on Dojo Mobile.

In the end, what we want to achieve is something that looks like this
example of bullet graph available on Wikipedia (with explanations in
red):

The first step in order to achieve this is to create a Dojo module & the corresponding class that will represent our bullet graph. As we already described a bullet graph is a particular kind of horizontal gauge that's why the BulletGraph class inherits from the dojox/dgauges/RectangularGauge class that represents horizontal & vertical gauges in Dojo. In order to extend it you need to create a BulletGraph.js file with the following content:

We then need to define the core properties that defines the model of a bullet graph:

the performance measure which is represented by the gauge value property

the comparative measure which is represented by the gauge target property

the qualitative ranges bad, satisfactory and good which are bound by the gauge minimum value (hardcoded to 0 for the bullet graph) as well as the low, medium and high threshold properties.

We also need to define a logical scaler that represents the limits of the bullet graph and extents from the minimum value (0) to the maximum one (high threshold property). There are several kind of scalers like logarithmic or linear ones and you can define your own scalers. For the bullet graph a simple linear scaler is used.

The core properties are usually defined and assigned as fields of the class while the scaler is instantiate in the constructor as follows:

constructor: function(){ var scaler = new LinearScaler({ // minimum is set to 0 which is the default // maximum is set to the high threshold maximum: this.high }); } });});

Now that the core logical values of the bullet graph are defined we need to create the graphical objects of the gauge that will be in charge of rendering each of these values. There are several kind of graphical elements and indicators that can be put in a gauge. For the bullet graph we will use:

dojox/dgauges/RectangularScale: a graphical element in charge of rendering the scaler of a gauge

dojox/dgauges/RectangularRangeIndicator: a graphical indicator in charge of rendering a range of values from a minimum to a maximum value on a scale. This is typically represented by a rectangle or a triangular ramp.

dojox/dgauges/RectangularValueIndicator: a graphical indicator in charge of rendering a single value on the gauge. This is typically represented by a thumb or a marker.

Once a graphical element has been instantiated it can be added to the gauge using the GaugeBase (from which RectangularGauge inherits) addElement method. In the following code extracted from the gauge constructor we are creating the RectangularScale connected to the previously created scaler and adding it to the gauge giving it the "scale" name:

The paddingTop and Bottom properties allows to specify how far from the top and bottom of the gauge content box the scale will be positioned. The labelPosition property allows to specify where the labels of the scale will be rendered. For an horizontal scale the "trailing" position means that the label will be rendered below the scale. The default would have lead to render them above the scale which is not corresponding to what a bullet graph should look like.

Similarly once a graphical indicator has been created it can be added to a scale use the ScaleBase addIndicator method. The following code is creating and adding to the scale the five indicators. They correspond to the five core properties of a bullet graph: the high, medium and low thresholds for performance measurement, the
measure itself which represents the value of the bullet graph and the
target or comparative measure.

As for the scale the padding properties allow to specify where the various indicators must be laid out. Each indicator value is initialized with the initial value of the corresponding core property of the bullet graph.

A shown in the following example, you can now use the bullet graph in a Dojo application by creating a sample HTML page that imports Dojo and instantiate the bullet graph with custom values for the various core properties using the Dojo parser:

As you can see even if all the core properties we are interested in
are present and rendered a the correct position on the scale, this is still not really looking like a bullet graph as we have not worked on the customization of the various indicators including their colors, thickness and other rendering properties.

In the following code several types of properties are added to the indicators to match the exact bullet graph expected rendering:

interactionMode: by default an indicator can be edited using mouse gestures or touch gestures. To prevent this behavior you should put interactionMode to "none". This is what we are doing for the bullet graph as it is not supposed to be editable as used just to monitor existing values.

fill: the fill object (color, gradient...) used to draw the indicator in dojox/gfx. Here we are levarage dojox/color to compute different intensities of a single hue (black here) to comply with bullet graph specification.

stroke: this defines the outline of the indicator, if no outline needs to be drawn like in the bullet graph you should put it to null

startThickness & endThickness: the tickness of the indicator at its initial and last position. To get a rectangular indicator they must be set to a single value, to get a ramp indicator you can use different values.

indicatorShapeFunc: this allows to override the way an indicator is drawn by providing a function that returns a dojox/gfx shape for the indicator. We need that for the target indicator in our case. By default an arrow is drawn where we want a vertical bar.

With these modifications we get the expected rendering behavior of a bullet graph:

We could stop here and have a working bullet graph. That said if at runtime you modify one of the gauge properties dynamically after its creation this would not be reflected in drawing. Indeed all the gauge elements and indicators were created and set in the gauge constructor and not updating later.

Fortunately this is relatively easy to enable this. You first have to enable the gauge refresh mechanism for the core properties you want to be dynamically set at runtime, for that you add the following code in the constructor:

This will make sure a refreshRendering method is called when one of these core properties value is changed. You can then define the refreshRendering method to re-bind the new values to the gauge elements and indicators as follows:

With this blog post we have seen how easy it is to create your own custom gauge using the dojox/dgauges package from Dojo. In a future blog post we will see how to use several instances of this gauge and automatically bind them to your data using the dojox/mvc package.