Developer's Guide for

Approximatrix Openchart2

Java Charting/Plotting Library

Prepared by Jeffrey Armstrong

December 26, 2006

Copyright © 2006 Approximatrix, LLC

Table of Contents

  1. Introduction
    1. Features
    2. History
    3. License
  2. Building and Incorporating Openchart2
    1. From source
    2. Using the JAR file
  3. Library Architecture
    1. Models
    2. Renderers
    3. Supporting Objects
  4. Creating Charts
    1. Creating the Data Model
    2. Creating the Chart Object
    3. Creating the Coordinate System Object
    4. Creating the Renderer
    5. Painting the Chart
    6. Common Additions
      1. Titles
      2. Legend
      3. Labels
      4. Colors
      5. Grids
  5. Swing Integration
  6. Support Information
  7. Copyright

Introduction

Openchart2 is a simple, open-source charting and plotting library designed for incorporation with a variety of Java applications.  The library can generate two dimensional bar, pie, radar, and scatter charts with customized titles, axis labels, legends and colors.  The simplicity of the library is its strongest feature, and developers will be met with a shallow learning curve.

Features

Openchart2 is a lightweight charting solution that can provide generation of several chart types.  This library provides a simple charting interface with the standard assortment of chart annotations.  Openchart2 can render the following chart types:
  1. Bar Charts (including Stacked Bar Charts)
  2. Pie Charts
  3. Radar Charts
  4. Scatter Plots (including Line Charts, Point Charts, or a combination)
The underlying engine for performing chart rendering has been designed for easy inclusion into a range of application types, including web applets and Swing desktop applications.  Openchart2 does trade some eye-candy operations for simplicity, allowing the developer to quickly and seamlessly generate and integrate dynamic charts and plots into his or her software.  Openchart2's liberal licensing and free documentation make development worry-free.

History

Openchart2 is a fork of the JOpenChart toolkit and library, based on version 0.94.  Openchart2 was forked by Approximatrix to update the following features:
The JOpenChart projects appears to have stalled in late 2002 despite a promising architecture.  Approximatrix provides full support of the Openchart2 fork, including the original JOpenChart features.

The Approximatrix Team thanks Sebastian Müller and the other JOpenChart contributors for their great work designing and building the original JOpenChart library.

License

Openchart2 is licensed under the GNU Lesser General Public License version 2.1 or greater.  The LGPL allows for linking of any program against the Openchart2 library without transmission of the LGPL terms to the calling program.  This licensing allows proprietary, closed-source software to use unmodified versions Openchart2 without requiring the distribution of source code.  If the Openchart2 library is modified in any way, all modifications must be released under the terms of the LGPL.  For more details concerning this license, please consult the Free Software Foundation's LGPL pages.

Openchart2 is copyrighted by Approximatrix, LLC, and Sebastian Müller.  Usage of the Openchart2 library does not require any explicit license from Approximatrix, but the terms of the LGPL must be respected.  Sebastian Müller has no affiliation with Approximatrix and should not be contacted for support for the Openchart2 library.

Back to Top

Building and Incorporating Openchart2

Openchart2 is available in both source and pre-compiled JAR form.  Openchart2 has no dependencies on outside libraries other than the standard Java runtime engine (version 1.4 or higher is recommended due to Swing dependencies).  Therefore, the source code can be easily compiled on a number of platforms, from the official Sun JDK to free software equivalents.

From source

A simple build.xml Ant script has been included with the source distribution.  Specifying a "jar" target will construct the necessary JAR file for inclusion with applications.  Automated building in Eclipse or Netbeans should also be straightforward as well.  

Using the JAR file

The JAR file must simply be in an application's classpath for another application/applet to call Openchart2.  The JAR file supplied by Approximatrix does not have any external dependencies other than the standard Java runtime.  An overview of the library and the steps to creating a chart appear below.  Tutorials and further documentation is available on the Openchart2 docmenation page.  
Back to Top

Library Architecture

The basis of a chart in Openchart2 is the AbstractChart object.  This object provides encapsulation and control of all the charting components, from the actual plot renderers to the coordinate systems.  A diagram of this architecture appears below:




