Programming dojox.chart (2) - Divide and Conquer

Divide and Conquer is our best friend, we would decompose a chart into different pieces and evaluate the possibilities to reuse components.

A chart can be described as:

and it can be decomposed as the following components:

Here is a typical chart example:

Generally, we can categorize charts into different types : Lines, Area, Column, Bar, Pie, XY-Chart, Stack; and 3D variants if applicable. Type determines how the data is visuallized.

Axis

Axis is another essential factor, which determines the resolution of the data. A “smart” axis needs to calibrate the length of unit and upper-bound, low-bound to maximize the resolution. On the other hand, users may override the default range. The attributes for Axis objects include: range: {floor, ceil}, lineStyle(color, dotted, slash …), labelStyle(font, position, …), arrowStyle.

Linear axis is commonly used in business world, while some scientists prefer logarithmic axis. A derived class LogarithmicAxis aims to support this feature.

Series

Series holds the raw data, which could be an array(in Column and Bar), single value(used in Pie), or array of (x, y) tuples(in XY-Chart). Series also needs a Label to identify itself and Style to differentiate itself with others.

Most user may not care about the Style, or even the Label, the chart would attach a default Style and Label if they are missing.

Grid

Grid is seldom used in most cases, but if the axis is logarithmic, the grid would improve readability dramatically.

Label

Label is the characterized by the font style and position.

Expected pseudo-code

Here is the code snippet of dojox.chart in action:

var chart = new dojox.chart.bar3d("test", 500, 500, "Chart Test")
.addSeries( new dojox.chart.Series(
   [10, 20, 15, 15, 22, 7]))
.addSeries( new dojox.chart.Series(
   [5, 42, 35, 12, 18, 21], "T1"))
.addSeries( new dojox.chart.Series(
   [50, 32, 25, 7, 15, 12], "S2",
   {type: "plastic", finish: dojox.gfx3d.lighting.finish.dull, color: "blue"}))
.calibrate()
.render();

The above code snippet demonstrates a typical chart operation. Once the series are added, calibrate would calculate the dimension of plotting area, resolution, floor and ceiling of values, add missing label and styles of series if necessary; then render the chart. These operations are supposed to be portable, aka the type of chart is interchangeable.