Adding Charts to Web-Based J2EE Applications
Business applications typically manage data. Therefore, developers often need to provide components that enable users to analyze that data. One way to do this is by providing users access to text-based reports. Another option is to provide a view to the data through a series of graphical charts. Charts can be an extremely useful tool because they allow users to visually compare data elements, spotting trends and patterns not easily discernable through reports when dealing with large amounts of data. Much of today's business software is Web-based and delivered through a browser. Nevertheless, requirements for these applications, namely data analysis requirements, remain the same. Luckily, if you are developing software with J2EE technologies, there are some open-source options to assist you. This article will demonstrate how J2EE developers can quickly add visually-appealing, graphical charts to their work.
JFreeChart and Cewolf—A Powerful Combination
JFree.org is a Web site that hosts many useful open-source projects. JFreeChart is just one such project. It is managed by David Gilbert. JFreeChart consists of a number of Java libraries that generate graphical charts based upon a set of data.
Cewolf is another open-source project. Cewolf comes with its own set of libraries, as well as a collection of JSP tags. The Cewolf project, founded by Guido Laures, gives developers an easy way to display JFreeChart-built charts in a JSP page. In other words, Cewolf is a layer that rests upon JFreeChart. Cewolf provides data input to JFreeChart, then displays the resulting image in a browser, as dictated by the JSP tags. Both projects' libraries are necessary to achieve the desired goal. The most recent version of Cewolf, version 0.9.8, supports JFreeChart up through, not by coincidence, version 0.9.8.
Concepts and Terminology
Graphical charts display one or more data 'series'. In some cases, these series may then be grouped into one or more 'categories'. A series is simply a collection of data values that is defined by name. For example, if we were to poll individuals on their favorite season, then 'Spring', 'Summer', 'Fall', and 'Winter' become the series names. In charts, each series is assigned a unique color or pattern and it usually appears in a legend. It is possible to group series into categories. If our previously mentioned poll were to be conducted over the course of two calendar years, year becomes a category that groups two sets of data series, one for each year. Deciding on a particular chart to represent your data (pie, line, bar, and so forth) often depends not only on how you want to display your data, but also on the complexity of the data you need to represent.
Charts display data, usually from a database, so JFreeChart requires a data source to perform its work. JFreeChart defines a base Java interface, called Dataset, to provide this data. Two of the most common Datasets are the CategoryDataset and the PieDataset. As you would expect, a PieDataset provides data to create pie charts. Pie charts are the simplest type of chart. They display a value for data series, and how each value contributes to the total value for all series. CategoryDataset is an interface for a more complex set of data that represents one or more series grouped by categories.
Cewolf provides an interface called DatasetProducer. Developers implement this interface to provide data to JFreeChart from a Web application. It is a DatasetProducer's responsibility to provide requested data, in the form of a JFreeChart Dataset, so that a chart may be constructed.
In this section, you will focus on the technical details necessary to add a pie chart to an application. The first requirement for this task is some sample data. I have created employee and department tables for the examples. Here is a bit of SQL used to create data in an hsql database:
CREATE TABLE dept ( dept_id INT NOT NULL IDENTITY, name VARCHAR(30) NOT NULL, descrip VARCHAR(200) ); CREATE TABLE emp ( emp_id INT NOT NULL IDENTITY, dept_id INT NOT NULL, f_name VARCHAR(30), l_name VARCHAR(30), hire_date DATE, CONSTRAINT fk_dept_id FOREIGN KEY (dept_id) REFERENCES dept (dept_id) ); INSERT INTO dept (name,descrip) VALUES('IT', 'Information Technology'); INSERT INTO dept (name,descrip) VALUES('ACCT', 'Corporate Accounting'); INSERT INTO dept (name,descrip) VALUES('MRKT', 'Sales and Marketing'); INSERT INTO dept (name,descrip) VALUES('HR', 'Human Resources and Payroll'); INSERT INTO emp(dept_id,f_name,l_name,hire_date) VALUES(0,'Mike','Smith','2003-01-29'); INSERT INTO emp(dept_id,f_name,l_name,hire_date) VALUES(0,'Joe','Taylor','2003-04-15'); INSERT INTO emp(dept_id,f_name,l_name,hire_date) VALUES(0,'Jennifer','Betts','2003-05-07'); ... --(more employees...) ...
Employees may be hired into one of four departments. The date of hire for each employee is captured in the emp table. Here is the entire SQL script if you would like to use it to compare against the charts you will derive from it.
In your Web application, you will need to include a number of libraries, including those from Cewolf and JFreeChart. By downloading the Cewolf distribution, you will receive all the necessary jar files. You should not need to download additional JFreeChart files. Place these jar files in your WEB-INF/lib folder:
Cewolf relies on a Java servlet, called CewolfRenderer, to render charts. This servlet accepts two input parameters. I will discuss these parameters below. For now, include the following servlet and servlet mapping definitions in your WEB-INF/web.xml:
<servlet> <servlet-name>CewolfServlet</servlet-name> <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class> <!-- sets storage implementation --> <init-param> <param-name>storage</param-name> <param-value>de.laures.cewolf.storage. TransientSessionStorage</param-value> </init-param> <!-- sets overlib.js location relative to webapp --> <init-param> <param-name>overliburl</param-name> <param-value>etc/overlib.js</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>CewolfServlet</servlet-name> <url-pattern>/cewolf/*</url-pattern> </servlet-mapping>