Table of
Contents
- Introduction
- Features
- History
- License
- Building
and Incorporating Openchart2
- From source
- Using
the JAR file
- Library
Architecture
- Models
- Renderers
- Supporting
Objects
- Creating Charts
- Creating the Data Model
- Creating the Chart Object
- Creating the Coordinate System Object
- Creating the Renderer
- Painting the Chart
- Common Additions
- Titles
- Legend
- Labels
- Colors
- Grids
- Swing Integration
- Support
Information
- 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:
- Bar Charts (including Stacked Bar Charts)
- Pie Charts
- Radar Charts
- 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:
- Enhanced scatter plot support (for scientific/mathematic
uses)
- Elimination of unnecessary dependencies
- Improved axis scaling calculations
- Grid drawing
- Dynamic zooming in Swing applications
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:
- DefaultChartDataModel - For basic scatter/line plots with
numeric X-Axis data shared across series
- EditableChartDataModel - Extends DefaultChartDataModel to
allow for inserting and changing data values
- ScatterDataModel - Extends EditableChartDataModel to allow
storage of series properties, such as colors and marker/line options
- MultiScatterDataModel - Model providing data for
scatter/line plots for multiple series, each with its own XY pairs
(X-Axis points vary between series)
- ObjectChartDataModel - For plots where the X-axis is
non-numeric (i.e. pie charts and bar charts)
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:
- BarChartRenderer - Draws vertical bars based on the
provided data model, and displays non-numeric X-axis values to
categorize each bar
- LineChartRenderer - Draws a simple line chart with multiple
series
- InterpolationChartRenderer - Similar to a line chart, but
creates interpolated lines if values fall outside the plotted range
- PlotChartRenderer - Draw a simple scatter chart using
symbols only with shared X-axis values for all series, automatically
choosing marker styles for each series
- ScatterChartRender - Provides a combination of
the LineChartRenderer
and PlotChartRenderer using a ScatterDataModel to determine if
markers and/or lines should be drawn for each data set
- MultiScatterChartRenderer - Uses a MultiScatterDataModel,
where X-axis points are not shared between series, to generate a chart
similar to the ScatterChartRenderer
- PieChartRenderer - Draws a simple pie chart
- RadarChartRenderer - Generates a radar chart based on a
numeric data model
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:
- Create appropriate data model
- Create the chart (either DefaultChart or ExtendedChart) using this model
- Create the required Renderer(s) based on the data model and chart's CoordSystem
- Add the Renderer to the chart
- 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
String
s. 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