Charting API Prototype - JavaBeans

There are 4 main areas of the architecture for the chart engine: the data, the metadata, the styling and the chart structure itself.

The Data

We have had a few very short discussions on the data implementation for charts. Gretchen will be working thorugh some scenarios shortly and will put out some initial ideas for discussion.

The Metadata

Same as the data. See above.

The Styling

We are postponing further discussions about the persisted style format of the chart definition and CSS until Thomas is in town at the end of this month. I have looked briefly into LibLayout, and need a sit down with Thomas to clarify the layouter does what I think it will. I am assuming (mostly from Thomas comments) that the CSS is completely hidden from the engine implementation, and we really only need to worry about name/value pairs as attributes when styling the chart at the API level. So we are not concerned about putting this on hold, when Thomas can be here and bring us up to speed more quickly.

The Chart Structure

I believe that JavaBeans will give us a nice model to work with when applying styles and data to the chart objects. This does not take rendering, output formats, additional outputs such as drill through URLS or tooltips into account. It does include the ability to apply the name\value pair attributes to all aspects of the chart for customization, and provide the property change event handling needed to notify observers of changes to the chart.

We propose two layers of beans - one at the chart component level and one at the chart type level. So the lower level beans would represent parts of the chart, such as the plot, axes, series, titles and such. The higher level beans would put the pieces together to form chart types of interest to users, such as a BarChartBean, LineChartBean, PieChartBean, etc.

The validation of this structure against the data would be the job of the data object. The data object will register as an observer to the chartbean, and as properties are set, the data can decide whether they are useful or not. Haven't thought in depth about metadata or data related styles. Thats a TBD. Also, the problem of an incomplete DOM still lingers, as well as how much we are going to infer about the chart objects. The CSS normalizer may eliminate some of these worries for us.

So, below is an image that highlights the portion that we are going to start coding on, JavaBeans style. Speak now or interject at the last minute when it can't possibly help.

Alternate View

Data

The charting process starts with a user-provided data-set. How this data looks like does not matter for now, nor does it matter how it is actually organized.

Meta-Data

Either derived from the data or provided by the user, the system contains a set of meta-data properties which describe the data, provide data-type information, min-max values or what ever might be needed.

If the user does not provide meta-data, the meta-data will be derived from the given data. If the user provides meta-data, the existing data must be validated against the meta-data (as I dont believe that users are able to provide error-free datasets).

Data and Meta-data are chart-type agnostic, they do not know or care about the chart that renders them.

Chart-DOM + Style-Information

The chart-DOM is a object model that consists of elements which can have attributes and child-elements. The DOM follows the ideas (but not necessarily the complexity and painful usage patterns) of the W3C-DOM model. Elements have a namespace and tag/type-name, and carry a set of attributes which are specified as "namespace+name -> value" tuples.

The DOM model should follow the principle of being as generic and extensible as possible.

We cannot know the properties needed for all chart-types that our system will support in the next couple of years. We also cannot know the extra properties that might be supported by or eligible for specific renderer implementations.

By defining a core-DOM-model (or more correct: A core DOM-configuration) for each known chart-type, we create a common set of nodes and properties that are understood by all chart-renderers without limiting our ability to add nodes and properties which are only understood by a subset of the renderers.

The use of Java-Beans enforces a non-namespaced attribute-value and strictly typed property-system on the Chart-DOM while at the same time preventing (or at least complicating) the addition of new properties or nodes to the model. Java's Single-Inheritance model for classes does make things easier either.

Java-Beans make it easier for programmers to work with the Chart-DOM, as beans provide
slots for all known properties and sub-elements. But I do not see our chart-DOM as a component, I consider the DOM a document that is processed by the system to produce an output which is independent of the document that created it.

A generic DOM implementation does not prevent the implementation of "property-change" events, as fireing events is not restricted to Beans at all. At the same time, beans do not automatically allow us to auto-generate a Editor-UI. The effort to write an editor for a complex bean-framework is still rather large, and if we want a user-friendly user-interface, we have to start to write a customized UI anyway with little to no help from code-generators.

Chart-Processor/Chart-Renderer

The chart-Processor is responsible for validating the Chart-DOM against the given Meta-Data and to complete the chart-DOM's missing pieces if the DOM is incomplete or invalid.

We should provide a generic set of chart-processors for all supported chart-types so that all renderer-implementations can work on a common core-set of properties and a common DOM structure.

Processing charts in 5 simple steps

# Obtain the data
DataSet ds = createDataSet();

# Obtain the meta-data (alternative: generate it from the data)
MetaData mds = generateMetaData(ds);

# Obtain the chart-DOM
# Alternative 1: by parsing an XML file
ChartDom dom = parseDom();

# Alternative 2: by aut-generating one)
# Select a suitable chart-renderer by querying all known chart-processors
ChartDom dom = ChartProcessorRegistry.createDefaultChart (mds, ds);

# Validate the Chart-DOM, autocompletes missing elements
String outputType = "image/png";
ChartProcessor proc = ChartProcessorRegistry.getChartProcessorForDom (dom, outputType);
proc.validate(dom);

# Render the chart (for example, write to a stream)
proc.render(dom, outputStream);