The base distribution implements two versions of this abstract class: DefaultChart and ExtendedChart.  These two classes are identical except that the ExtendedChart class implements methods for quick access to zooming.  

Any chart allows multiple renderers to be implemented on a single chart drawing in a specified z-order (the order in which each render is drawn on top of the previous).  The result of this design is that multiple renderers of unlike type may be plotted in the same chart (i.e. a scatter chart and a bar chart).  Each renderer is linked to its own data model, so the data for any given renderer can be different from another renderer.  The chart data model is based on the AbstractChartDataModel class, and the extending classes implement the necessary data storage for any given chart type.  The AbstractChart class, however, relies on a single data model for passing to the CoordSystem constructors, which handles the transform from the data coordinate systems to the graphics coordinate systems.

Each of the components' functionalities are described below in general terms.  The specifics of the renderers and data models are covered in the Creating Charts section.

Models

Each chart type generally has its own data model tailored specifically to the needs of the chart type.  These objects are stored in the com.approximatrix.charting.model package.  Openchart2 implements the following basic data models:
The models with numeric X-axis data also rely on constraint objects to simplify the complicated determination of max/min values in the models' data sets.  These constraint objects are only called by the related models themselves.

Renderers

Openchart2 implements several renderers, which can loosely be equated with the desired chart type.  The renderers rely on coordinate system transformations, provided by CoordSystem objects, to properly render the data stored in their individual data models.  The renderers only draw the data stored in the data models, while other supporting objects handle the axes, tic marks, legends, etc.  Openchart2 provides the following renderers for plotting:
All renderers rely on CoordSystem objects for drawing and scaling and RowColorModel objects from the parent AbstractChart class for determining series colors when drawing.

Supporting objects

Title
The Title object stores and handles drawing of the title of a given chart.  The text in the title is easily changed using setText() and getText() routines.  The title is always centered on the chart, and the font used to draw the title is controlled via the setFont() and getFont() routines

Legend
The Legend object is optional, and is sued to render a legend to the right of the rendered chart.  The legend relies solely on the data model stored in the top level AbstractChart class (similar to the CoordSystem and RowColorModel objects).  The legend draws a simple block based on the chart's RowColorModel object next to the name of each series.  Theoretically, these colors should be consistent with the Renderer's colors since both normally share the same RowColorModel, as the earlier diagram shows.

RowColorModel
The RowColorModel object controls the colors and symbols (if applicable) with which each series is drawn.  This object is external to the Renderer so that it may be shared by Legend objects.  The default array of colors and symbols to use in drawing each series is stored in a HashMap inside the object.  Calling code may change the color of any given series using the setColor() routine, which will be reflected in the Renderer object as well as the Legend if present.

CoordSystem
The CoordSystem object serves the important function of providing the data-to-graphics transformation as well as encapsulating all Axis and Label drawing methods.  The CoordSystem object relies on a single data model for all calculations.  The CoordSystem object retains the capability to display two Y-axes, but this functionality is not yet implemented fully.  The CoordSystem object relies on the CoordSystemUtilities object for all transformation calculations, tic placements, chart margin calculations, label drawing,etc.  The CoordSystem object is necessary for all charts even if the axes are not drawn.

Back to Top

Creating Charts

The steps to creating a chart are straightforward and shared between all charts regardless of type.  The general steps are as follows:
  1. Create appropriate data model
  2. Create the chart (either DefaultChart or ExtendedChart) using this model
  3. Create the required Renderer(s) based on the data model and chart's CoordSystem
  4. Add the Renderer to the chart
  5. Annotate as necessary (legend, title, etc.)
The steps change based on the chart type, but can be generalized across all types.  These steps will create a chart, but will not display anything; an appropriate Graphics object must be provided to draw onto.  See the Swing Integration section for basic display of the chart.

Creating the Data Model

The type of data model created depends on the nature of the data to be plotted.  For example, if the X-axis is non-numeric, an ObjectChartDataModel may be appropriate.  The ObjectChartDataModel provides a number of constructors depending on the data structure.  The general outline for the constructor is:

model = new ObjectChartDataModel(data[][], column_ids[], series_ids[]);

