JFreeChart Extension II

Purpose

Many business applications need to display business charts. This contribution shows how the free chart library JFreeChart can be integrated into ULC applications.

The integration is done entirely on the server side. This approach has the advantage that beside the standard ULC libraries and a small extension no additional libraries (especially the large JFreeChart library) have to be deployed on the client. As a drawback, since the JFreeChart library heavily relies on Java2D, the integration will only work for server configurations with headless support and with JDK 1.4.2 installed. On the client side JDK 1.3.1 or higher is required.

Screenshots

jfreechartextensionII_1 jfreechartextensionII_2

Features

Features of the extension

  • Implements the mouse event handling of JFreeChart: double-clicking on the chart entity or the legend triggers a chart entity clicked event; double-clicking on the chart (except on a chart entity or the legend) triggers a chart clicked event; zooming the chart triggers a chart zoomed event.
  • The chart can be zoomed in and out along the horizontal and vertical axis using an adjustable scale factor. Note that a category chart (bar chart, stacked chart etc.) cannot be zoomed horizontally and a pie chart cannot be zoomed at all. In addition, it is possible to reset the zoom to its initial state.
  • If the horizontal and / or the vertical zoom trace lines are enabled, it is possible to zoom in or out on charts in an interactive way. Drag a rectangle over the area you want to zoom in. The selected area is highlighted. In order to reset the zoom, just press the mouse button and move upwards before release it.
  • There are predefined standard colors (based on Microsoft Excel colors) for each data series and for the legend items.
  • Resizing the window automatically adjusts the chart size.

Features of the sample application

  • The data used in the charts is random. It is possible to create new random data, which in turn triggers the chart to be redrawn. In addition to the data values, the series and category numbers are also generated randomly.
  • Double-click on a chart entity (e.g. on a bar or on a pie section) to display an item properties dialog. Use this dialog to set the border and the area color of the selected entity.
  • Double-click the legend to display the legend properties dialog. Use this dialog to set the border, the area and the font color of the legend.
  • Double-click the chart dialog box or right-click to open the popup menu and then select "Chart Properties" to open the chart properties dialog. Note that you can click any part of the chart dialog box except the legend or the chart entities. Set the chart type, the title, the axis labels, and the plot orientation. Turn on or turn off the display of the border, the legend and the horizontal and vertical trace lines in order to zoom in on charts. Note that it is not possible to set the axis labels and the plot orientation for pie charts.
  • Select the predefined standard colors by clicking the "automatic" radio button.

How to use

A sample usage of the JFreeChart Extension II is provided in com.canoo.ulc.community.jfreechart.server.JFreeChartSampleApplication.

ULCJFreeChart is simply an ULCComponent containing a JFreeChart object. Thus the first step is to instantiate an ULCJFreeChart object and to set the chart in this component. It is absolutely necessary to inform the ULCJFreeChart object about the chart's size because this will be needed afterwards when creating the image.

...ULCJFreeChart chartComponent = new ULCJFreeChart();
JFreeChart chart = SimpleChartFactory.createChart(...);
Dimension chartSize = new Dimension(400, 400);
chartComponent.setChart(chart, chartSize);

...

Now additional operations can be performed on the chart component object (e.g. zooming on the chart or adding a popup menu).

...chartComponent.zoomVerticalAxes(0.25, 0.75);
...
chartComponent.zoomHorizontalAxes(-0.50, 1.50);
...
chartComponent.setPopupMenu(createChartPopup());...

Remember that at least one trace line has to be activated before the user is able to zoom interactively. In order to activate the trace lines, use the following operations.

...chartComponent.setShowHorizontalTraceLine(true);
chartComponent.setShowVerticalTraceLine(true);
...

There are two listeners that can be added to the chart component. One is the IChartComponentListener, which is always notified after the size of the chart component is changed, and the other is the IChartEventListener, which is informed when a mouse event (e.g. double-click on a chart entity) occurred on the chart. The listeners can easily be added to the chart component as follows:

...chartComponent.addChartComponentListener(new IChartComponentListener() {

     public void chartResized(UlcChartComponentEvent event) {
          System.out.println("latest chart size: "+event.getChartComponentSize());
     }
});chartComponent.addChartEventListener(new IChartEventListener() {

     public void chartClicked(UlcChartEvent event) {...}
     public void chartEntityClicked(UlcChartEvent event) {
          ChartEntity entity = event.getChartEntity();
          System.out.println("entity coordinates: "+entity.getShapeCoords());
     }

     public void chartZoomed(UlcChartEvent event) {...}
});...

ULCJFreeChartConstants, included in the integration, provides some useful constants and methods.

How it is implemented

The core components are ULCJFreeChart and UIJFreeChart. ULCJFreeChart provides an API to set a JFreeChart chart, to zoom on the chart, as well as to register an IChartComponentListener to receive notifications when the chart size changes and an IChartEventListener to receive notifications when a mouse event occurred on the chart.

The ULCJFreeChart converts the chart into a PNG image and sends the image plus a list of all chart entities containing all relevant information about the image to the UIJFreeChart. The UIJFreeChart then displays the chart image. When the user resizes the component enclosing the chart image, the new size is sent to the ULCJFreeChart, which then creates a new chart image of the appropriate size and sends it back to the client.

The ULCChartEntity and the UIChartEntity wrap JFreeChart's ChartEntity. This is necessary because the server and the client must be able to communicate with each other whenever possible using high-level events. The UIJFreeChart finds out which entity has been selected by the user and sends it (enabled by ULCChartEntity and UIChartEntity) to the server where further operations can be executed.

UIJFreeChart handles all zoom feedback on the client side. This has the advantage that no server roundtrip is necessary until the user has finished drawing his zoom rectangle, which eventually triggers the zoom event. The same applies to the mouse event handling.

Resources