Tutorial #2: Bar Chart Application
An example of integrating a bar chart into a Swing application
Introduction
Openchart2 contains components that make the integration of charts into Swing applications simple. A well-commented version of the source code appears at the end of this text.
Step 1: Create Our Application
This example focuses on creating a chart within a Swing application. Our main class will be called BarChart, which will subsequently extend javax.swing.JDialog. More details concerning components within the dialog will follow shortly.
Step 2: Define Some Data
First we must define some simple data to display in our chart. Since we're creating a bar chart, we'll use three categories with floating point values and non-numeric labels. In this example, the following will suffice:
/** Our labels for each bar */
String[] names = {"Shea","Flick","Will"};
/** The value associated with each label */
double[] values = {10.0,30.0,60.0};
The above data will need a slight transformation before constructing the chart.
Step 3: Initialize the Dialog
The dialog is initialized just like any other Swing dialog. In this example, we'll add a menu with an "Exit" option, set the dialog to allow resizing, and apply a BorderLayout to the main content pane. The unremarkable code for these steps appear in the complete source code, but we'll leave these steps to the reader.
Step 4: Create the Chart
Creating the chart is similar to the steps described in Tutorial #1. We first need to transform our data for the chart into a two-dimensional array. Two-dimensional arrays are used heavily to support multiple series in a single chart, but here we'll only be using a single series. The code below performs this task:
Double[][] data = new Double[1][values.length];
for(int i=0;i<values.length;i++) {
data[0][i] = new Double(values[i]);
}
The code is overly complex for this task, but is more illustrative of the process than a more complex implementation. The two-dimensional array is sized to contain 1 series (the first dimension) of values.length points (the second dimension). Double objects are used because points can be null, meaning Openchart2 will ignore them during drawing.
An array of series labels will also be needed. Since we are using a single series in this example, the array has only one element:
String[] series_names = {"Ohmsfords"};Our data is now formatted properly and ready to be passed into a data model constructor. The chart data model object handles all the data used in drawing the graph. Since we are creating a bar chart with a non-numeric x-axis, the ObjectChartDataModel type will be sufficient:
ChartDataModel model = new ObjectChartDataModel(data, names, series_names);
Now that the model is constructed, we can generate a coordinate system object. All graphs require coordinate systems, or CoordSystem objects, which serve multiple purposes. Most importantly, the CoordSystem object handles all chart scaling, providing the transforms from the data-space into the graphics-space. These objects also provide the routines to draw and label the axes. Every CoordSystem object must be linked to some data model for scaling purposes. Below we construct a new CoordSystem object using our new data model:
CoordSystem coord = new CoordSystem(model);
Now that the coordinate system and model are defined, the chart can be constructed. Since we are integrating this chart into Swing, we'll use an Openchart2 chart panel, which actually extends javax.swing.JPanel. The ChartPanel object contains all the necessary updating and painting routines for the chart, simplifying the overrides used in Tutorial #1. Construct the panel as follows:
ChartPanel chart_panel = new ChartPanel(model,"Disapproval Rating");
The chart panel object requires our data model (used in constructing the RowColorModel and Legend) and a string to use as title in our chart. Our new panel will also need a defined coordinate system:
chart_panel.setCoordSystem(coord);
Finally, we need to specify a renderer for the chart to use. The renderer object performs the actual drawing of chart data, and Openchart2 provides numerous types. For tis example, we'll want to use a BarChartRenderer object:
chart_panel.addChartRenderer(new BarChartRenderer(coord,model), 0);
The BarChartRenderer constructor requires both a coordinate system (for determining the data-space to graphics-space transform) and data model. The new renderer is added to the panel at a z-position of 0. The z-position is used when using multiple renderers on a single chart; a higher z-position renderer is drawn on top of a lower z-position renderer. Because we are using only a single renderer in this example, a z-position of 0 will suffice.
At this point, the major chart construction steps have been completed. However, let's assume that our data values are percentages. Openchart2 will scale the coordinate system to the maximum value by default, meaning our y-axis will end at the value 60. If we're looking at percentages, we may want to scale the y-axis from 0 to 100 instead. The following code achieves this:
model.setManualScale(true);
model.setMinimumValue(new Double(0.0));
model.setMaximumValue(new Double(100.0));
The model is first configured for manual scaling. When manual scaling is enabled, the coordinate system object request manually set maximum and minimum values instead of the largest and smallest values occurring in the data to perform the necessary axes drawing and data transform. Next the manual values are set to 0 and 100 for minimum and maximum values respectively. This procedure is possible with any type of chart where manual scaling is desired.
Step 5: Add the Chart to the Dialog
Our chart is now ready for display. As stated earlier, we specified that the content pane of our dialog use a BorderLayout. The completed chart panel can be added at the center position of our layout:
contentPane.add(chart_panel,BorderLayout.CENTER);
The resulting bar chart will now appear in the center of our dialog. No other methods are necessary, and our task is complete.
Conclusion
The resulting Swing application shows a bar chart in the center of a dialog with a menu appearing above it. The dialog can be set to resizeable, and the ChartPanel object will seamlessly handle redraws as a result of the resize. One should note that the chart can be modified within the application. A change such as a new title or scaling can be called at any time. In the complete source code, you'll notice that the scaling is actually performed after the chart is added to the dialog; the scale can be changed at any time, and it is not necessary to construct a new chart just to perform a rescale. A more complex example of a dynamic graph will appear in Tutorial #3. Download the source code to this example to try out the mechanics of Openchart2 yourself!
Source code: Download!