The data can be passed in with the values for each data series in each row.  ObjectChartDataModel supports the data array as Number, int, or double types.  The column_ids array contains the text for each X-axis point (corresponding to each column in the data array).  The series_ids array contains the text for each series.  If only one series was included, data would be a 1 by x array, column_ids would have x elements, and series_ids would have only a single element.

Scatter charts (such as line plots, point plots, or combinations of the two) with shared X-axis data can use three types of data models, depending on the nature of the application.  The most general model is ScatterDataModel, which provides storage of series properties along with series data.  The general outline of the constructor is:

model = new ScatterDataModel(data[][], columns[], series_ids[]);

This constructor works similar to the ObjectChartDataModel as described above, but the columns array is now numeric double values instead of Strings.  The data structure and the series_ids remain the same.  

The most complex type of data model is the MultiScatterDataModel, which allows differing X-axis values between series.  These models are used for true scatter plots where the structures of the  individual data series are inconsistent.  An outline of the constructor method follows:

model = new MultiScatterDataModel();
model.addData(x[], y[], name);
...


The MultiScatterDataModel is initialized in the constructor.  Data sets are then added individually via x and y double arrays.  The MultiScatterDataModel is only to be used with MultiScatterChartRenderer renderer objects.

Creating the Chart Object

Openchart2 provides two basic chart objects, DefaultChart and ExtendedChart.  Either is appropriate for all chart types.  For now assume the non-zoomable DefaultChart is sufficient.  The constructor would be used as follows:

chart = new DefaultChart(model, title, DefaultChart.LINEAR_X_LINEAR_Y);

The chart object has now been created along with its required CoordSystem object with linear axes.  Currently only linear axes are supported via this constructor.  A custom CoordSystem object can be used by passing a created CoordSystem object through the setCoordSystem() method.

Creating the Coordinate System Object

The coordinate system object, CoordSystem, defines the entire drawing surface for the chart.  This object also performs the drawing of the axes with their requisite labels, ticks, and grid lines.  Most Renderer objects require a coordinate system object to be defined first, as the CoordSystem objects provide the data-to-graphics transforms needed for painting the chart contents.

The CoordSystem object is constructed by passing the defining model into the constructor, as shown below:

coords = new CoordSystem(model);

This coordinate system must now be added to the chart object, which does not have a default coordinate system.  The following code adds the coordinate system to the chart:

chart.setCoordSystem(coords);

Although a chart can contain multiple renderings, a single CoordSystem object is used for drawing.  Therefore, initially the chart scaling will be defined by the single model passed in through the constructor.  The scaling can later be manually adjusted through appropriate calls to the CoordSystem object.  

Creating the Renderer

The renderer performs all drawing of the actual data on the chart.  Openchart2 provides a number of renderers based on the type of chart.  Most renderers will also require a CoordSystem object when constructed because the CoordSystem object contains the data-to-graphics transform necessary for drawing.  For example, to create a bar chart, one would use the following:

renderer = BarChartRenderer(
coords, model);

The renderer must then be added to the chart.  To add this bar chart, use the following:

chart.addChartRenderer(renderer, 0);

The statement above adds the BarChartRenderer object to the chart at z-position 0.  Because charts can contain multiple renderers, the z-position of each must be specified when the renderer is added.  The largest z-value will be drawn topmost, with each descending z-value falling under the highest.  If only a single renderer is used, the z-value is inconsequential.

Painting the Chart

Chart drawing is handled using a Java Graphics2D object.  Before any drawing is performed, bounds for the chart must be defined using standard setBounds() syntax:

chart.setBounds((Rectangle)bounds);

The rectangle defines the area on the Graphics2D object where the chart is to be drawn.  To perform the painting, the call is simply:

chart.render((Graphics2D)g);

The combination above allows easy integration of Openchart2 charts into Swing applications/applets or quick generation of images.

Common Additions

Openchart2 allows for the quick addition and modification of many common chart annotations.  The chart object contains all references to the title and legend, while the CoordSystem object contains all labels, grid, and scaling controls.

Titles
The title object is accessed through the main chart object.  An example is:

Title title = chart.getTitle();

The title can be changed modified using its set*() and get*() commands.  Specifically, to change the text, the command would be:

title.setText("New Title String");

Setting the chart's title object to null will cause the title to be omitted from drawing.

