339
CHAPTER 14
Charting with
JFreeChart
M
ANY PORTAL APPLICATIONS
will have a business requirement to provide charting,
reporting, or other analysis tools. These could be part of a sales forecasting sys-
tem, a financial reporting tool, or a customer service application. In one possible
architecture, basic functionality for accessing and modifying charts or reports
could belong to a front-end portlet application, with an enterprise information
system (EIS) on the back-end.
In many cases, the EIS already exists, either as a custom-built application or as
a packaged product. Packaged products may have charting, reporting, or analysis
tools, although these may not be completely customizable or deployable in a port-
let environment.
If you are developing the EIS at the same time as the portlet application, you
can design an API to enable data extraction for charting or reporting. Patching in
a data access layer after the EIS is completed will probably be more complicated.
In either case, creating a specification that defines the needed data and goals
of the application will help create usable portlets. Sample charts are an easy way
to define requirements for the application. By creating examples early in the
process, developers and customers can set expectations for the project. Sometimes
the charting tools will not be at the level needed for the sample charts. Knowing
this ahead of time, developers can factor in additional development time for the
project. Choosing a charting component that comes with source code is an effi-
cient way to provide more business value for your customers and speed up your
development.
In this chapter, we use an open source product for charting named JFreeChart.
Although many other commercial and open source charting products and tools
are available, JFreeChart is widely used, has a large selection of charts, and is
integrated into several reporting tools, such as Jasper Reports and JFreeReport.
Building Charts and Graphs with JFreeChart
JFreeChart is an open source Java library that you can use to create charts and
graphs. The software package can be found at
www.jfree.org/jfreechart/index.html
.
The library is licensed under the GNU Lesser Public License. We are using
version 0.9.17 for the examples in this chapter. You will need the JFreeChart JAR
2840ch14.qxd 7/13/04 12:44 PM Page 339
Download at Boykma.Com
Chapter 14
340
file (jfreechart-0.9.17.jar). From the JFreeChart distribution’s lib directory, we
also use the gnujaxp.jar, log4j-1.2.8.jar, and jcommon-0.9.2.jar files.
JFreeChart provides charts for Swing applications, applets, servlets, portlets,
or other types of Java applications. The JFreeChart software does not offer any
direct support for the portlet API or portal behavior. In this chapter, we focus on
understanding how to use the JFreeChart API; then we create a portlet application
that displays charts generated with JFreeChart. Our charting portlet creates tem-
porary files for our charts, and a servlet serves the image files to the user.
Chart Types
The common chart types are included with JFreeChart, including bar, pie, area,
scatter plots, time series, and area charts. Variations are possible with each chart
type, and it is also possible to create 3D pie charts and bar charts. JFreeChart comes
with a charting demo application (jfreechart-0.9.17-demo.jar) that has examples
of the various charts and styles. You can run the demo application from the root
directory of the JFree distribution with this command line (adjust the slashes for
your OS if it is not Windows):
java -cp lib\gnujaxp.jar;lib\jcommon-0.9.2.jar;lib\log4j-1.2.8.jar➥
;lib\servlet.jar;jfreechart-0.9.17.jar -jar jfreechart-0.9.17-demo.jar
NOTE
The previous command should all be one line when you type it, but we
had to split it to fit on the printed page.
From the demo application, Figures 14-1 through 14-6 show examples of charts
that JFreeChart can create.
2840ch14.qxd 7/13/04 12:44 PM Page 340
Download at Boykma.Com
Charting with JFreeChart
341
Figure 14-1. A vertical 3D bar chart
Figure 14-2. A pie chart showing an exploded section
Figure 14-3. An XY chart with a gradient background
2840ch14.qxd 7/13/04 12:44 PM Page 341
Download at Boykma.Com
Chapter 14
342
Figure 14-4. An XY scatter plot
Figure 14-5. A Gantt chart
Figure 14-6. A horizontal combined chart, with embedded time series and XY plot
charts
2840ch14.qxd 7/13/04 12:44 PM Page 342
Download at Boykma.Com
Charting with JFreeChart
343
If JFreeChart does not have the exact chart type you need, you may be able
to customize one of the existing chart types to do what you need. The source code
is included with the distribution, so you can look at the existing charts and see
how JFreeChart creates its graphs. Additionally, you can customize how JFreeChart
draws the chart so that it uses your fonts and colors. It is also possible to set the
background image for a chart to anything you like.
Basic JFreeChart Example
Let’s now create a 3D bar chart example using JFreeChart. Applications can display
the charts in Swing, or export charts to Joint Photographic Experts Group (JPEG)
or Portable Network Graphics (PNG) images. Our example will create a PNG file
on disk, and you can view the image in your web browser or another application.
The PNG image format looks much better than JPEG-compressed charts,
because PNG is lossless compression and JPEG is lossy. JPEG is more suitable for
photographic images than for simple charts. Most modern web browsers support
PNG images, although it is not as common on web pages as the JPEG and GIF
formats.
The
org.jfree.chart.ChartFactory
class provides static methods for creating
charts. All of the method signatures are similar, although the inputs needed do
vary with the type of chart being created. We use the
createBarChart3D()
method
on the
ChartFactory
class for our example:
public static JFreeChart createBarChart3D(String title,
String categoryAxisLabel,
String valueAxisLabel,
CategoryDataset dataset,
PlotOrientation orientation,
boolean legend,
boolean tooltips,
boolean urls)
The first argument,
title
, may be null. The category and value axis labels
may also be null. Be sure to keep your category and value axes straight when you
create your data set—this is easy to mix up. For a hypothetical bar chart that rep-
resents the weather in Austin, Texas, the category axis would be Months in 2004,
and the value axis would be Number of Sunny Days.
The 3D bar chart requires a category data set, as an
org.jfree.data.CategoryDataset
object. All of the JFreeChart charts use data sets that inherit from the base
org.jfree.data.Dataset
interface. We discuss data sets in more detail later in this
chapter.
2840ch14.qxd 7/13/04 12:44 PM Page 343
Download at Boykma.Com
Chapter 14
344
The chart can be displayed with a horizontal or a vertical orientation. The
createBarChart3D()
method takes a
PlotOrientation
object. The values are avail-
able as either the
HORIZONTAL
or
VERTICAL
static variable on
PlotOrientation
. The
chart may display a legend if needed. The tooltips on the chart are optional, as is
URL generation. Both tooltips and URLs are used for HTML image maps, if the chart
is clickable in a web browser. JFreeChart can also use the OverLIB (
www.bosrup.com/
web/overlib/
) JavaScript library to generate tooltips for web images. You will need
to include the JavaScript source file overlib.js in your portlet application output.
Data for the 3D Bar Chart
The 3D bar chart requires an
org.jfree.data.CategoryDataset
object as its data
source. The
CategoryDataset
class is an interface. We use the concrete implementa-
tion
org.jfree.data.DefaultCategoryDataset
class to hold our data. For our purposes,
the only method we need to use on the data set class is
addValue(double value,
Comparable rowKey, comparable columnKey)
. This method adds our numerical value
to the data set, with the row key “2004” and the column key “January”, “February”,
or “March”.
The row and column keys refer to the data set’s structure, not necessarily the
way the chart is rendered. If we use more than one row key in a bar chart data
set, we will get multiple bars for each category value. Each bar will have a different
color. We could use this for a chart that visualizes monthly rainfall in different years,
although other chart types (such as a line chart) would probably be better.
Saving the Chart As a PNG Image File
In our example, we export the chart to a PNG image file on our file system. The
chart’s filename is barchart3d.png, and will be created in the working directory
for this Java application.
The PNG image should load in most modern web browsers and image manip-
ulation tools. The
org.jfree.chart.ChartUtilities
class provides methods for
saving charts as JPEG or PNG images, writing JPEG or PNG to an input stream, and
working with image maps:
public static void saveChartAsPNG(File file, JFreeChart chart, int width,➥
int height) throws java.io.IOException
The
saveChartAsPNG()
method we use in the
SimpleChartDemo
example creates
a PNG image out of the chart with the width and height in pixels that we specified.
The file does not have to exist before this method is called, and any existing files
will be overwritten if the file system allows it.
2840ch14.qxd 7/13/04 12:44 PM Page 344
Download at Boykma.Com
Charting with JFreeChart
345
3D Bar Chart Example Source Code
You can execute this charting example from the command line. Your classpath
will need to include the libraries distributed with JFreeChart. With JFreeChart
0.9.17, this would be jcommon-0.9.2.jar, jfreechart-0.9.17.jar, log4j-1.2.8.jar, and
gnujaxp.jar.
package com.portalbook.charting;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.CategoryDataset;
import org.jfree.data.DefaultCategoryDataset;
import java.io.*;
public class SimpleChartDemo
{
protected CategoryDataset createChartData()
{
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.3, "2004", "January");
dataset.addValue(2.6, "2004", "February");
dataset.addValue(4.6, "2004", "March");
return dataset;
}
protected JFreeChart createBarChart3D(CategoryDataset dataset)
{
String title = "Weather in Austin, Texas";
JFreeChart chart =
ChartFactory.createBarChart3D(
title,
"Months in 2004",
"Number of Sunny Days",
dataset,
2840ch14.qxd 7/13/04 12:44 PM Page 345
Download at Boykma.Com
Chapter 14
346
PlotOrientation.VERTICAL,
true,
false,
false);
return chart;
}
protected void saveChartAsPNG(JFreeChart chart) throws IOException
{
File file = new File("barchart3d.png");
ChartUtilities.saveChartAsPNG(file, chart, 400, 300);
}
public static void main(String[] args)
{
SimpleChartDemo demo = new SimpleChartDemo();
CategoryDataset dataset = demo.createChartData();
JFreeChart chart = demo.createBarChart3D(dataset);
try
{
demo.saveChartAsPNG(chart);
}
catch (IOException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
After this application runs, you should have a file called barchart3d.png
in your working directory. Your output should be similar to that shown in
Figure 14-7.
2840ch14.qxd 7/13/04 12:44 PM Page 346
Download at Boykma.Com