Legend
The legend text is controlled by the associated data model.  Each legend entry is associated with the related series entry in the chart's central data model.  In order to change text in the legend, the actual series name must be changed.  The method/ability to do so depends heavily on the type of data model being utilized; see the appropriate model's Javadocs for more details (available online here).

Labels
The axis labels are stored in and handled by the CoordSystem object of the chart.  The axes labels, or units, can be changed using the setXAxisUnit() and setYAxisUnit() methods.  For example, to change the X axis lable, use the following code:

coords.setXAxisUnit("Month");

The update should be reflected on the next repaint of the chart.

Colors
Series colors are handled by the RowColorModel object of the chart.  Although each renderer can use a different RowColorModel, the chart object's base model is used by default.  The RowColorModel can be accessed from a variety of sources:

rcm = chart.getRowColorModel();


or

rcm = chart.getLegend().getRowColorModel();


or

rcm = renderer.getRowColorModel();

All three will return a RowColorModel object.  By default, all three techniques will return the same object.  The RowColorModel object can be used to change the color fo series in the chart.  For example, to change the color of the first series in any type of chart, use the following:

rcm.setColor(0, Color.RED);

The above code changes the first series to red.  Any valid java.awt.Color object can be used.  

The RowColorModel also handles marker drawing for scatter plots.  Equivalent commands allow the setting of the marker shape to use in drawing the individual data points based on a valid java.awt.RectangularShape object.  

Grids
The CoordSystem object also controls the drawing of a grid in the body of the chart.  The grid can be enabled simply by using the following command:

coords.setPaintGrid(true);


The above statement causes the CoordSystem object to draw a light grey grid in the chart body consistent with the major tick marks on the axes.  Currently Openchart2 does not support per-axis grid drawing, but this feature is planned for future release.

Back to Top

Swing Integration

Openchart2 provides Swing-compatible components for simple inclusion of Openchart2 charts into Swing-based applications.  The package com.approximatrix.charting.swing contains two classes, ChartPanel and ExtendedChartPanel, which extend javax.swing.JPanel.  The ChartPanel object implements a DefaultChart in a JPanel, while the ExtendedChartPanel implements an ExtendedChart (allowing zoom).

The standard method for creating a ChartPanel is to pass the appropriate data model into the constructor.  Other constructor options providing further customizations also exist.  Once constructed, the desired Renderer(s) is(are) then added to the panel.  The panel will also generate default titles and legends based on the data model passed in.  

The ExtendedChartPanel behaves similarly, but also allows dynamic zooming with the appropriate flags set.  Dynamic zooming enables the user to drag the mouse over a selected region of the chart to define new axes limits.  The functionality is best suited for scatter plot renderers, but can be used in conjunction with non-numeric X-axis plots as well if desired.

Both panel types will expand and fill the entire space allotted to them by their parent container, just as a normal JPanel would.  All controls, with the exception of painting, behave exactly as a JPanel would.  Both panels implement MouseMotionListener, MouseListener and Printable.  The mouse listeners are used for zooming (or simply drawing selection boxes in ChartPanel's case), and extending these panels to override the default listener methods is encouraged to customize JPanel behavior.  The Printable interface provides simple chart printing, if desired, based on the current panel's size; this interface can also be extended to provide more advanced printing of charts.

Back to Top

Support Information

Approximatrix, LLC provides full support for the Openchart2 library.  Please consult the Openchart2 home page for information concerning bug reporting, feature addition, and code submissions.  All bug fixes and feature requests will be addressed in due course if submitted.  Code submissions for inclusion in the main Openchart2 distribution are encouraged; requirements are outlined on the Openchart2 support page.

Commercial support of the Openchart2 library is also available from Approximatrix.  A commercial support contract entitles the user to higher priority addressing of bugs and feature additions.  If Openchart2 needs further improvement for your product, Approximatrix can provide development capabilities under support contracts.  For more information, visit the Openchart2 support page.  Because this product is licensed under the GNU Lesser General Public Licsense, it is provided without any warranty.

Back to Top

Copyright

This document is Copyright © 2006 Approximatrix, LLC.

The Openchart2 library is copyrighted by the following:
Copyright © 2006 Approximatrix, LLC
Copyright © 2001 Sebastian Müller

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Back to Top