The JFree Chart Class Library Developer Guide V1 0 9
User Manual:
Open the PDF directly: View PDF
.
Page Count: 805
| Download | |
| Open PDF In Browser | View PDF |
The JFreeChart Class Library
Version 1.0.9
Developer Guide
Written by David Gilbert
January 7, 2008
c 2000-2008, Object Refinery Limited. All rights reserved.
IMPORTANT NOTICE:
We work hard to make this document as accurate and informative as we can, but
cannot guarantee that it is error-free.
Contents
1 Introduction
1.1 What is JFreeChart? . . . .
1.2 This Document . . . . . . .
1.3 Acknowledgements . . . . .
1.4 Comments and Suggestions
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
16
18
18
18
2 Sample Charts
2.1 Introduction . . . . . . . . . . .
2.2 Pie Charts . . . . . . . . . . . .
2.3 Bar Charts . . . . . . . . . . .
2.4 Line Chart . . . . . . . . . . .
2.5 XY Plots . . . . . . . . . . . .
2.6 Time Series Charts . . . . . . .
2.7 Histograms . . . . . . . . . . .
2.8 Area Charts . . . . . . . . . . .
2.9 Difference Chart . . . . . . . .
2.10 Step Chart . . . . . . . . . . .
2.11 Gantt Chart . . . . . . . . . . .
2.12 Multiple Axis Charts . . . . . .
2.13 Combined and Overlaid Charts
2.14 Future Development . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
19
21
23
24
25
26
27
27
29
30
31
32
33
3 Downloading and Installing JFreeChart
3.1 Introduction . . . . . . . . . . . . . . . . .
3.2 Download . . . . . . . . . . . . . . . . . .
3.3 Unpacking the Files . . . . . . . . . . . .
3.4 Running the Demonstration Applications
3.5 Configuring JFreeChart for use in IDEs .
3.6 Compiling the Source . . . . . . . . . . .
3.7 Generating the Javadoc Documentation .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
34
34
34
34
35
36
36
36
.
.
.
.
4 Using JFreeChart
37
4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.2 Creating Your First Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5 Pie
5.1
5.2
5.3
5.4
5.5
5.6
5.7
Charts
Introduction . . . . . . . . . . .
Creating a Simple Pie Chart . .
Section Colours . . . . . . . . .
Section Outlines . . . . . . . .
Null, Zero and Negative Values
Section and Legend Labels . . .
Exploded Sections . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
40
40
40
40
41
41
42
42
CONTENTS
5.8
5.9
6 Bar
6.1
6.2
6.3
6.4
6.5
2
3D Pie Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Multiple Pie Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
43
Charts
Introduction . . . . . . . . .
A Bar Chart . . . . . . . .
The ChartFactory Class . .
Simple Chart Customisation
Customising the Renderer .
45
45
45
48
48
49
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7 Line Charts
51
7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
7.2 A Line Chart Based On A Category Dataset . . . . . . . . . . . . . . . . . . . . . . 51
7.3 A Line Chart Based On An XYDataset . . . . . . . . . . . . . . . . . . . . . . . . . 56
8 Time Series Charts
61
8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.2 Time Series Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9 Customising Charts
9.1 Introduction . . .
9.2 Chart Attributes
9.3 Plot Attributes .
9.4 Axis Attributes .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
67
67
67
69
70
10 Dynamic Charts
72
10.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
10.2 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
10.3 The Demo Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
11 Tooltips
11.1 Overview . . . . . . .
11.2 Generating Tool Tips .
11.3 Collecting Tool Tips .
11.4 Displaying Tool Tips .
11.5 Disabling Tool Tips .
11.6 Customising Tool Tips
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
77
77
77
78
78
78
78
12 Item Labels
12.1 Introduction . . . . . . . . . . . . . . .
12.2 Displaying Item Labels . . . . . . . . .
12.3 Item Label Appearance . . . . . . . .
12.4 Item Label Positioning . . . . . . . . .
12.5 Customising the Item Label Text . . .
12.6 Example 1 - Values Above a Threshold
12.7 Example 2 - Displaying Percentages .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
79
79
80
81
82
83
84
87
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13 Multiple Axes and Datasets
91
13.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
13.2 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
13.3 Hints and Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
CONTENTS
3
14 Combined Charts
14.1 Introduction . . . . . . . . . . . .
14.2 Combined Domain Category Plot
14.3 Combined Range Category Plot .
14.4 Combined Domain XY Plot . . .
14.5 Combined Range XY Plot . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15 Datasets and JDBC
15.1 Introduction . . . . . . .
15.2 About JDBC . . . . . .
15.3 Sample Data . . . . . .
15.4 PostgreSQL . . . . . . .
15.5 The JDBC Driver . . .
15.6 The Demo Applications
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
99
. 99
. 99
. 99
. 100
. 101
. 102
PDF
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16 Exporting Charts to Acrobat
16.1 Introduction . . . . . . . . .
16.2 What is Acrobat PDF? . .
16.3 iText . . . . . . . . . . . . .
16.4 Graphics2D . . . . . . . . .
16.5 Getting Started . . . . . . .
16.6 The Application . . . . . .
16.7 Viewing the PDF File . . .
16.8 Unicode Characters . . . . .
17 Exporting Charts to SVG
17.1 Introduction . . . . . . .
17.2 Background . . . . . . .
17.3 A Sample Application .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
94
94
94
95
96
97
103
103
103
103
103
104
104
108
108
Format
111
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
18 Applets
114
18.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
18.2 Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
18.3 A Sample Applet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
19 Servlets
19.1 Introduction . . . . . . . . . . . . .
19.2 A Simple Servlet . . . . . . . . . .
19.3 Compiling the Servlet . . . . . . .
19.4 Deploying the Servlet . . . . . . .
19.5 Embedding Charts in HTML Pages
19.6 Supporting Files . . . . . . . . . .
19.7 Deploying Servlets . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
118
118
118
120
121
121
126
127
20 Miscellaneous
20.1 Introduction . . . . .
20.2 X11 / Headless Java
20.3 Java Server Pages . .
20.4 Loading Images . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
129
129
129
129
129
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21 Packages
130
21.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
CONTENTS
22 Package: org.jfree.chart
22.1 Overview . . . . . . .
22.2 ChartColor . . . . . .
22.3 ChartFactory . . . . .
22.4 ChartFrame . . . . . .
22.5 ChartMouseEvent . .
22.6 ChartMouseListener .
22.7 ChartPanel . . . . . .
22.8 ChartRenderingInfo .
22.9 ChartUtilities . . . . .
22.10ClipPath . . . . . . . .
22.11DrawableLegendItem .
22.12Effect3D . . . . . . . .
22.13HashUtilities . . . . .
22.14JFreeChart . . . . . .
22.15LegendItem . . . . . .
22.16LegendItemCollection
22.17LegendItemSource . .
22.18LegendRenderingOrder
22.19PolarChartPanel . . .
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
131
131
131
131
134
135
136
136
141
142
144
144
144
145
145
150
152
153
154
154
23 Package: org.jfree.chart.annotations
23.1 Overview . . . . . . . . . . . . . . .
23.2 AbstractXYAnnotation . . . . . . .
23.3 CategoryAnnotation . . . . . . . . .
23.4 CategoryLineAnnotation . . . . . . .
23.5 CategoryPointerAnnotation . . . . .
23.6 CategoryTextAnnotation . . . . . . .
23.7 TextAnnotation . . . . . . . . . . . .
23.8 XYAnnotation . . . . . . . . . . . .
23.9 XYBoxAnnotation . . . . . . . . . .
23.10XYDrawableAnnotation . . . . . . .
23.11XYImageAnnotation . . . . . . . . .
23.12XYLineAnnotation . . . . . . . . . .
23.13XYPointerAnnotation . . . . . . . .
23.14XYPolygonAnnotation . . . . . . . .
23.15XYShapeAnnotation . . . . . . . . .
23.16XYTextAnnotation . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
155
155
155
157
157
159
161
162
164
165
166
167
168
169
171
173
174
24 Package: org.jfree.chart.axis
24.1 Overview . . . . . . . . . .
24.2 Axis . . . . . . . . . . . . .
24.3 AxisCollection . . . . . . .
24.4 AxisLocation . . . . . . . .
24.5 AxisSpace . . . . . . . . . .
24.6 AxisState . . . . . . . . . .
24.7 CategoryAnchor . . . . . .
24.8 CategoryAxis . . . . . . . .
24.9 CategoryAxis3D . . . . . .
24.10CategoryLabelPosition . . .
24.11CategoryLabelPositions . .
24.12CategoryLabelWidthType .
24.13CategoryTick . . . . . . . .
24.14ColorBar . . . . . . . . . .
24.15CompassFormat . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
177
177
177
182
182
183
183
184
184
189
190
191
191
192
192
192
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CONTENTS
24.16CyclicNumberAxis . . .
24.17DateAxis . . . . . . . .
24.18DateTickMarkPosition .
24.19DateTick . . . . . . . .
24.20DateTickUnit . . . . . .
24.21ExtendedCategoryAxis .
24.22LogAxis . . . . . . . . .
24.23LogarithmicAxis . . . .
24.24MarkerAxisBand . . . .
24.25ModuloAxis . . . . . . .
24.26MonthDateFormat . . .
24.27NumberAxis . . . . . . .
24.28NumberAxis3D . . . . .
24.29NumberTick . . . . . . .
24.30NumberTickUnit . . . .
24.31PeriodAxis . . . . . . .
24.32PeriodAxisLabelInfo . .
24.33QuarterDateFormat . .
24.34SegmentedTimeline . . .
24.35StandardTickUnitSource
24.36SubCategoryAxis . . . .
24.37SymbolAxis . . . . . . .
24.38Tick . . . . . . . . . . .
24.39TickType . . . . . . . .
24.40TickUnit . . . . . . . . .
24.41TickUnits . . . . . . . .
24.42TickUnitSource . . . . .
24.43Timeline . . . . . . . . .
24.44ValueAxis . . . . . . . .
24.45ValueTick . . . . . . . .
5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
193
194
198
198
199
200
200
203
204
205
206
207
211
212
213
214
216
218
218
219
220
221
223
223
223
224
225
225
226
229
25 Package: org.jfree.chart.block
25.1 Introduction . . . . . . . . . .
25.2 AbstractBlock . . . . . . . . .
25.3 Arrangement . . . . . . . . .
25.4 Block . . . . . . . . . . . . .
25.5 BlockBorder . . . . . . . . . .
25.6 BlockContainer . . . . . . . .
25.7 BlockFrame . . . . . . . . . .
25.8 BlockParams . . . . . . . . .
25.9 BlockResult . . . . . . . . . .
25.10BorderArrangement . . . . .
25.11CenterArrangement . . . . .
25.12ColorBlock . . . . . . . . . .
25.13ColumnArrangement . . . . .
25.14EmptyBlock . . . . . . . . . .
25.15EntityBlockParams . . . . . .
25.16EntityBlockResult . . . . . .
25.17FlowArrangement . . . . . . .
25.18GridArrangement . . . . . . .
25.19LabelBlock . . . . . . . . . .
25.20LengthConstraintType . . . .
25.21LineBorder . . . . . . . . . .
25.22RectangleConstraint . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
231
231
231
233
234
234
235
237
237
237
238
238
238
239
240
240
240
240
241
241
243
243
244
CONTENTS
26 Package: org.jfree.chart.editor
26.1 Introduction . . . . . . . . . .
26.2 ChartEditor . . . . . . . . . .
26.3 ChartEditorFactory . . . . .
26.4 ChartEditorManager . . . . .
26.5 DefaultAxisEditor . . . . . .
26.6 DefaultChartEditor . . . . . .
26.7 DefaultChartEditorFactory .
26.8 DefaultColorBarEditor . . . .
26.9 DefaultNumberAxisEditor . .
26.10DefaultPlotEditor . . . . . .
26.11DefaultTitleEditor . . . . . .
26.12PaletteChooserPanel . . . . .
26.13PaletteSample . . . . . . . . .
6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
246
246
246
246
247
247
247
248
248
249
249
249
249
250
27 Package: org.jfree.chart.encoders
27.1 Introduction . . . . . . . . . . . .
27.2 EncoderUtil . . . . . . . . . . . .
27.3 ImageEncoderFactory . . . . . .
27.4 ImageEncoder . . . . . . . . . . .
27.5 ImageFormat . . . . . . . . . . .
27.6 KeyPointPNGEncoderAdapter .
27.7 SunJPEGEncoderAdapter . . . .
27.8 SunPNGEncoderAdapter . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
251
251
251
252
253
253
253
254
255
28 Package: org.jfree.chart.entity
28.1 Introduction . . . . . . . . . .
28.2 Background . . . . . . . . . .
28.3 CategoryItemEntity . . . . .
28.4 ChartEntity . . . . . . . . . .
28.5 ContourEntity . . . . . . . .
28.6 EntityCollection . . . . . . .
28.7 LegendItemEntity . . . . . .
28.8 PieSectionEntity . . . . . . .
28.9 StandardEntityCollection . .
28.10TickLabelEntity . . . . . . .
28.11XYAnnotationEntity . . . . .
28.12XYItemEntity . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
256
256
256
256
258
258
259
259
260
260
261
262
262
29 Package: org.jfree.chart.event
29.1 Introduction . . . . . . . . . .
29.2 AxisChangeEvent . . . . . . .
29.3 AxisChangeListener . . . . .
29.4 ChartChangeEvent . . . . . .
29.5 ChartChangeEventType . . .
29.6 ChartChangeListener . . . . .
29.7 ChartProgressEvent . . . . .
29.8 ChartProgressListener . . . .
29.9 MarkerChangeEvent . . . . .
29.10MarkerChangeListener . . . .
29.11PlotChangeEvent . . . . . . .
29.12PlotChangeListener . . . . .
29.13RendererChangeEvent . . . .
29.14RendererChangeListener . . .
29.15TitleChangeEvent . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
263
263
263
263
264
264
265
265
266
266
267
267
268
268
268
269
.
.
.
.
.
.
.
.
.
.
.
.
.
CONTENTS
7
29.16TitleChangeListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
30 Package: org.jfree.chart.imagemap
30.1 Overview . . . . . . . . . . . . . . . . . . . .
30.2 DynamicDriveToolTipTagFragmentGenerator
30.3 ImageMapUtilities . . . . . . . . . . . . . . .
30.4 OverLIBToolTipTagFragmentGenerator . . .
30.5 StandardToolTipTagFragmentGenerator . . .
30.6 StandardURLTagFragmentGenerator . . . . .
30.7 ToolTipTagFragmentGenerator . . . . . . . .
30.8 URLTagFragmentGenerator . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
270
270
270
270
271
271
272
272
273
31 Package: org.jfree.chart.labels
31.1 Introduction . . . . . . . . . . . . . . . .
31.2 AbstractCategoryItemLabelGenerator .
31.3 AbstractPieItemLabelGenerator . . . . .
31.4 AbstractXYItemLabelGenerator . . . .
31.5 BoxAndWhiskerToolTipGenerator . . .
31.6 BoxAndWhiskerXYToolTipGenerator .
31.7 CategoryItemLabelGenerator . . . . . .
31.8 CategorySeriesLabelGenerator . . . . .
31.9 CategoryToolTipGenerator . . . . . . .
31.10ContourToolTipGenerator . . . . . . . .
31.11CustomXYToolTipGenerator . . . . . .
31.12HighLowItemLabelGenerator . . . . . .
31.13IntervalCategoryItemLabelGenerator . .
31.14IntervalCategoryToolTipGenerator . . .
31.15ItemLabelAnchor . . . . . . . . . . . . .
31.16ItemLabelPosition . . . . . . . . . . . .
31.17MultipleXYSeriesLabelGenerator . . . .
31.18PieSectionLabelGenerator . . . . . . . .
31.19PieToolTipGenerator . . . . . . . . . . .
31.20StandardCategoryItemLabelGenerator .
31.21StandardCategorySeriesLabelGenerator
31.22StandardCategoryToolTipGenerator . .
31.23StandardContourToolTipGenerator . . .
31.24StandardPieSectionLabelGenerator . . .
31.25StandardPieToolTipGenerator . . . . . .
31.26StandardXYItemLabelGenerator . . . .
31.27StandardXYSeriesLabelGenerator . . . .
31.28StandardXYToolTipGenerator . . . . .
31.29StandardXYZToolTipGenerator . . . . .
31.30SymbolicXYItemLabelGenerator . . . .
31.31XYItemLabelGenerator . . . . . . . . .
31.32XYSeriesLabelGenerator . . . . . . . . .
31.33XYToolTipGenerator . . . . . . . . . . .
31.34XYZToolTipGenerator . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
274
274
274
275
276
278
278
278
279
279
280
280
280
281
282
282
283
284
285
286
286
287
288
289
289
291
292
293
294
295
296
296
296
297
297
32 Package: org.jfree.chart.needle
32.1 Overview . . . . . . . . . . .
32.2 ArrowNeedle . . . . . . . . .
32.3 LineNeedle . . . . . . . . . .
32.4 LongNeedle . . . . . . . . . .
32.5 MeterNeedle . . . . . . . . . .
32.6 PinNeedle . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
299
299
299
300
300
300
301
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CONTENTS
32.7 PlumNeedle .
32.8 PointerNeedle
32.9 ShipNeedle .
32.10WindNeedle .
8
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
301
302
302
302
33 Package: org.jfree.chart.plot
33.1 Overview . . . . . . . . . . . .
33.2 CategoryMarker . . . . . . . .
33.3 CategoryPlot . . . . . . . . . .
33.4 ColorPalette . . . . . . . . . . .
33.5 CombinedDomainCategoryPlot
33.6 CombinedDomainXYPlot . . .
33.7 CombinedRangeCategoryPlot .
33.8 CombinedRangeXYPlot . . . .
33.9 CompassPlot . . . . . . . . . .
33.10ContourPlot . . . . . . . . . . .
33.11ContourPlotUtilities . . . . . .
33.12ContourValuePlot . . . . . . .
33.13CrosshairState . . . . . . . . .
33.14DatasetRenderingOrder . . . .
33.15DefaultDrawingSupplier . . . .
33.16DialShape . . . . . . . . . . . .
33.17DrawingSupplier . . . . . . . .
33.18FastScatterPlot . . . . . . . . .
33.19GreyPalette . . . . . . . . . . .
33.20IntervalMarker . . . . . . . . .
33.21Marker . . . . . . . . . . . . . .
33.22MeterInterval . . . . . . . . . .
33.23MeterPlot . . . . . . . . . . . .
33.24MultiplePiePlot . . . . . . . . .
33.25PieLabelDistributor . . . . . .
33.26PieLabelRecord . . . . . . . . .
33.27PiePlot . . . . . . . . . . . . .
33.28PiePlot3D . . . . . . . . . . . .
33.29PiePlotState . . . . . . . . . . .
33.30Plot . . . . . . . . . . . . . . .
33.31PlotOrientation . . . . . . . . .
33.32PlotRenderingInfo . . . . . . .
33.33PlotState . . . . . . . . . . . .
33.34PlotUtilities . . . . . . . . . . .
33.35PolarPlot . . . . . . . . . . . .
33.36RainbowPalette . . . . . . . . .
33.37RingPlot . . . . . . . . . . . . .
33.38SeriesRenderingOrder . . . . .
33.39SpiderWebPlot . . . . . . . . .
33.40ThermometerPlot . . . . . . . .
33.41ValueAxisPlot . . . . . . . . . .
33.42ValueMarker . . . . . . . . . .
33.43WaferMapPlot . . . . . . . . .
33.44XYPlot . . . . . . . . . . . . .
33.45Zoomable . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
304
304
304
306
311
312
313
315
316
317
320
321
321
321
321
322
323
324
325
328
328
330
334
335
339
342
342
342
354
356
356
361
361
363
363
363
368
368
370
370
375
382
382
383
383
393
CONTENTS
9
34 Package: org.jfree.chart.plot.dial
34.1 Overview . . . . . . . . . . . . .
34.2 AbstractDialLayer . . . . . . . .
34.3 ArcDialFrame . . . . . . . . . . .
34.4 DialBackground . . . . . . . . . .
34.5 DialCap . . . . . . . . . . . . . .
34.6 DialFrame . . . . . . . . . . . . .
34.7 DialLayer . . . . . . . . . . . . .
34.8 DialLayerChangeEvent . . . . . .
34.9 DialLayerChangeListener . . . .
34.10DialPlot . . . . . . . . . . . . . .
34.11DialPointer . . . . . . . . . . . .
34.12DialPointer.Pin . . . . . . . . . .
34.13DialPointer.Pointer . . . . . . . .
34.14DialScale . . . . . . . . . . . . .
34.15DialTextAnnotation . . . . . . .
34.16DialValueIndicator . . . . . . . .
34.17SimpleDialFrame . . . . . . . . .
34.18StandardDialRange . . . . . . . .
34.19StandardDialScale . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
395
395
395
397
398
399
401
401
402
403
403
406
407
408
409
410
411
414
415
417
35 Package: org.jfree.chart.renderer
35.1 Overview . . . . . . . . . . . . .
35.2 AbstractRenderer . . . . . . . . .
35.3 AreaRendererEndType . . . . . .
35.4 DefaultPolarItemRenderer . . . .
35.5 GrayPaintScale . . . . . . . . . .
35.6 LookupPaintScale . . . . . . . . .
35.7 NotOutlierException . . . . . . .
35.8 Outlier . . . . . . . . . . . . . . .
35.9 OutlierList . . . . . . . . . . . .
35.10OutlierListCollection . . . . . . .
35.11PaintScale . . . . . . . . . . . . .
35.12PolarItemRenderer . . . . . . . .
35.13RendererState . . . . . . . . . . .
35.14WaferMapRenderer . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
421
421
421
440
440
441
442
443
443
444
444
444
445
446
446
36 Package: org.jfree.chart.renderer.category
36.1 Overview . . . . . . . . . . . . . . . . . . .
36.2 AbstractCategoryItemRenderer . . . . . . .
36.3 AreaRenderer . . . . . . . . . . . . . . . . .
36.4 BarRenderer . . . . . . . . . . . . . . . . .
36.5 BarRenderer3D . . . . . . . . . . . . . . . .
36.6 BoxAndWhiskerRenderer . . . . . . . . . .
36.7 CategoryItemRenderer . . . . . . . . . . . .
36.8 CategoryItemRendererState . . . . . . . . .
36.9 CategoryStepRenderer . . . . . . . . . . . .
36.10DefaultCategoryItemRenderer . . . . . . . .
36.11GanttRenderer . . . . . . . . . . . . . . . .
36.12GroupedStackedBarRenderer . . . . . . . .
36.13IntervalBarRenderer . . . . . . . . . . . . .
36.14LayeredBarRenderer . . . . . . . . . . . . .
36.15LevelRenderer . . . . . . . . . . . . . . . . .
36.16LineAndShapeRenderer . . . . . . . . . . .
36.17LineRenderer3D . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
447
447
447
451
452
457
459
460
470
471
473
473
474
475
476
477
479
483
CONTENTS
10
36.18MinMaxCategoryRenderer . . . .
36.19ScatterRenderer . . . . . . . . . .
36.20StackedAreaRenderer . . . . . . .
36.21StackedBarRenderer . . . . . . .
36.22StackedBarRenderer3D . . . . . .
36.23StatisticalBarRenderer . . . . . .
36.24StatisticalLineAndShapeRenderer
36.25WaterfallBarRenderer . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
485
487
490
490
492
494
495
497
37 Package: org.jfree.chart.renderer.xy
37.1 Overview . . . . . . . . . . . . . . .
37.2 AbstractXYItemRenderer . . . . . .
37.3 CandlestickRenderer . . . . . . . . .
37.4 ClusteredXYBarRenderer . . . . . .
37.5 CyclicXYItemRenderer . . . . . . . .
37.6 DefaultXYItemRenderer . . . . . . .
37.7 DeviationRenderer . . . . . . . . . .
37.8 HighLowRenderer . . . . . . . . . .
37.9 StackedXYAreaRenderer . . . . . . .
37.10StackedXYAreaRenderer2 . . . . . .
37.11StackedXYBarRenderer . . . . . . .
37.12StandardXYItemRenderer . . . . . .
37.13VectorRenderer . . . . . . . . . . . .
37.14WindItemRenderer . . . . . . . . . .
37.15XYAreaRenderer . . . . . . . . . . .
37.16XYBarRenderer . . . . . . . . . . . .
37.17XYBlockRenderer . . . . . . . . . .
37.18XYBoxAndWhiskerRenderer . . . .
37.19XYBubbleRenderer . . . . . . . . . .
37.20XYDifferenceRenderer . . . . . . . .
37.21XYDotRenderer . . . . . . . . . . .
37.22XYErrorRenderer . . . . . . . . . . .
37.23XYItemRenderer . . . . . . . . . . .
37.24XYItemRendererState . . . . . . . .
37.25XYLineAndShapeRenderer . . . . .
37.26XYSplineRenderer . . . . . . . . . .
37.27XYStepRenderer . . . . . . . . . . .
37.28XYStepAreaRenderer . . . . . . . .
37.29YIntervalRenderer . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
500
500
500
505
508
509
510
510
512
513
515
516
518
521
523
523
525
527
529
530
532
534
535
537
547
548
554
556
557
558
38 Package: org.jfree.chart.servlet
38.1 Overview . . . . . . . . . . . .
38.2 ChartDeleter . . . . . . . . . .
38.3 DisplayChart . . . . . . . . . .
38.4 ServletUtilities . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
560
560
560
560
560
39 Package: org.jfree.chart.title
39.1 Overview . . . . . . . . . .
39.2 Events . . . . . . . . . . . .
39.3 CompositeTitle . . . . . . .
39.4 DateTitle . . . . . . . . . .
39.5 ImageTitle . . . . . . . . . .
39.6 LegendGraphic . . . . . . .
39.7 LegendItemBlockContainer
39.8 LegendTitle . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
562
562
562
562
563
564
564
566
567
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CONTENTS
11
39.9 PaintScaleLegend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
39.10TextTitle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
39.11Title . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
40 Package: org.jfree.chart.urls
40.1 Overview . . . . . . . . . . . . .
40.2 CategoryURLGenerator . . . . .
40.3 CustomPieURLGenerator . . . .
40.4 CustomXYURLGenerator . . . .
40.5 PieURLGenerator . . . . . . . .
40.6 StandardCategoryURLGenerator
40.7 StandardPieURLGenerator . . .
40.8 StandardXYURLGenerator . . .
40.9 StandardXYZURLGenerator . .
40.10TimeSeriesURLGenerator . . . .
40.11URLUtilities . . . . . . . . . . .
40.12XYURLGenerator . . . . . . . .
40.13XYZURLGenerator . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
577
577
577
578
579
579
579
581
582
583
583
583
583
584
41 Package: org.jfree.chart.util
585
41.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
41.2 RelativeDateFormat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
42 Package: org.jfree.data
42.1 Introduction . . . . . . . . . .
42.2 ComparableObjectItem . . .
42.3 ComparableObjectSeries . . .
42.4 DataUtilities . . . . . . . . .
42.5 DefaultKeyedValue . . . . . .
42.6 DefaultKeyedValues . . . . .
42.7 DefaultKeyedValues2D . . . .
42.8 DomainInfo . . . . . . . . . .
42.9 DomainOrder . . . . . . . . .
42.10KeyedObject . . . . . . . . .
42.11KeyedObjects . . . . . . . . .
42.12KeyedObjects2D . . . . . . .
42.13KeyedValue . . . . . . . . . .
42.14KeyedValueComparator . . .
42.15KeyedValueComparatorType
42.16KeyedValues . . . . . . . . .
42.17KeyedValues2D . . . . . . . .
42.18KeyToGroupMap . . . . . . .
42.19Range . . . . . . . . . . . . .
42.20RangeInfo . . . . . . . . . . .
42.21RangeType . . . . . . . . . .
42.22UnknownKeyException . . .
42.23Value . . . . . . . . . . . . .
42.24Values . . . . . . . . . . . . .
42.25Values2D . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
588
588
588
589
590
591
592
594
596
596
597
597
599
601
601
601
602
602
603
604
606
606
607
607
607
608
CONTENTS
12
43 Package: org.jfree.data.category
43.1 Introduction . . . . . . . . . . .
43.2 CategoryDataset . . . . . . . .
43.3 CategoryToPieDataset . . . . .
43.4 DefaultCategoryDataset . . . .
43.5 DefaultIntervalCategoryDataset
43.6 IntervalCategoryDataset . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
609
609
609
609
611
613
616
44 Package: org.jfree.data.contour
44.1 Introduction . . . . . . . . . . .
44.2 ContourDataset . . . . . . . . .
44.3 DefaultContourDataset . . . .
44.4 NonGridContourDataset . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
617
617
617
618
618
45 Package: org.jfree.data.function
45.1 Introduction . . . . . . . . . . .
45.2 Function2D . . . . . . . . . . .
45.3 LineFunction2D . . . . . . . . .
45.4 NormalDistributionFunction2D
45.5 PowerFunction2D . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
619
619
619
619
620
621
46 Package: org.jfree.data.gantt
46.1 Introduction . . . . . . . . .
46.2 GanttCategoryDataset . . .
46.3 Task . . . . . . . . . . . . .
46.4 TaskSeries . . . . . . . . . .
46.5 TaskSeriesCollection . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
622
622
622
623
624
625
47 Package: org.jfree.data.general
47.1 Introduction . . . . . . . . . . .
47.2 AbstractDataset . . . . . . . .
47.3 AbstractSeriesDataset . . . . .
47.4 CombinationDataset . . . . . .
47.5 CombinedDataset . . . . . . . .
47.6 Dataset . . . . . . . . . . . . .
47.7 DatasetChangeEvent . . . . . .
47.8 DatasetChangeListener . . . . .
47.9 DatasetGroup . . . . . . . . . .
47.10DatasetUtilities . . . . . . . . .
47.11DefaultKeyedValueDataset . .
47.12DefaultKeyedValuesDataset . .
47.13DefaultKeyedValues2DDataset
47.14DefaultPieDataset . . . . . . .
47.15DefaultValueDataset . . . . . .
47.16KeyedValueDataset . . . . . . .
47.17KeyedValuesDataset . . . . . .
47.18KeyedValues2DDataset . . . .
47.19PieDataset . . . . . . . . . . .
47.20Series . . . . . . . . . . . . . .
47.21SeriesChangeEvent . . . . . . .
47.22SeriesChangeListener . . . . . .
47.23SeriesDataset . . . . . . . . . .
47.24SeriesException . . . . . . . . .
47.25SubSeriesDataset . . . . . . . .
47.26ValueDataset . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
628
628
628
629
630
630
630
631
631
631
632
636
636
636
636
638
638
639
639
639
640
642
642
642
643
643
643
.
.
.
.
.
CONTENTS
13
47.27WaferMapDataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
48 Package: org.jfree.data.io
645
48.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
48.2 CSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
49 Package: org.jfree.data.jdbc
49.1 Introduction . . . . . . . . .
49.2 JDBCCategoryDataset . . .
49.3 JDBCPieDataset . . . . . .
49.4 JDBCXYDataset . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
646
646
646
647
647
50 Package: org.jfree.data.statistics
50.1 Introduction . . . . . . . . . . . . . . . .
50.2 BoxAndWhiskerCalculator . . . . . . . .
50.3 BoxAndWhiskerCategoryDataset . . . .
50.4 BoxAndWhiskerItem . . . . . . . . . . .
50.5 BoxAndWhiskerXYDataset . . . . . . .
50.6 DefaultBoxAndWhiskerCategoryDataset
50.7 DefaultBoxAndWhiskerXYDataset . . .
50.8 DefaultMultiValueCategoryDataset . . .
50.9 DefaultStatisticalCategoryDataset . . .
50.10HistogramBin . . . . . . . . . . . . . . .
50.11HistogramDataset . . . . . . . . . . . .
50.12HistogramType . . . . . . . . . . . . . .
50.13MeanAndStandardDeviation . . . . . . .
50.14MultiValueCategoryDataset . . . . . . .
50.15Regression . . . . . . . . . . . . . . . . .
50.16SimpleHistogramBin . . . . . . . . . . .
50.17SimpleHistogramDataset . . . . . . . . .
50.18StatisticalCategoryDataset . . . . . . . .
50.19Statistics . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
649
649
649
650
651
652
653
656
658
660
662
663
665
666
666
667
668
669
671
671
51 Package: org.jfree.data.time
51.1 Introduction . . . . . . . . . .
51.2 DateRange . . . . . . . . . .
51.3 Day . . . . . . . . . . . . . .
51.4 DynamicTimeSeriesCollection
51.5 FixedMillisecond . . . . . . .
51.6 Hour . . . . . . . . . . . . . .
51.7 Millisecond . . . . . . . . . .
51.8 Minute . . . . . . . . . . . . .
51.9 Month . . . . . . . . . . . . .
51.10MovingAverage . . . . . . . .
51.11Quarter . . . . . . . . . . . .
51.12RegularTimePeriod . . . . . .
51.13Second . . . . . . . . . . . . .
51.14SimpleTimePeriod . . . . . .
51.15TimePeriod . . . . . . . . . .
51.16TimePeriodAnchor . . . . . .
51.17TimePeriodFormatException
51.18TimePeriodValue . . . . . . .
51.19TimePeriodValues . . . . . .
51.20TimePeriodValuesCollection .
51.21TimeSeries . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
674
674
674
674
676
678
678
679
680
681
682
683
684
686
687
687
688
688
688
689
691
693
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CONTENTS
51.22TimeSeriesCollection .
51.23TimeSeriesDataItem .
51.24TimeSeriesTableModel
51.25TimeTableXYDataset
51.26Week . . . . . . . . . .
51.27Year . . . . . . . . . .
14
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
698
701
702
702
704
705
52 Package: org.jfree.data.time.ohlc
52.1 Introduction . . . . . . . . . . . .
52.2 OHLC . . . . . . . . . . . . . . .
52.3 OHLCItem . . . . . . . . . . . .
52.4 OHLCSeries . . . . . . . . . . . .
52.5 OHLCSeriesCollection . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
707
707
707
708
709
709
53 Package: org.jfree.data.xml
53.1 Introduction . . . . . . . .
53.2 Usage . . . . . . . . . . .
53.3 CategoryDatasetHandler .
53.4 CategorySeriesHandler . .
53.5 DatasetReader . . . . . .
53.6 DatasetTags . . . . . . . .
53.7 ItemHandler . . . . . . . .
53.8 KeyHandler . . . . . . . .
53.9 PieDatasetHandler . . . .
53.10RootHandler . . . . . . .
53.11ValueHandler . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
712
712
712
712
713
713
713
714
714
714
715
715
54 Package: org.jfree.data.xy
54.1 Introduction . . . . . . . . .
54.2 AbstractIntervalXYDataset
54.3 AbstractXYDataset . . . .
54.4 AbstractXYZDataset . . . .
54.5 CategoryTableXYDataset .
54.6 DefaultHighLowDataset . .
54.7 DefaultIntervalXYDataset .
54.8 DefaultOHLCDataset . . .
54.9 DefaultTableXYDataset . .
54.10DefaultWindDataset . . . .
54.11DefaultXYDataset . . . . .
54.12DefaultXYZDataset . . . .
54.13IntervalXYDataset . . . . .
54.14IntervalXYDelegate . . . . .
54.15IntervalXYZDataset . . . .
54.16MatrixSeries . . . . . . . . .
54.17MatrixSeriesCollection . . .
54.18NormalizedMatrixSeries . .
54.19OHLCDataItem . . . . . . .
54.20OHLCDataset . . . . . . . .
54.21TableXYDataset . . . . . .
54.22Vector . . . . . . . . . . . .
54.23VectorDataItem . . . . . . .
54.24VectorSeries . . . . . . . . .
54.25VectorSeriesCollection . . .
54.26VectorXYDataset . . . . . .
54.27WindDataset . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
716
716
716
716
717
717
719
720
723
724
726
728
730
732
733
734
734
735
736
737
738
739
739
740
741
742
744
744
CONTENTS
15
54.28XisSymbolic . . . . . . . . .
54.29XYBarDataset . . . . . . .
54.30XYCoordinate . . . . . . .
54.31XYDataItem . . . . . . . .
54.32XYDataset . . . . . . . . .
54.33XYDatasetTableModel . . .
54.34XYInterval . . . . . . . . .
54.35XYIntervalDataItem . . . .
54.36XYIntervalSeries . . . . . .
54.37XYIntervalSeriesCollection
54.38XYSeries . . . . . . . . . .
54.39XYSeriesCollection . . . . .
54.40XYZDataset . . . . . . . . .
54.41YInterval . . . . . . . . . .
54.42YIntervalDataItem . . . . .
54.43YIntervalSeries . . . . . . .
54.44YIntervalSeriesCollection .
54.45YisSymbolic . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
745
745
747
748
748
750
751
752
753
754
756
759
761
761
762
763
764
765
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
767
767
767
768
768
769
770
771
772
773
773
774
B JCommon
B.1 Introduction . . . . . . . . . . . . .
B.2 Align . . . . . . . . . . . . . . . . .
B.3 GradientPaintTransformer . . . . .
B.4 GradientPaintTransformType . . .
B.5 PublicCloneable . . . . . . . . . . .
B.6 RectangleAnchor . . . . . . . . . .
B.7 RectangleEdge . . . . . . . . . . .
B.8 RectangleInsets . . . . . . . . . . .
B.9 StandardGradientPaintTransformer
B.10 TextAnchor . . . . . . . . . . . . .
B.11 UnitType . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
775
775
775
776
776
776
777
777
777
779
781
781
A Migration
A.1 Introduction .
A.2 1.0.8 to 1.0.9
A.3 1.0.7 to 1.0.8
A.4 1.0.6 to 1.0.7
A.5 1.0.5 to 1.0.6
A.6 1.0.4 to 1.0.5
A.7 1.0.3 to 1.0.4
A.8 1.0.2 to 1.0.3
A.9 1.0.1 to 1.0.2
A.10 1.0.0 to 1.0.1
A.11 0.9.x to 1.0.0
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
C Configuring IDEs for JFreeChart
783
C.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783
C.2 Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783
C.3 NetBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
D The
D.1
D.2
D.3
GNU Lesser General Public Licence
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Licence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Frequently Asked Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
790
790
790
796
Chapter 1
Introduction
1.1
1.1.1
What is JFreeChart?
Overview
JFreeChart is a free chart library for the Java(tm) platform. It is designed for use in applications,
applets, servlets and JSP. JFreeChart is distributed with complete source code subject to the terms
of the GNU Lesser General Public Licence, which permits JFreeChart to be used in proprietary or
free software applications (see Appendix D for details).
Dual Axis Chart
80
8.0
75
7.5
70
7.0
65
6.5
60
6.0
55
5.5
Value
45
4.5
4.0
40
3.5
35
3.0
30
2.5
25
2.0
20
1.5
15
1.0
10
0.5
5
0.0
0
Secondary
50
5.0
C
C
C
C
C
C
C
C
at
at
at
at
at
at
at
at
eg
eg
eg
eg
eg
eg
eg
eg
or
or
or
y
y
y
y
y
or
or
y
y
or
y
or
or
8
7
6
5
4
3
2
1
Category
S1
S2
S3
S4
Figure 1.1: A sample chart
Figure 1.1 shows a typical chart created using JFreeChart. Many more examples are shown in later
sections of this document.
1.1.2
Features
JFreeChart can generate pie charts, bar charts (regular and stacked, with an optional 3D-effect),
line charts, scatter plots, time series charts (including moving averages, high-low-open-close charts
and candlestick plots), Gantt charts, meter charts (dial, compass and thermometer), symbol charts,
wind plots, combination charts and more.
Additional features include:
16
CHAPTER 1. INTRODUCTION
17
• data is accessible from any implementation of the defined interfaces;
• export to PNG and JPEG image file formats (or you can use Java’s ImageIO library to export
to any format supported by ImageIO);
• export to any format with a Graphics2D implementation including:
– PDF via iText (http://www.lowagie.com/iText/);
– SVG via Batik (http://xml.apache.org/batik/);
• tool tips;
• interactive zooming;
• chart mouse events (these can be used for drill-down charts or information pop-ups);
• annotations;
• HTML image map generation;
• works in applications, servlets, JSP (thanks to the Cewolf project1 ) and applets;
• distributed with complete source code subject to the terms of the GNU Lesser General Public
License (LGPL);
JFreeChart is written entirely in Java, and should run on any implementation of the Java 2 platform
(JDK 1.3.1 or later). It will also work quite well with free runtimes based on GNU Classpath 0.92
or later.2
1.1.3
Home Page
The JFreeChart home page can be found at:
http://www.jfree.org/jfreechart/
Here you will find all the latest information about JFreeChart, including sample charts, download
links, Javadocs, a discussion forum and more.
1 See
2 See
http://cewolf.sourceforge.net for details.
http://www.gnu.org/software/classpath/ for details.
CHAPTER 1. INTRODUCTION
1.2
18
This Document
1.2.1
Versions
Two versions of this document are available:
• a free version, the “JFreeChart Installation Guide”, is available from the JFreeChart home
page, and contains chapters up to and including the instructions for installing JFreeChart and
running the demo;
• a premium version, the “JFreeChart Developer Guide”, is available only to those that have
paid for it, and includes additional tutorial chapters and reference documentation for the
JFreeChart classes.
If you wish to purchase the latter version, please visit the following site:
http://www.object-refinery.com/jfreechart/guide.html
We’d like to thank everyone that has supported JFreeChart in the past by purchasing the JFreeChart
Developer Guide!
1.2.2
Disclaimer
Please note that I have put in considerable effort to ensure that the information in this document
is up-to-date and accurate, but I cannot guarantee that it does not contain errors. You must use
this document at your own risk or not use it at all.
1.3
Acknowledgements
JFreeChart contains code and ideas from many people. At the risk of missing someone out, I would
like to thank the following people for contributing to the project:
Eric Alexander, Richard Atkinson, David Basten, David Berry, Chris Boek, Zoheb
Borbora, Anthony Boulestreau, Jeremy Bowman, Daniel Bridenbecker, Nicolas Brodu,
Jody Brownell, David Browning, Søren Caspersen, Chuanhao Chiu, Brian Cole, Pascal Collet, Martin Cordova, Paolo Cova, Michael Duffy, Don Elliott, Rune Fausk,
Jonathan Gabbai, Serge V. Grachov, Daniel Gredler, Hans-Jurgen Greiner, Joao Guilherme Del Valle, Nick Guenther, Aiman Han, Cameron Hayne, Jon Iles, Wolfgang Irler,
Sergei Ivanov, Adrian Joubert, Darren Jung, Xun Kang, Bill Kelemen, Norbert Kiesel,
Gideon Krause, Pierre-Marie Le Biot, Arnaud Lelievre, Wolfgang Lenhard, David Li,
Yan Liu, Tin Luu, Craig MacFarlane, Achilleus Mantzios, Thomas Meier, Aaron Metzger, Jim Moore, Jonathan Nash, Barak Naveh, David M. O’Donnell, Krzysztof Paz,
Tomer Peretz, Xavier Poinsard, Andrzej Porebski, Luke Quinane, Viktor Rajewski, Eduardo Ramalho, Michael Rauch, Cameron Riley, Klaus Rheinwald, Dan Rivett, Scott
Sams, Michel Santos, Thierry Saura, Andreas Schneider, Jean-Luc Schwab, Bryan Scott,
Tobias Self, Mofeed Shahin, Pady Srinivasan, Greg Steckman, Roger Studner, Gerald
Struck, Irv Thomae, Eric Thomas, Rich Unger, Daniel van Enckevort, Laurence Vanhelsuwé, Sylvain Vieujot, Jelai Wang, Mark Watson, Alex Weber, Richard West, Matthew
Wright, Benoit Xhenseval, Christian W. Zuckschwerdt, Hari and Sam (oldman).
1.4
Comments and Suggestions
If you have any comments or suggestions regarding this document, please send e-mail to:
david.gilbert@object-refinery.com
Chapter 2
Sample Charts
2.1
Introduction
This section shows some sample charts created using JFreeChart. It is intended to give a reasonable
overview of the types of charts that JFreeChart can generate. For other examples, please run the
demo application included in the JFreeChart distribution:
java -jar jfreechart-1.0.9-demo.jar
The complete source code for the demo application is available to purchasers of the JFreeChart
Developer Guide.1
2.2
Pie Charts
JFreeChart can create pie charts using any data that conforms to the PieDataset interface. Figure
2.1 shows a simple pie chart.
Pie Chart Demo 1
Six
One
Five
Four
Two
Three
One
Two
Three
Four
Five
Six
Figure 2.1: A simple pie chart (see PieChartDemo1.java)
1 See
http://www.object-refinery.com/jfreechart/guide.html for details.
19
CHAPTER 2. SAMPLE CHARTS
20
Individual pie sections can be “exploded”, as shown in figure 2.2.
Pie Chart Demo 2
Six (15% percent)
One (34% percent)
Five (9% percent)
Four (14% percent)
Two (8% percent)
Three (21% percent)
One
Two
Three
Four
Five
Six
Figure 2.2: A pie chart with an “exploded” section (see PieChartDemo2.java)
You can also display pie charts with a 3D effect, as shown in figure 2.3.
Pie Chart 3D Demo 1
C/C++
Visual Basic
PHP
Java
Perl
Java
Visual Basic
C/C++
PHP
Perl
Figure 2.3: A pie chart drawn with a 3D effect (see PieChart3DDemo1.java)
At the current time it is not possible to explode sections of the 3D pie chart.
CHAPTER 2. SAMPLE CHARTS
2.3
21
Bar Charts
A range of bar charts can be created with JFreeChart, using any data that conforms to the
CategoryDataset interface. Figure 2.4 shows a bar chart with a vertical orientation.
Bar Chart Demo 1
8
7
6
Value
5
4
3
2
1
0
Ca
teg
ory
1
Ca
teg
ory
2
Ca
teg
ory
3
Ca
teg
ory
4
Ca
teg
ory
5
Category
First
Second
Third
Figure 2.4: A vertical bar chart (see BarChartDemo1.java)
Bar charts can be displayed with a 3D effect as shown in figure 2.5.
3D Bar Chart Demo
17.5
15.0
12.5
10.0
Value
7.5
5.0
2.5
0.0
-2.5
-5.0
-7.5
-10.0
-12.5
Ca
teg
ory
1
Ca
teg
ory
2
Ca
teg
ory
3
Ca
teg
ory
4
Category
Series 1
Series 2
Series 3
Series 4
Series 5
Series 6
Series 7
Series 8
Series 9
Figure 2.5: A bar chart with 3D effect (see BarChart3DDemo1.java)
CHAPTER 2. SAMPLE CHARTS
22
Another variation, the waterfall chart, is shown in figure 2.6.
Product Cost Breakdown
$3.51
30
$4.71
Cost Per Unit
25
$8.66
20
$32.64
15
10
$15.76
5
0
Labour
Administration
Marketing
Distribution
Total Expense
Expense Category
Figure 2.6: A waterfall chart (see WaterfallChartDemo1.java)
Bar charts can also be generated from time series data—for example, see figure 2.7:
State Executions - USA
Source: http://www.amnestyusa.org/abolish/listbyyear.do
100
90
Number of People
80
70
60
50
40
30
20
10
0
1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004
Year
Executions
Figure 2.7: An XY bar chart (see XYBarChartDemo1.java)
CHAPTER 2. SAMPLE CHARTS
2.4
23
Line Chart
The line chart can be generated using the same CategoryDataset that is used for the bar charts—
figure 2.8 shows an example.
Java Standard Class Library
Number of Classes By Release
3000
2800
2600
2400
Class Count
2200
2000
1800
1600
1400
1200
1000
800
600
400
200
0
JDK 1.0
JDK 1.1
SDK 1.2
SDK 1.3
SDK 1.4
Release
Source: Java In A Nutshell (4th Edition) by David Flanagan (O'Reilly)
Figure 2.8: A line chart (see LineChartDemo1.java)
CHAPTER 2. SAMPLE CHARTS
2.5
24
XY Plots
A third type of dataset, the XYDataset, is used to generate a range of chart types.
The standard XY plot has numerical x and y axes. By default, lines are drawn between each data
point—see figure 2.9.
Line Chart Demo 4
2.00
1.75
1.50
1.25
1.00
0.75
0.50
Y
0.25
0.00
-0.25
-0.50
-0.75
-1.00
-1.25
-1.50
-1.75
-2.00
-10
-9
-8
-7
-6
-5
-4
-3
-2
-1
0
1
2
3
4
5
6
7
8
9
X
y = cosine(x)
y = 2*sine(x)
Figure 2.9: A line chart (see LineChartDemo4.java)
Scatter plots can be drawn by drawing a shape at each data point, rather than connecting the
points with lines—an example is shown in figure 2.10.
Scatter Plot Demo 1
900
800
700
600
500
400
300
200
Y
100
0
-100
-200
-300
-400
-500
-600
-700
-800
-100
-75
-50
-25
0
25
50
75
X
Sample 0
Sample 1
Sample 2
Sample 3
Figure 2.10: A scatter plot (see ScatterPlotDemo1.java)
100
CHAPTER 2. SAMPLE CHARTS
2.6
25
Time Series Charts
JFreeChart supports time series charts, as shown in figure 2.11.
Legal & General Unit Trust Prices
185
180
175
170
165
160
Price Per Unit
155
150
145
140
135
130
125
120
115
110
105
100
Mar-2001 May-2001
Jul-2001
Sep-2001
Nov-2001
Jan-2002
Mar-2002 May-2002
Jul-2002
Date
L&G European Index Trust
L&G UK Index Trust
Figure 2.11: A time series chart (see TimeSeriesDemo1.java)
It is straightforward to add a moving average line to a time series chart—see figure 2.12 for an
example.
Time Series Demo 8
1.68
1.67
1.66
1.65
1.64
Value
1.63
1.62
1.61
1.60
1.59
1.58
1.57
1.56
Jan-2001
Mar-2001
May-2001
Jul-2001
Sep-2001
Nov-2001
Date
EUR/GBP
30 day moving average
Figure 2.12: A time series chart with a moving average (see TimeSeriesDemo8.java)
CHAPTER 2. SAMPLE CHARTS
26
Using an OHLCDataset (an extension of XYDataset) you can display high-low-open-close data, see
figure 2.13 for an example.
OHLC Demo 2
65
60
55
50
45
Value
40
35
30
25
20
15
10
5
0
7-Jan
14-Jan
21-Jan
28-Jan
4-Feb
11-Feb
18-Feb
Time
Series 1
Series 1-MAVG
Figure 2.13: A high-low-open-close chart (see HighLowChartDemo2.java)
2.7
Histograms
Histograms can be generated using an IntervalXYDataset (another extension of XYDataset), see
figure 2.14 for an example.
Histogram Demo
32.5
30.0
27.5
25.0
22.5
20.0
17.5
15.0
12.5
10.0
7.5
5.0
2.5
0.0
2.0
2.5
3.0
3.5
4.0
4.5
5.0
5.5
H1
6.0
6.5
7.0
7.5
8.0
8.5
9.0
9.5
H2
Figure 2.14: A histogram (see HistogramDemo1.java)
10.0
CHAPTER 2. SAMPLE CHARTS
2.8
27
Area Charts
You can generate an area chart for data in a CategoryDataset or an XYDataset. Figure 2.15 shows
an example.
XY Area Chart Demo
800
700
600
500
400
300
Range (Y)
200
100
0
-100
-200
-300
-400
-500
-600
Test
-700
-800
1.0
1.5
2.0
2.5
3.0
3.5
4.0
4.5
5.0
5.5
6.0
6.5
7.0
7.5
8.0
Domain (X)
Random 1
Random 2
Figure 2.15: An area chart (see XYAreaChartDemo1.java)
JFreeChart also supports the creation of stacked area charts as shown in figure 2.16.
Stacked XY Area Chart Demo 1
32.5
30.0
27.5
25.0
22.5
Y Value
20.0
17.5
15.0
12.5
10.0
7.5
5.0
2.5
0.0
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
X Value
Series 1
Series 2
Figure 2.16: A stacked area chart (see StackedXYAreaChartDemo1.java)
2.9
Difference Chart
A difference chart highlights the difference between two series (see figure 2.17).
A second example, shown in figure 2.18 shows how a date axis can be used for the range values.
CHAPTER 2. SAMPLE CHARTS
28
Difference Chart Demo 1
3.0
2.5
2.0
1.5
Value
1.0
0.5
0.0
-0.5
-1.0
-1.5
-2.0
-2.5
Aug-2006
Sep-2006
Oct-2006
Nov-2006
Dec-2006
Jan-2007
Feb-2007
Time
Random 1
Random 2
Figure 2.17: A difference chart (see DifferenceChartDemo1.java)
Daylight Hours - London, UK
Data source: http://www.sunrisesunset.com/
22:00
20:00
18:00
Time
16:00
14:00
12:00
10:00
08:00
06:00
04:00
British Summer Time
Feb-2004
Apr-2004
Jun-2004
Aug-2004
Oct-2004
Dec-2004
Time
Sunrise
Sunset
Figure 2.18: A difference chart with times on the range axis (see DifferenceChartDemo2.java)
CHAPTER 2. SAMPLE CHARTS
2.10
29
Step Chart
A step chart displays numerical data as a sequence of “steps”—an example is shown in figure 2.19.
XYStepRenderer Demo 1
9.0
8.5
8.0
7.5
7.0
6.5
6.0
Y
5.5
5.0
4.5
4.0
3.5
3.0
2.5
2.0
1.5
1.0
0.5
0.0
1.0
1.5
2.0
2.5
3.0
3.5
4.0
4.5
5.0
5.5
X
Series 1
Series 2
Figure 2.19: A step chart (see XYStepRendererDemo1.java)
Step charts are generated from data in an XYDataset.
6.0
CHAPTER 2. SAMPLE CHARTS
2.11
30
Gantt Chart
Gantt charts can be generated using data from an IntervalCategoryDataset, as shown in figure
2.20.
Gantt Chart Demo
Date
May-2001
Jul-2001
Sep-2001
Nov-2001
Write Proposal
Obtain Approval
Requirements Analysis
Design Phase
Task
Design Signoff
Alpha Implementation
Design Review
Revised Design Signoff
Beta Implementation
Testing
Final Implementation
Signoff
Scheduled
Actual
Figure 2.20: A Gantt chart (see GanttChartDemo1.java)
Another example, showing subtasks and progress indicators, is shown in figure 2.21.
Gantt Chart Demo
Date
May-2001
Jul-2001
Sep-2001
Nov-2001
Write Proposal
Obtain Approval
Requirements Analysis
Design Phase
Task
Design Signoff
Alpha Implementation
Design Review
Revised Design Signoff
Beta Implementation
Testing
Final Implementation
Signoff
Scheduled
Figure 2.21: A Gantt chart with progress indicators (see GanttChartDemo2.java)
CHAPTER 2. SAMPLE CHARTS
2.12
31
Multiple Axis Charts
JFreeChart has support for charts with multiple axes. Figure 2.22 shows a price-volume chart that
demonstrates this feature.
Eurodollar Futures Contract (MAR03)
750,000
98.50
98.25
700,000
98.00
650,000
97.75
600,000
97.50
550,000
97.25
500,000
96.75
450,000
96.50
400,000
96.25
350,000
96.00
Volume
Price
97.00
300,000
95.75
250,000
95.50
95.25
200,000
95.00
150,000
94.75
100,000
94.50
50,000
94.25
Jan-2002
Mar-2002
May-2002
Jul-2002
Sep-2002
0
Nov-2002
Date
Price
Volume
Figure 2.22: A price-volume chart (see PriceVolumeDemo1.java)
This feature is supported by the CategoryPlot and XYPlot classes. Figure 2.23 shows an example
with four range axes.
Multiple Axis Demo 1
Four datasets and four range axes.
110
1,300
Range Axis 2
1,000
950
27.5
100
11,000
25.0
95
10,000
22.5
9,000
90
8,000
85
7,000
80
6,000
75
5,000
900
70
850
65
800
60
4,000
3,000
11:00
11:30
12:00
12:30
13:00
13:30
20.0
17.5
15.0
12.5
Range Axis 4
1,050
30.0
12,000
Range Axis 3
1,100
Primary Range Axis
1,200
1,150
13,000
105
1,250
10.0
7.5
2,000
5.0
1,000
2.5
0
0.0
14:00
Time of Day
Series 1
Series 2
Series 3
Series 4
Figure 2.23: A chart with multiple axes (see MultipleAxisDemo1.java)
CHAPTER 2. SAMPLE CHARTS
2.13
32
Combined and Overlaid Charts
JFreeChart supports combined and overlaid charts. Figure 2.24 shows a line chart overlaid on top
of a bar chart.
Freshmeat Software Projects
By Programming Language
As at 5 March 2003
5000
100%
4500
90%
4000
80%
70%
SQL
Unix Shell
PHP
C#
10%
0
Ruby
20%
500
Python
30%
1000
Java
40%
1500
C++
50%
2000
Perl
60%
2500
C
3000
Percent
Projects
3500
0%
Language
Languages
Cumulative
Figure 2.24: An overlaid chart (see ParetoChartDemo1.java)
It is possible to combine several charts that share a common domain axis, as shown in figure 2.25.
Combined Domain Category Plot Demo
8
7
Value
6
5
4
3
2
1
0
Value
15
10
5
0
Type 1
Type 2
Type 3
Type 4
Type 5
Type 6
Type 7
Type 8
Category
First
Second
Third
Fourth
Figure 2.25: A chart with a combined domain (see CombinedCategoryPlotDemo1.java)
In a similar way, JFreeChart can combine several charts that share a common range axis, see figure
2.26.
CHAPTER 2. SAMPLE CHARTS
33
Combined (Range) XY Plot
18,000
17,000
16,000
15,000
14,000
13,000
12,000
Value
11,000
10,000
9,000
8,000
7,000
6,000
5,000
4,000
3,000
2,000
1,000
0
7-Mar
14-Mar
7-Mar
Date
14-Mar
Date
Series 1
Series 2
Figure 2.26: A chart with a combined range (see CombinedXYPlotDemo2.java)
2.14
Future Development
JFreeChart is free software,2 so anyone can extend it and add new features to it. Already, more than
80 developers from around the world have contributed code back to the JFreeChart project. It is
likely that many more chart types will be developed in the future as developers modify JFreeChart
to meet their requirements. Check the JFreeChart home page regularly for announcements and
other updates:
http://www.jfree.org/jfreechart/
And if you would like to contribute code to the project, please join in...
2 See
http://www.fsf.org
Chapter 3
Downloading and Installing
JFreeChart
3.1
Introduction
This section contains instructions for downloading, unpacking, and (optionally) recompiling JFreeChart. Also included are instructions for running the JFreeChart demonstration application, and
generating the Javadoc HTML files from the JFreeChart source code.
3.2
Download
You can download the latest version of JFreeChart from:
http://www.jfree.org/jfreechart/download/
There are two versions of the JFreeChart download:
File:
Description:
jfreechart-1.0.9.tar.gz
jfreechart-1.0.9.zip
JFreeChart for Linux/Unix.
JFreeChart for Windows.
The two files contain the same source code. The main difference is that all the text files in the zip
download have been recoded to have both carriage return and line-feed characters at the end of
each line.
JFreeChart uses the JCommon class library (currently version 1.0.12). The JCommon runtime jar
file is included in the JFreeChart download, but if you require the source code (recommended) then
you should also download JCommon from:
http://www.jfree.org/jcommon/
3.3
Unpacking the Files
After downloading JFreeChart, you need to unpack the files. You should move the download file to
a convenient directory—when you unpack JFreeChart, a new subdirectory (jfreechart-1.0.9) will
be created in the same location as the zip or tar.gz archive file.
3.3.1
Unpacking on Linux/Unix
To extract the files from the download on Linux/Unix, enter the following command:
34
CHAPTER 3. DOWNLOADING AND INSTALLING JFREECHART
35
tar xvzf jfreechart-1.0.9.tar.gz
This will extract all the source, run-time and documentation files for JFreeChart into a new directory
called jfreechart-1.0.9.
3.3.2
Unpacking on Windows
To extract the files from the download on Windows, you can use the jar utility. Enter the following
command:
jar -xvf jfreechart-1.0.9.zip
This will extract all the source, run-time and documentation files for JFreeChart into a new directory
called jfreechart-1.0.9.
3.3.3
The Files
The top-level directory (jfreechart-1.0.9) contains the files and directories listed in the following
table:
File/Directory:
Description:
README.txt
NEWS
ChangeLog
ant
Important information - read this first!
Project news.
A detailed log of changes made to JFreeChart.
A directory containing an Ant build.xml script. You can use
this script to rebuild JFreeChart from the source code included
in the distribution.
A directory containing several Checkstyle property files.
These define the coding conventions used in the JFreeChart
source code.
A directory containing source files for classes that are not part
of the standard JFreeChart API (yet). We would appreciate
feedback on this code. Please note that the API for these
classes is subject to change.
A directory containing the JFreeChart jar file, and other libraries used by JFreeChart.
A directory containing the source code for JFreeChart.
A directory containing the source code for the experimental
SWT code. Please note that the API for these classes is subject to change.
A directory containing the source code for the JFreeChart unit
tests.
A runnable jar file containing demo applications.
The JFreeChart licence (GNU LGPL).
checkstyle
experimental
lib
source
swt
tests
jfreechart-1.0.9-demo.jar
licence-LGPL.txt
You should spend some time familiarising yourself with the files included in the download. In
particular, you should always read the README.txt file.
3.4
Running the Demonstration Applications
A demonstration application is included in the distribution that shows a wide range of charts that
can be generated with JFreeChart . To run the demo, type the following command:
java -jar jfreechart-1.0.9-demo.jar
The source code for the demo application is not included in the JFreeChart distribution, but is
available to download separately when you purchase the JFreeChart Developer Guide.1
1 If you have purchased the guide and you want to download the demo source code, look for the file
jfreechart-1.0.9-demos.zip on the download page for the JFreeChart Developer Guide.
CHAPTER 3. DOWNLOADING AND INSTALLING JFREECHART
3.5
36
Configuring JFreeChart for use in IDEs
If, like most developers, you use an integrated development environment (IDE) such as Eclipse or
NetBeans for your Java development work, you’ll want to configure JFreeChart within that IDE.
The procedure for this is IDE-specific—refer to Appendix C for more details.
3.6
Compiling the Source
To recompile the JFreeChart classes, you can use the Ant build.xml file included in the distribution.
Change to the ant directory and type:
ant compile
This will recompile all the necessary source files and recreate the JFreeChart run-time jar file.
To run the script requires that you have Ant 1.5.1 (or later) installed on your system, to find out
more about Ant visit:
http://ant.apache.org/
It is possible to recompile JFreeChart without using Ant, but there are one or two “gotchas” that
you have to take special care to avoid:
• some JFreeChart classes (particularly resource bundles) are not referenced directly in the code,
and some compilers omit to compile them—this results in runtime errors or problems due to
missing class files;
• if you create your own JFreeChart jar file, you need to be sure to include the non-Java files
(resource bundle .properties files, gorilla.jpg, etc.).
In the end, it’s simpler to learn Ant and use the script included in the JFreeChart distribution.
3.7
Generating the Javadoc Documentation
The JFreeChart source code contains extensive Javadoc comments. You can use the javadoc tool
to generate HTML documentation files directly from the source code.
To generate the documentation, use the javadoc target in the Ant build.xml script:
ant javadoc
This will create a javadoc directory containing all the Javadoc HTML files, inside the main jfreechart-1.0.9
directory.
Chapter 4
Using JFreeChart
4.1
Overview
This section presents a simple introduction to JFreeChart, intended for new users of JFreeChart.
4.2
4.2.1
Creating Your First Chart
Overview
Creating charts with JFreeChart is a three step process. You need to:
• create a dataset containing the data to be displayed in the chart;
• create a JFreeChart object that will be responsible for drawing the chart;
• draw the chart to some output target (often, but not always, a panel on the screen);
To illustrate the process, we describe a sample application (First.java) that produces the pie chart
shown in figure 4.1.
Figure 4.1: A pie chart created using First.java
Each of the three steps outlined above is described, along with sample code, in the following sections.
4.2.2
The Data
Step one requires us to create a dataset for our chart. This can be done easily using the DefaultPieDataset
class, as follows:
37
CHAPTER 4. USING JFREECHART
38
// create a dataset...
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Category 1", 43.2);
dataset.setValue("Category 2", 27.9);
dataset.setValue("Category 3", 79.5);
Note that JFreeChart can create pie charts using data from any class that implements the PieDataset
interface. The DefaultPieDataset class (used above) provides a convenient implementation of this
interface, but you are free to develop an alternative dataset implementation if you want to.1
4.2.3
Creating a Pie Chart
Step two concerns how we will present the dataset created in the previous section. We need to
create a JFreeChart object that can draw a chart using the data from our pie dataset. We will use
the ChartFactory class, as follows:
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
dataset,
true,
// legend?
true,
// tooltips?
false
// URLs?
);
Notice how we have passed a reference to the dataset to the factory method. JFreeChart keeps a
reference to this dataset so that it can obtain data later on when it is drawing the chart.
The chart that we have created uses default settings for most attributes. There are many ways
to customise the appearance of charts created with JFreeChart, but in this example we will just
accept the defaults.
4.2.4
Displaying the Chart
The final step is to display the chart somewhere. JFreeChart is very flexible about where it draws
charts, thanks to its use of the Graphics2D class.
For now, let’s display the chart in a frame on the screen. The ChartFrame class contains the
machinery (a ChartPanel) required to display charts:
// create and display a frame...
ChartFrame frame = new ChartFrame("Test", chart);
frame.pack();
frame.setVisible(true);
And that’s all there is to it...
4.2.5
The Complete Program
Here is the complete program, so that you can see which packages you need to import and the order
of the code fragments given in the preceding sections:
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.ChartFrame;
org.jfree.chart.JFreeChart;
org.jfree.data.general.DefaultPieDataset;
public class First {
/**
* The starting point for the demo.
*
* @param args ignored.
*/
public static void main(String[] args) {
1 This is similar in concept to the way that Swing’s JTable class obtains data via the TableModel interface. In
fact, this was the inspiration for using interfaces to define the datasets for JFreeChart.
CHAPTER 4. USING JFREECHART
39
// create a dataset...
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Category 1", 43.2);
dataset.setValue("Category 2", 27.9);
dataset.setValue("Category 3", 79.5);
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
dataset,
true,
// legend?
true,
// tooltips?
false
// URLs?
);
// create and display a frame...
ChartFrame frame = new ChartFrame("First", chart);
frame.pack();
frame.setVisible(true);
}
}
Hopefully this has convinced you that it is not difficult to create and display charts with JFreeChart.
Of course, there is much more to learn...
Chapter 5
Pie Charts
5.1
Introduction
This chapter provides information about using some of the standard features of the pie charts in
JFreeChart, including:
• controlling the color and outline of pie sections;
• handling of null and zero values;
• pie section labels (customising the text, altering the space allocated);
• “exploded” sections;
• multiple pie charts.
• displaying charts with a 3D effect;
In addition to this chapter, you should refer to the PiePlot reference documentation in section
33.27.
5.2
Creating a Simple Pie Chart
A step-by-step guide to creating a simple pie chart is included in the previous chapter 4.
5.3
Section Colours
Default fill colours for the pie sections are allocated automatically1 the first time a plot is rendered. If
you don’t like the default colours, you can set them yourself using the setSectionPaint(Comparable,
Paint) method. For example:
PiePlot plot = (PiePlot) chart.getPlot();
plot.setSectionPaint("Section A", new Color(200, 255, 255));
plot.setSectionPaint("Section B", new Color(200, 200, 255));
A demo that uses custom colours (PieChartDemo2.java) is included in the JFreeChart demo collection.
In addition to the per-series section colour attributes, there is also a base or default setting—for
more information, refer to the documentation for the PiePlot class (section 33.27).
1 Inside
the lookupSectionPaint(Comparable, boolean) method of the PiePlot class.
40
CHAPTER 5. PIE CHARTS
5.4
41
Section Outlines
Section outlines are drawn, by default, as a thin grey line around each pie section. The PiePlot
class provides options to:
• switch off the outlines completely;
• change the outlines for all sections by changing the default values;
• control the outline for particular pie sections independently;
5.4.1
Outline Visibility
To switch off the section outlines completely, use the following code:
PiePlot plot = (PiePlot) chart.getPlot();
plot.setSectionOutlinesVisible(false);
At any time, you can make the outlines visible again using:
plot.setSectionOutlinesVisible(true);
Calls to this method trigger a PlotChangeEvent, which will cause the chart to be repainted immediately if it is displayed in a ChartPanel.
5.4.2
Outline Appearance
When outlines are visible, you can change the colour and style of the outline for all pie sections
(using the base settings) or individual pie sections (using the per series settings).
At the base layer, a default setting is defined—this is used when no higher level settings have been
made. You can change the base settings with these methods in the PiePlot class:
public void setBaseSectionOutlinePaint(Paint paint);
public void setBaseSectionOutlineStroke(Stroke stroke);
Sometimes, you may prefer to set the outline paint and stroke on a “per series” basis, perhaps to
highlight a particular section in the chart. For this, you can use the series layer settings, defined
via these methods:
public void setSectionOutlinePaint(Comparable key, Paint paint);
public void setSectionOutlineStroke(Comparable key, Stroke stroke);
The first argument for each method is the section key from the dataset. If you set the value for a
section to null, the base layer setting will be used instead.
5.5
Null, Zero and Negative Values
A PieDataset can contain null, zero or negative values which are awkward or impossible to display
in a pie chart. Some special handling is built into the PiePlot class for these.
If a zero value is found in the dataset, the PiePlot class, by default, will place a label at the position
where the pie section would be displayed if it had a positive value and will also add an item to the
chart’s legend. If you prefer zero values to be ignored, you can set a flag for this, as follows:
PiePlot plot = (PiePlot) chart.getPlot();
plot.setIgnoreZeroValues(true);
A similar approach is taken for null values, which represent a missing or unknown value in the
dataset. The default handling is the same as for zero values, and if you prefer null values to be
ignored, you can set a flag as follows:
PiePlot plot = (PiePlot) chart.getPlot();
plot.setIgnoreNullValues(true);
There does not seem to be a sensible way to represent negative values in a pie chart, and JFreeChart
will always ignore them.
CHAPTER 5. PIE CHARTS
5.6
42
Section and Legend Labels
The text used for the section labels, both on the chart and in the chart’s legend, is fully customisable.
Default label generators are installed automatically, but if you need to you can change these with
the following methods:
public void setLabelGenerator(PieSectionLabelGenerator generator);
public void setLegendLabelGenerator(PieSectionLabelGenerator generator);
The StandardPieSectionLabelGenerator class is typically used as the generator, and provides enough
flexibility to handle most custom labelling requirements (but if not, you are free two write your
own class that implements the PieSectionLabelGenerator interface). The generator works by using
Java’s MessageFormat class to construct labels by substituting values that are derived from the
dataset—see table 5.1 for the available substitutions.
Key:
Value:
{0}
{1}
{2}
The section key as a String.
The section value.
The section value as a percentage of the total of all values in the dataset.
Figure 5.1: StandardPieSectionLabelGenerator substitutions
By way of example, suppose you have a PieDataset containing the following values:
Section Key:
Section Value:
S1
S2
S3
S4
3.0
5.0
null
2.0
Figure 5.2: A sample dataset
...then the following format strings would generate the labels shown:
Format String:
Section:
Generated Label:
{0}
{0} has value {1}
{0} ({2} percent)
{0} = {1}
0
1
0
2
S1
S2 has value 5.0
S1 (30 percent)
S3 = null
Figure 5.3: Format string examples
The PieChartDemo2.java application (included in the JFreeChart demo collection) shows a custom
label generator in use.
5.7
Exploded Sections
The PiePlot class supports the display of “exploded” sections, in which a pie section is offset from
the centre of the chart to highlight it. For example, the PieChartDemo2.java application creates the
chart shown in figure 5.6.
The amount by which a section is offset from the chart is specified as a percentage of the radius of
the pie chart, for example 0.30 (30 percent) is used in the example.
PiePlot plot = (PiePlot) chart.getPlot();
plot.setExplodePercent("Section A", 0.30);
To make space for the sections that are offset from the centre of the pie chart, the radius of the
main pie is reduced, so a pie chart with exploded sections will appear smaller than a pie chart with
no exploded sections.
CHAPTER 5. PIE CHARTS
43
Figure 5.4: A pie chart with an “exploded” section
5.8
3D Pie Charts
JFreeChart includes a PiePlot3D class that adds a pseudo-3D effect to pie charts—for example, see
figure 5.5. PiePlot3D is a subclass of PiePlot, so you can just substitute it when you create your
pie chart. Or if you construct your pie charts using the ChartFactory class, it is sufficient to call
the createPieChart3D() method instead of the createPieChart() method.
Figure 5.5: A 3D pie chart
There are some limitations with this class:
• exploded sections are not supported;
• it is not possible to set the angle of “rotation” for the 3D effect—if the plot is wider than it
is tall, the chart usually looks good, but if the plot is taller than it is wide, the 3D effect is a
little distorted.
Some demo applications (PieChart3DDemo1-3.java) are included in the JFreeChart demo collection.
5.9
Multiple Pie Charts
As a convenience, the MultiplePiePlot class enables you to create a single chart that displays
multiple pie plots using data from a CategoryDataset. An example is shown in figure 5.6.
The individual pie charts are created by “rubber stamping” a single pie chart multiple times. For
each rendering of the pie chart, a new PieDataset is extracted from the next row (or column) of the
CategoryDataset.
CHAPTER 5. PIE CHARTS
44
Figure 5.6: A chart using MultiplePiePlot
A number of demos (MultiplePieChartDemo1-4.java) are included in the JFreeChart demo collection.
Chapter 6
Bar Charts
6.1
Introduction
This chapter provides an introduction to creating bar charts with JFreeChart. We begin with a
very simple bar chart, then go on to describe some of the many options that JFreeChart provides
for customising the charts. After covering the standard bar chart and its options, we’ll move on to
some more complex bar chart variants:
• stacked bar charts;
• bar charts for time series data;
• histograms.
By the end of this chapter, you should have a good overview of the features that JFreeChart supports
for bar chart creation.
6.2
6.2.1
A Bar Chart
Overview
Bar charts are used to provide a visual representation of tabular data. For example, consider the
following table, which contains a simple set of data in two rows and three columns:
Row 1:
Row 2:
Column 1:
Column 2:
Column 3:
1.0
2.0
5.0
3.0
3.0
2.0
Figure 6.1: Sample data
In JFreeChart, this table is referred to as a dataset, each column heading is a category, and each
row in the table is a series. Each row heading is a series name (or series key). A bar chart that
presents this data is shown in figure 6.2.
You can see in the sample chart that JFreeChart groups the items from each column (category)
together, and uses colours to highlight the data from each row (series). The chart’s legend provides
the link between the bar colours and the series name/key.
6.2.2
Creating a Dataset
The first step in creating a bar chart is to create an appropriate dataset. The set of methods that
JFreeChart uses to access the tabular data for a bar chart is defined by the CategoryDataset interface.
45
CHAPTER 6. BAR CHARTS
46
Figure 6.2: A bar chart (see BarExample1.java)
This interface defines a read-only interface to the dataset, because that is all that JFreeChart
requires to draw charts. A dataset can, but is not required to, provide methods to update the
dataset.
A convenient class that implements this interface is the DefaultCategoryDataset class. Here is how
you might create a dataset for the values given in table 6.1:
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, "Row 1", "Column 1");
dataset.addValue(5.0, "Row 1", "Column 2");
dataset.addValue(3.0, "Row 1", "Column 3");
dataset.addValue(2.0, "Row 2", "Column 1");
dataset.addValue(3.0, "Row 2", "Column 2");
dataset.addValue(2.0, "Row 2", "Column 3");
6.2.3
Creating a Bar Chart
The next step is to create a JFreeChart instance that draws a bar chart for this example dataset.
Taking a short-cut, we use the ChartFactory class to create the JFreeChart instance:
JFreeChart chart = ChartFactory.createBarChart(
"Bar Chart Demo", // chart title
"Category", // domain axis label
"Value", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
true, // include legend
true, // tooltips?
false // URLs?
);
Most of the arguments to the createBarChart() method are obvious, but a few of them demand
further explanation:
• the plot orientation can be either horizontal or vertical (for bar charts, this corresponds to
the way the bars are drawn, horizontally or vertically);
• the tooltips flag controls whether or not a tool tip generator is added to the chart—in this
example, we’ve set this flag to true so that we’ll see tool tips when we display the chart in a
Swing application;
CHAPTER 6. BAR CHARTS
47
• the URLs flag is only relevant when creating drill-down reports using HTML image maps, so
we set it to cffalse here.
After we’ve completed this first bar chart example, we’ll come back and take a closer look at what
the ChartFactory class is doing “behind the scenes” here.
6.2.4
Displaying the Chart
To complete our first bar chart example, we pass the JFreeChart instance to a ChartPanel and
display it in a simple Swing application. The full source code for this example is listed here:
/* ---------------* BarExample1.java
* ---------------* (C) Copyright 2006, by Object Refinery Limited.
*
*/
package tutorial;
import java.awt.Dimension;
/**
* A simple demonstration application showing how to create a bar chart.
*/
public class BarExample1 extends ApplicationFrame {
/**
* Creates a new demo instance.
*
* @param title the frame title.
*/
public BarExample1(String title) {
super(title);
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, "Row 1", "Column 1");
dataset.addValue(5.0, "Row 1", "Column 2");
dataset.addValue(3.0, "Row 1", "Column 3");
dataset.addValue(2.0, "Row 2", "Column 1");
dataset.addValue(3.0, "Row 2", "Column 2");
dataset.addValue(2.0, "Row 2", "Column 3");
JFreeChart chart = ChartFactory.createBarChart(
"Bar Chart Demo",
// chart title
"Category",
// domain axis label
"Value",
// range axis label
dataset,
// data
PlotOrientation.VERTICAL, // orientation
true,
// include legend
true,
// tooltips?
false
// URLs?
);
ChartPanel chartPanel = new ChartPanel(chart, false);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
BarExample1 demo = new BarExample1("Bar Demo 1");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
CHAPTER 6. BAR CHARTS
48
}
If you compile and run this example, you should see a frame containing the chart in figure 6.2.
6.3
The ChartFactory Class
In our first example, the ChartFactory class is used to piece together a JFreeChart instance that
renders a bar chart. Here we take a closer look at how this is done, so we can see a little more of the
underlying structure of our bar chart. Understanding this structure is key to being able customise
the appearance of the chart.
Here are the important parts of the code from the createBarChart() method in the ChartFactory
class:
1
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
2
3
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
BarRenderer renderer = new BarRenderer();
[snip...]
4
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
renderer);
5
plot.setOrientation(orientation);
6
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT TITLE FONT,
plot, legend);
Here’s what this code is doing:
• Our bar chart has two axes, one that displays categories from the dataset (a CategoryAxis),
and another that provides the numerical scale against which the data values are plotted (a
NumberAxis). You can see these axes being constructed in lines 1 and 2 above, using the axis
labels that we passed to the createBarChart() method.
• At line 3, a BarRenderer is created—this is the class that is used to draw the bar for each
data item. The renderer handles most of the drawing work, and you’ll see later that you can
substitute another type of renderer to change the overall appearance of the chart.
• The dataset, axes and renderer are all managed by a CategoryPlot, which coordinates most
of the interaction between these components. When you customise charts, you’ll often need
to get a reference to the chart’s plot, which in turn can give you access to the axes, renderer
and dataset. At line 4, the plot is created, and the other components are assigned to it.
• Finally, the plot is wrapped in a JFreeChart instance, with the specified title. The JFreeChart
class provides the top-level access to a chart, but most of the “guts” of a chart is defined
at the plot level (or in the objects managed by the plot, such as the axes, dataset(s) and
renderer(s)).
Armed with this knowledge of the internal structure of our chart, in the following sections, we’ll
slowly customise our bar chart.
6.4
Simple Chart Customisation
Some simple modifications to the appearance of a bar chart can be made by calling methods in the
JFreeChart and CategoryPlot classes. For example, to change the background colours for the chart
and plot:
CHAPTER 6. BAR CHARTS
49
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);
This code fragment (from BarExample2.java) changes the background colour for the chart, then
obtains a reference to the chart’s plot and modifies it as well—see figure 6.3.
Figure 6.3: A bar chart (see BarExample2.java)
A cast of the plot reference (to CategoryPlot) is required—it is safe to make this cast, because we
know that a CategoryPlot is used for this chart type. JFreeChart uses other plot types (PiePlot,
XYPlot, and so on) for different kinds of charts. You almost always need to cast the plot reference to
one of these types, because the base class (Plot) only defines a few common attributes and methods.
As you become more familiar with JFreeChart, you’ll learn which Plot subclass is used for each
type of chart.
In our example, we also use the plot reference to change the colour of the grid lines for the range
axis. Take a look through the API documentation for the CategoryPlot class, to see what else you
could modify here.
6.5
Customising the Renderer
Recall from section 6.3 that the CategoryPlot manages a renderer which, in the case of a regular
bar chart, is an instance of BarRenderer. If we obtain a reference to this renderer, a large number
of customisation options become available.
6.5.1
Bar Colours
To change the colours used for each series in the chart:
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setSeriesPaint(0, Color.gray);
renderer.setSeriesPaint(1, Color.orange);
renderer.setDrawBarOutline(false);
This results in the chart shown in figure 6.4. Note that the setSeriesPaint() method is defined in
the AbstractRenderer base class—you can use this for all types of renderer.
CHAPTER 6. BAR CHARTS
50
Figure 6.4: A bar chart (see BarExample3.java)
6.5.2
Bar Spacing Within Categories
Among other things, the renderer controls the spacing of bars within each category.1 So we could
remove all the space between bars in the same category, as follows:
renderer.setItemMargin(0.0);
This results in the chart shown in figure 6.5. Notice how the bars have grown a little wider—this
is because JFreeChart is now allocating less of the overall space to provide gaps between the bars,
so the bars themselves resize a little bigger.
Figure 6.5: A bar chart (see BarExample4.java)
1 The
spacing between categories is controlled by the CategoryAxis. That will be covered later.
Chapter 7
Line Charts
7.1
Introduction
This section describes the line charts that can be created with JFreeChart. It is possible to create
line charts using data from either the CategoryDataset interface or the XYDataset interface.
7.2
A Line Chart Based On A Category Dataset
7.2.1
Overview
A line chart based on a CategoryDataset simply connects each (category, value) data item using
straight lines. This section presents a sample application that generates the following chart shown
in figure 7.1.
Figure 7.1: A sample line chart
The full source code for this demo (LineChartDemo1.java) is available for download with the JFreeChart
Developer Guide.
7.2.2
The Dataset
The first step in generating the chart is, as always, to create a dataset. In the example, the
DefaultCategoryDataset class is used:
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(212, "Classes", "JDK 1.0");
dataset.addValue(504, "Classes", "JDK 1.1");
dataset.addValue(1520, "Classes", "SDK 1.2");
51
CHAPTER 7. LINE CHARTS
52
dataset.addValue(1842, "Classes", "SDK 1.3");
dataset.addValue(2991, "Classes", "SDK 1.4");
Note that you can use any implementation of the CategoryDataset interface as your dataset.
7.2.3
Constructing the Chart
The createLineChart() method in the ChartFactory class provides a convenient way to create the
chart. Here is the code:
// create the chart...
JFreeChart chart = ChartFactory.createLineChart(
"Java Standard Class Library", // chart title
"Release", // domain axis label
"Class Count", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips
false // urls
);
This method constructs a JFreeChart object with a title, no legend, and plot with appropriate axes,
renderer and tooltip generator. The dataset is the one created in the previous section.
7.2.4
Customising the Chart
The chart will be initialised using default settings for most attributes. You are, of course, free to
modify any of the settings to change the appearance of your chart. In this example, we customise
the chart in the following ways:
• two subtitles are added to the chart;
• the chart background color is set to white;
• the plot background color is set to light gray;
• the gridline color is changed to white;
• the range axis is modified to display integer values only;
• the renderer is modified to fill shapes with white.
The first subtitle is added at the default position (below the main title):
chart.addSubtitle(new TextTitle("Number of Classes By Release"));
The next subtitle takes a little extra code, to change the font, place it at the bottom of the chart,
and align it to the right side:
TextTitle source = new TextTitle(
"Source: Java In A Nutshell (4th Edition) "
+ "by David Flanagan (O’Reilly)"
);
source.setFont(new Font("SansSerif", Font.PLAIN, 10));
source.setPosition(RectangleEdge.BOTTOM);
source.setHorizontalAlignment(HorizontalAlignment.RIGHT);
chart.addSubtitle(source);
Changing the chart’s background color is simple, because this is an attribute maintained by the
JFreeChart class:
chart.setBackgroundPaint(Color.white);
To change other attributes, we first need to obtain a reference to the CategoryPlot object used by
the chart:
CHAPTER 7. LINE CHARTS
53
CategoryPlot plot = (CategoryPlot) chart.getPlot();
To set the background color for the plot, and change the gridline color:
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);
The plot is responsible for drawing the data and axes on the chart. Some of this work is delegated
to a renderer, which you can access via the getRenderer() method. The renderer maintains most
of the attributes that relate to the appearance of the data items within the chart.
LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(); renderer.setShapesVisible(true);
renderer.setDrawOutlines(true); renderer.setUseFillPaint(true);
The plot also manages the chart’s axes. In the example, the range axis is modified so that it only
displays integer values for the tick labels:
// change the auto tick unit selection to integer units only...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
There are many other ways to customise the chart. Please refer to the reference section of this
document, the API documentation and the source code for details of the methods available.
7.2.5
The Complete Program
The code for the demonstration application is presented in full, complete with the import statements. The source code is available for download from the same location as the JFreeChart Developer Guide.
/* ------------------* LineChartDemo1.java
* ------------------* (C) Copyright 2002-2005, by Object Refinery Limited.
*
*/
package demo;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JPanel;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.ChartPanel;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.NumberAxis;
org.jfree.chart.plot.CategoryPlot;
org.jfree.chart.plot.PlotOrientation;
org.jfree.chart.renderer.category.LineAndShapeRenderer;
org.jfree.chart.title.TextTitle;
org.jfree.data.category.CategoryDataset;
org.jfree.data.category.DefaultCategoryDataset;
org.jfree.ui.ApplicationFrame;
org.jfree.ui.HorizontalAlignment;
org.jfree.ui.RectangleEdge;
org.jfree.ui.RefineryUtilities;
/**
* A simple demonstration application showing how to create a line chart using
* data from a {@link CategoryDataset}.
*/
public class LineChartDemo1 extends ApplicationFrame {
/**
* Creates a new demo.
*
* @param title the frame title.
*/
public LineChartDemo1(String title) {
super(title);
CHAPTER 7. LINE CHARTS
CategoryDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Creates a sample dataset.
*
* @return The dataset.
*/
private static CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(212, "Classes", "JDK 1.0");
dataset.addValue(504, "Classes", "JDK 1.1");
dataset.addValue(1520, "Classes", "SDK 1.2");
dataset.addValue(1842, "Classes", "SDK 1.3");
dataset.addValue(2991, "Classes", "SDK 1.4");
return dataset;
}
/**
* Creates a sample chart.
*
* @param dataset a dataset.
*
* @return The chart.
*/
private static JFreeChart createChart(CategoryDataset dataset) {
// create the chart...
JFreeChart chart = ChartFactory.createLineChart(
"Java Standard Class Library",
// chart title
"Release",
// domain axis label
"Class Count",
// range axis label
dataset,
// data
PlotOrientation.VERTICAL,
// orientation
false,
// include legend
true,
// tooltips
false
// urls
);
chart.addSubtitle(new TextTitle("Number of Classes By Release"));
TextTitle source = new TextTitle(
"Source: Java In A Nutshell (4th Edition) "
+ "by David Flanagan (O’Reilly)"
);
source.setFont(new Font("SansSerif", Font.PLAIN, 10));
source.setPosition(RectangleEdge.BOTTOM);
source.setHorizontalAlignment(HorizontalAlignment.RIGHT);
chart.addSubtitle(source);
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);
// customise the range axis...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
// customise the renderer...
LineAndShapeRenderer renderer
= (LineAndShapeRenderer) plot.getRenderer();
renderer.setShapesVisible(true);
renderer.setDrawOutlines(true);
renderer.setUseFillPaint(true);
renderer.setFillPaint(Color.white);
return chart;
}
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
54
CHAPTER 7. LINE CHARTS
return new ChartPanel(chart);
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
LineChartDemo1 demo = new LineChartDemo1("Line Chart Demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
55
CHAPTER 7. LINE CHARTS
7.3
56
A Line Chart Based On An XYDataset
7.3.1
Overview
A line chart based on an XYDataset connects each (x, y) point with a straight line. This section
presents a sample application that generates the chart shown in figure 7.2.
Figure 7.2: A sample line chart using an XYPlot
The complete source code (LineChartDemo2.java) is available to download with the JFreeChart
Developer Guide.
7.3.2
The Dataset
For this chart, an XYSeriesCollection is used as the dataset (you can use any implementation of
the XYDataset interface). For the purposes of the self-contained demo, we create this dataset in
code, as follows:
XYSeries series1
series1.add(1.0,
series1.add(2.0,
series1.add(3.0,
series1.add(4.0,
series1.add(5.0,
series1.add(6.0,
series1.add(7.0,
series1.add(8.0,
= new XYSeries("First");
1.0);
4.0);
3.0);
5.0);
5.0);
7.0);
7.0);
8.0);
XYSeries series2
series2.add(1.0,
series2.add(2.0,
series2.add(3.0,
series2.add(4.0,
series2.add(5.0,
series2.add(6.0,
series2.add(7.0,
series2.add(8.0,
= new XYSeries("Second");
5.0);
7.0);
6.0);
8.0);
4.0);
4.0);
2.0);
1.0);
XYSeries series3 = new XYSeries("Third");
series3.add(3.0, 4.0);
series3.add(4.0, 3.0);
series3.add(5.0, 2.0);
series3.add(6.0, 3.0);
series3.add(7.0, 6.0);
series3.add(8.0, 3.0);
series3.add(9.0, 4.0);
series3.add(10.0, 3.0);
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series1);
dataset.addSeries(series2);
dataset.addSeries(series3);
return dataset;
CHAPTER 7. LINE CHARTS
57
Notice how each series has x-values (not just y-values) that are independent from the other series.
The dataset will also accept null in place of a y-value. When a null value is encountered, no
connecting line is drawn, resulting in a discontinuous line for the series.
7.3.3
Constructing the Chart
The createXYLineChart() method in the ChartFactory class provides a convenient way to create the
chart:
JFreeChart chart = ChartFactory.createXYLineChart(
"Line Chart Demo 2",
// chart title
"X",
// x axis label
"Y",
// y axis label
dataset,
// data
PlotOrientation.VERTICAL,
true,
// include legend
true,
// tooltips
false
// urls
);
This method constructs a JFreeChart object with a title, legend and plot with appropriate axes
and renderer. The dataset is the one created in the previous section. The chart is created with a
legend, and tooltips are enabled (URLs are disabled—these are only used in the creation of HTML
image maps).
7.3.4
Customising the Chart
The chart will be initialised using default settings for most attributes. You are, of course, free
to modify any of the settings to change the appearance of your chart. In this example, several
attributes are modified:
• the chart background color;
• the plot background color;
• the axis offsets;
• the color of the domain and range gridlines;
• the renderer is modified to draw shapes as well as lines;
• the tick unit collection for the range axis, so that the tick values always display integer values;
Changing the chart’s background color is simple:
// set the background color for the chart...
chart.setBackgroundPaint(Color.white);
Changing the plot background color, the axis offsets, and the color of the gridlines, requires a
reference to the plot. The cast to XYPlot is required so that we can access methods specific to this
type of plot:
// get a reference to the plot for further customisation...
XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
The renderer is modified to display filled shapes in addition to the default lines:
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
renderer.setShapesVisible(true);
renderer.setShapesFilled(true);
CHAPTER 7. LINE CHARTS
58
The final modification is a change to the range axis. We change the default collection of tick units
(which allow fractional values) to an integer-only collection:
// change the auto tick unit selection to integer units only...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
Refer to the source code, Javadoc API documentation or elsewhere in this document for details of
the other customisations that you can make to an XYPlot.
7.3.5
The Complete Program
The code for the demonstration application is presented here in full, complete with the import
statements:
/* ------------------* LineChartDemo2.java
* ------------------* (C) Copyright 2002-2005, by Object Refinery Limited.
*
*/
package demo;
import java.awt.Color;
import javax.swing.JPanel;
import
import
import
import
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.ChartPanel;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.NumberAxis;
org.jfree.chart.plot.PlotOrientation;
org.jfree.chart.plot.XYPlot;
org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
org.jfree.data.xy.XYDataset;
org.jfree.data.xy.XYSeries;
org.jfree.data.xy.XYSeriesCollection;
org.jfree.ui.ApplicationFrame;
org.jfree.ui.RectangleInsets;
org.jfree.ui.RefineryUtilities;
/**
* A simple demonstration application showing how to create a line chart using
* data from an {@link XYDataset}.
*
* IMPORTANT NOTE: THIS DEMO IS DOCUMENTED IN THE JFREECHART DEVELOPER GUIDE.
* DO NOT MAKE CHANGES WITHOUT UPDATING THE GUIDE ALSO!!
*/
public class LineChartDemo2 extends ApplicationFrame {
/**
* Creates a new demo.
*
* @param title the frame title.
*/
public LineChartDemo2(String title) {
super(title);
XYDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Creates a sample dataset.
*
* @return a sample dataset.
*/
private static XYDataset createDataset() {
XYSeries series1 = new XYSeries("First");
series1.add(1.0, 1.0);
series1.add(2.0, 4.0);
CHAPTER 7. LINE CHARTS
series1.add(3.0,
series1.add(4.0,
series1.add(5.0,
series1.add(6.0,
series1.add(7.0,
series1.add(8.0,
3.0);
5.0);
5.0);
7.0);
7.0);
8.0);
XYSeries series2
series2.add(1.0,
series2.add(2.0,
series2.add(3.0,
series2.add(4.0,
series2.add(5.0,
series2.add(6.0,
series2.add(7.0,
series2.add(8.0,
= new XYSeries("Second");
5.0);
7.0);
6.0);
8.0);
4.0);
4.0);
2.0);
1.0);
XYSeries series3 = new XYSeries("Third");
series3.add(3.0, 4.0);
series3.add(4.0, 3.0);
series3.add(5.0, 2.0);
series3.add(6.0, 3.0);
series3.add(7.0, 6.0);
series3.add(8.0, 3.0);
series3.add(9.0, 4.0);
series3.add(10.0, 3.0);
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series1);
dataset.addSeries(series2);
dataset.addSeries(series3);
return dataset;
}
/**
* Creates a chart.
*
* @param dataset the data for the chart.
*
* @return a chart.
*/
private static JFreeChart createChart(XYDataset dataset) {
// create the chart...
JFreeChart chart = ChartFactory.createXYLineChart(
"Line Chart Demo 2",
// chart title
"X",
// x axis label
"Y",
// y axis label
dataset,
// data
PlotOrientation.VERTICAL,
true,
// include legend
true,
// tooltips
false
// urls
);
// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
chart.setBackgroundPaint(Color.white);
// get a reference to the plot for further customisation...
XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
XYLineAndShapeRenderer renderer
= (XYLineAndShapeRenderer) plot.getRenderer();
renderer.setShapesVisible(true);
renderer.setShapesFilled(true);
// change the auto tick unit selection to integer units only...
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
// OPTIONAL CUSTOMISATION COMPLETED.
return chart;
}
59
CHAPTER 7. LINE CHARTS
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
return new ChartPanel(chart);
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
LineChartDemo2 demo = new LineChartDemo2("Line Chart Demo 2");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
60
Chapter 8
Time Series Charts
8.1
Introduction
Time series charts are very similar to line charts, except that the values on the domain axis are
dates rather than numbers. This section describes how to create time series charts with JFreeChart.
8.2
8.2.1
Time Series Charts
Overview
A time series chart is really just a line chart using data obtained via the XYDataset interface (see
the example in the previous section). The difference is that the x-values are displayed as dates
on the domain axis. This section presents a sample application that generates the chart shown in
figure 8.1.
Figure 8.1: A time series chart
The complete source code (TimeSeriesDemo1.java) for this example is available for download with
the JFreeChart Developer Guide.
8.2.2
Dates or Numbers?
Time series charts are created using data from an XYDataset. This interface doesn’t have any
methods that return dates, so how does JFreeChart create time series charts?
The x-values returned by the dataset are double primitives, but the values are interpreted in a
special way—they are assumed to represent the number of milliseconds since midnight, 1 January
61
CHAPTER 8. TIME SERIES CHARTS
62
1970 (the encoding used by the java.util.Date class).
A special axis class (DateAxis) converts from milliseconds to dates and back again as necessary,
allowing the axis to display tick labels formatted as dates.
8.2.3
The Dataset
For the demo chart, a TimeSeriesCollection is used as the dataset (you can use any implementation
of the XYDataset interface):
TimeSeries
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1 = new TimeSeries("L&G European Index Trust", Month.class);
Month(2, 2001), 181.8);
Month(3, 2001), 167.3);
Month(4, 2001), 153.8);
Month(5, 2001), 167.6);
Month(6, 2001), 158.8);
Month(7, 2001), 148.3);
Month(8, 2001), 153.9);
Month(9, 2001), 142.7);
Month(10, 2001), 123.2);
Month(11, 2001), 131.8);
Month(12, 2001), 139.6);
Month(1, 2002), 142.9);
Month(2, 2002), 138.7);
Month(3, 2002), 137.3);
Month(4, 2002), 143.9);
Month(5, 2002), 139.8);
Month(6, 2002), 137.0);
Month(7, 2002), 132.8);
TimeSeries
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2 = new TimeSeries("L&G UK Index Trust", Month.class);
Month(2, 2001), 129.6);
Month(3, 2001), 123.2);
Month(4, 2001), 117.2);
Month(5, 2001), 124.1);
Month(6, 2001), 122.6);
Month(7, 2001), 119.2);
Month(8, 2001), 116.5);
Month(9, 2001), 112.7);
Month(10, 2001), 101.5);
Month(11, 2001), 106.1);
Month(12, 2001), 110.3);
Month(1, 2002), 111.7);
Month(2, 2002), 111.0);
Month(3, 2002), 109.6);
Month(4, 2002), 113.2);
Month(5, 2002), 111.6);
Month(6, 2002), 108.8);
Month(7, 2002), 101.6);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
In the example, the series contain monthly data. However, the TimeSeries class can be used to
represent values observed at other intervals (annual, daily, hourly etc).
8.2.4
Constructing the Chart
The createTimeSeriesChart() method in the ChartFactory class provides a convenient way to create
the chart:
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Legal & General Unit Trust Prices", // title
"Date",
// x-axis label
"Price Per Unit",
// y-axis label
dataset,
// data
true,
// create legend?
true,
// generate tooltips?
false
// generate URLs?
);
This method constructs a JFreeChart object with a title, legend and plot with appropriate axes and
renderer. The dataset is the one created in the previous section.
CHAPTER 8. TIME SERIES CHARTS
8.2.5
63
Customising the Chart
The chart will be initialised using default settings for most attributes. You are, of course, free
to modify any of the settings to change the appearance of your chart. In this example, several
attributes are modified:
• the renderer is changed to display series shapes at each data point, in addition to the lines
between data points;
• a date format override is set for the domain axis;
Modifying the renderer requires a couple of steps to obtain a reference to the renderer and then
cast it to a XYLineAndShapeRenderer:
XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setBaseShapesVisible(true);
renderer.setBaseShapesFilled(true);
}
In the final customisation, a date format override is set for the domain axis.
DateAxis axis = (DateAxis) plot.getDomainAxis();
axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));
When this is set, the axis will continue to “auto-select” a DateTickUnit from the collection of
standard tick units, but it will ignore the formatting from the tick unit and use the override format
instead.
8.2.6
The Complete Program
The code for the demonstration application is presented in full, complete with the import statements:
/* ------------------* TimeSeriesDemo.java
* ------------------* (C) Copyright 2002-2005, by Object Refinery Limited.
*
*/
package demo;
import java.awt.Color;
import java.text.SimpleDateFormat;
import javax.swing.JPanel;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.ChartPanel;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.DateAxis;
org.jfree.chart.plot.XYPlot;
org.jfree.chart.renderer.xy.XYItemRenderer;
org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
org.jfree.data.time.Month;
org.jfree.data.time.TimeSeries;
org.jfree.data.time.TimeSeriesCollection;
org.jfree.data.xy.XYDataset;
org.jfree.ui.ApplicationFrame;
org.jfree.ui.RectangleInsets;
org.jfree.ui.RefineryUtilities;
/**
* An example of a time series chart.
For the most part, default settings are
CHAPTER 8. TIME SERIES CHARTS
* used, except that the renderer is modified to show filled shapes (as well as
* lines) at each data point.
*
* IMPORTANT NOTE: THIS DEMO IS DOCUMENTED IN THE JFREECHART DEVELOPER GUIDE.
* DO NOT MAKE CHANGES WITHOUT UPDATING THE GUIDE ALSO!!
*/
public class TimeSeriesDemo1 extends ApplicationFrame {
/**
* A demonstration application showing how to create a simple time series
* chart. This example uses monthly data.
*
* @param title the frame title.
*/
public TimeSeriesDemo1(String title) {
super(title);
XYDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
chartPanel.setMouseZoomable(true, false);
setContentPane(chartPanel);
}
/**
* Creates a chart.
*
* @param dataset a dataset.
*
* @return A chart.
*/
private static JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Legal & General Unit Trust Prices", // title
"Date",
// x-axis label
"Price Per Unit",
// y-axis label
dataset,
// data
true,
// create legend?
true,
// generate tooltips?
false
// generate URLs?
);
chart.setBackgroundPaint(Color.white);
XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setBaseShapesVisible(true);
renderer.setBaseShapesFilled(true);
}
DateAxis axis = (DateAxis) plot.getDomainAxis();
axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));
return chart;
}
/**
64
CHAPTER 8. TIME SERIES CHARTS
* Creates a dataset, consisting of two series of monthly data.
*
* @return the dataset.
*/
private static XYDataset createDataset() {
TimeSeries
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1 = new TimeSeries("L&G European Index Trust", Month.class);
Month(2, 2001), 181.8);
Month(3, 2001), 167.3);
Month(4, 2001), 153.8);
Month(5, 2001), 167.6);
Month(6, 2001), 158.8);
Month(7, 2001), 148.3);
Month(8, 2001), 153.9);
Month(9, 2001), 142.7);
Month(10, 2001), 123.2);
Month(11, 2001), 131.8);
Month(12, 2001), 139.6);
Month(1, 2002), 142.9);
Month(2, 2002), 138.7);
Month(3, 2002), 137.3);
Month(4, 2002), 143.9);
Month(5, 2002), 139.8);
Month(6, 2002), 137.0);
Month(7, 2002), 132.8);
TimeSeries
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2 = new TimeSeries("L&G UK Index Trust", Month.class);
Month(2, 2001), 129.6);
Month(3, 2001), 123.2);
Month(4, 2001), 117.2);
Month(5, 2001), 124.1);
Month(6, 2001), 122.6);
Month(7, 2001), 119.2);
Month(8, 2001), 116.5);
Month(9, 2001), 112.7);
Month(10, 2001), 101.5);
Month(11, 2001), 106.1);
Month(12, 2001), 110.3);
Month(1, 2002), 111.7);
Month(2, 2002), 111.0);
Month(3, 2002), 109.6);
Month(4, 2002), 113.2);
Month(5, 2002), 111.6);
Month(6, 2002), 108.8);
Month(7, 2002), 101.6);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
dataset.setDomainIsPointsInTime(true);
return dataset;
}
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
return new ChartPanel(chart);
}
/**
* Starting point for the demonstration application.
65
CHAPTER 8. TIME SERIES CHARTS
*
* @param args ignored.
*/
public static void main(String[] args) {
TimeSeriesDemo1 demo = new TimeSeriesDemo1("Time Series Demo 1");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
66
Chapter 9
Customising Charts
9.1
Introduction
JFreeChart has been designed to be highly customisable. There are many attributes that you can
set to change the default appearance of your charts. In this section, some common techniques for
customising charts are presented.
9.2
Chart Attributes
9.2.1
Overview
At the highest level, you can customise the appearance of your charts using methods in the
JFreeChart class. This allows you to control:
• the chart border;
• the chart title and sub-titles;
• the background color and/or image;
• the rendering hints that are used to draw the chart, including whether or not anti-aliasing is
used;
These items are described in the following sections.
9.2.2
The Chart Border
JFreeChart can draw a border around the outside of a chart. By default, no border is drawn, but
you can change this using the setBorderVisible() method. The color and line-style for the border
are controlled by the setBorderPaint() and setBorderStroke() methods.
Note: if you are displaying your chart inside a ChartPanel, then you might prefer to use the border
facilities provided by Swing.
9.2.3
The Chart Title
A chart has one title that can appear at the top, bottom, left or right of the chart (you can also add
subtitles—see the next section). The title is an instance of TextTitle. You can obtain a reference
to the title using the getTitle() method:
TextTitle title = chart.getTitle();
To modify the title text (without changing the font or position):
67
CHAPTER 9. CUSTOMISING CHARTS
68
chart.setTitle("A Chart Title");
The placement of the title at the top, bottom, left or right of the chart is controlled by a property
of the title itself. To move the title to the bottom of the chart:
chart.getTitle().setPosition(RectangleEdge.BOTTOM);
If you prefer to have no title on your chart, you can set the title to null.
9.2.4
Subtitles
A chart can have any number of subtitles. To add a sub-title to a chart, create a subtitle (any
subclass of Title) and add it to the chart. For example:
TextTitle subtitle1 = new TextTitle("A Subtitle");
chart.addSubtitle(subtitle1);
You can add as many sub-titles as you like to a chart, but keep in mind that as you add more
sub-titles there will be less and less space available for drawing the chart.
To modify an existing sub-title, you need to get a reference to the sub-title. For example:
Title subtitle = chart.getSubtitle(0);
You will need to cast the Title reference to an appropriate subclass before you can change its
properties.
You can check the number of sub-titles using the getSubtitleCount() method.
9.2.5
Setting the Background Color
You can use the setBackgroundPaint() method to set the background color for a chart.1 For example:
chart.setBackgroundPaint(Color.blue);
You can use any implementation of the Paint interface, including the Java classes Color, GradientPaint
and TexturePaint. For example:
Paint p = new GradientPaint(0, 0, Color.white, 1000, 0, Color.green));
chart.setBackgroundPaint(p);
You can also set the background paint to null, which is recommended if you have specified a
background image for your chart.
9.2.6
Using a Background Image
You can use the setBackgroundImage() method to set a background image for a chart.
chart.setBackgroundImage(JFreeChart.INFO.getLogo());
By default, the image will be scaled to fit the area that the chart is being drawn into, but you can
change this using the setBackgroundImageAlignment() method.
chart.setBackgroundImageAlignment(Align.TOP LEFT);
Using the setBackgroundImageAlpha() method, you can control the alpha-transparency for the image.
If you want an image to fill only the data area of your chart (that is, the area inside the axes), then
you need to add a background image to the chart’s Plot (described later).
1 You
can also set the background color for the chart’s plot area, which has a slightly different effect—refer to the
Plot class for details.
CHAPTER 9. CUSTOMISING CHARTS
9.2.7
69
Rendering Hints
JFreeChart uses the Java2D API to draw charts. Within this API, you can specify rendering hints
to fine tune aspects of the way that the rendering engine works.
JFreeChart allows you to specify the rendering hints to be passed to the Java2D API when charts
are drawn—use the setRenderingHints() method.
As a convenience, a method is provided to turn anti-aliasing on or off. With anti-aliasing on, charts
appear to be smoother but they take longer to draw:
// turn on antialiasing...
chart.setAntiAlias(true);
By default, charts are drawn with anti-aliasing turned on.
9.3
Plot Attributes
9.3.1
Overview
The JFreeChart class delegates a lot of the work in drawing a chart to the Plot class (or, rather, to
a specific subclass of Plot). The getPlot() method in the JFreeChart class returns a reference to
the plot being used by the chart.
Plot plot = chart.getPlot();
You may need to cast this reference to a specific subclass of Plot, for example:
CategoryPlot plot = chart.getCategoryPlot();
...or:
XYPlot plot = chart.getXYPlot();
Note that these methods will throw a ClassCastException if the plot is not an appropriate class.
9.3.2
Which Plot Subclass?
How do you know which subclass of Plot is being used by a chart? As you gain experience with
JFreeChart, it will become clear which charts use CategoryPlot and which charts use XYPlot. If in
doubt, take a look in the ChartFactory class source code to see how each chart type is put together.
9.3.3
Setting the Background Paint
You can use the setBackgroundPaint() method to set the background color for a plot. For example:
Plot plot = chart.getPlot();
plot.setBackgroundPaint(Color.white);
You can use any implementation of the Paint interface, including the Java classes Color, GradientPaint
and TexturePaint. You can also set the background paint to null.
9.3.4
Using a Background Image
You can use the setBackgroundImage() method to set a background image for a plot:
Plot plot = chart.getPlot();
plot.setBackgroundImage(JFreeChart.INFO.getLogo());
By default, the image will be scaled to fit the area that the plot is being drawn into. You can
change this using the setBackgroundImageAlignment() method:
plot.setBackgroundImageAlignment(Align.BOTTOM RIGHT);
Use the setBackgroundAlpha() method to control the alpha-transparency used for the image.
If you prefer your image to fill the entire chart area, then you need to add a background image to
the JFreeChart object (described previously).
CHAPTER 9. CUSTOMISING CHARTS
9.4
70
Axis Attributes
9.4.1
Overview
The majority of charts created with JFreeChart have two axes, a domain axis and a range axis.
Of course, there are some charts (for example, pie charts) that don’t have axes at all. For charts
where axes are used, the Axis objects are managed by the plot.
9.4.2
Obtaining an Axis Reference
Before you can change the properties of an axis, you need to obtain a reference to the axis. The
plot classes CategoryPlot and XYPlot both have methods getDomainAxis() and getRangeAxis().
These methods return a reference to a ValueAxis, except in the case of the CategoryPlot, where the
domain axis is an instance of CategoryAxis.
// get an axis reference...
CategoryPlot plot = chart.getCategoryPlot();
CategoryAxis domainAxis = plot.getDomainAxis();
// change axis properties...
domainAxis.setLabel("Categories");
domainAxis.setLabelFont(someFont);
There are many different subclasses of the CategoryAxis and ValueAxis classes. Sometimes you will
need to cast your axis reference to a more specific subclass, in order to access some of its attributes.
For example, if you know that your range axis is a NumberAxis (and the range axis almost always
is), then you can do the following:
XYPlot plot = chart.getXYPlot();
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setAutoRange(false);
9.4.3
Setting the Axis Label
You can use the setLabel() method to change the axis label. If you would prefer not to have a
label for your axis, just set it to null.
You can change the font, color and insets (the space around the outside of the label) with the
methods setLabelFont(), setLabelPaint(), and setLabelInsets(), defined in the Axis class.
9.4.4
Rotating Axis Labels
When an axis is drawn at the left or right of a plot (a “vertical” axis), the label is automatically rotated by 90 degrees to minimise the space required. If you prefer to have the label drawn
horizontally, you can change the label angle:
XYPlot plot = chart.getXYPlot();
ValueAxis axis = plot.getRangeAxis();
axis.setLabelAngle(Math.PI / 2.0);
Note that the angle is specified in radians (Math.PI = 180 degrees).
9.4.5
Hiding Tick Labels
To hide the tick labels for an axis:
CategoryPlot plot = chart.getCategoryPlot();
ValueAxis axis = plot.getRangeAxis();
axis.setTickLabelsVisible(false);
For a CategoryAxis, setTickLabelsVisible(false) will hide the category labels.
CHAPTER 9. CUSTOMISING CHARTS
9.4.6
71
Hiding Tick Marks
To hide the tick marks for an axis:
XYPlot plot = chart.getXYPlot();
Axis axis = plot.getDomainAxis();
axis.setTickMarksVisible(false);
Category axes do not have tick marks.
9.4.7
Setting the Tick Size
By default, numerical and date axes automatically select a tick size so that the tick labels will not
overlap. You can override this by setting your own tick unit using the setTickUnit() method.
Alternatively, for a NumberAxis or a DateAxis you can specify your own set of tick units from which
the axis will automatically select an appropriate tick size. This is described in the following sections.
9.4.8
Specifying “Standard” Number Tick Units
In the NumberAxis class, there is a method setStandardTickUnits() that allows you to supply your
own set of tick units for the “auto tick unit selection” mechanism.
One common application is where you have a number axis that should only display integers. In this
case, you don’t want tick units of (say) 0.5 or 0.25. There is a (static) method in the NumberAxis
class that returns a set of standard integer tick units:
XYPlot plot = chart.getXYPlot();
NumberAxis axis = (NumberAxis) plot.getRangeAxis();
TickUnitSource units = NumberAxis.createIntegerTickUnits();
axis.setStandardTickUnits(units);
You are free to create your own TickUnits collection, if you want greater control over the standard
tick units.
9.4.9
Specifying “Standard” Date Tick Units
Similar to the case in the previous section, the DateAxis class has a method setStandardTickUnits()
that allows you to supply your own set of tick units for the “auto tick unit selection” mechanism.
The createStandardDateTickUnits() method returns the default collection for a DateAxis, but you
are free to create your own TickUnits collection if you want greater control over the standard tick
units.
Chapter 10
Dynamic Charts
10.1
Overview
To illustrate the use of JFreeChart for creating “dynamic” charts, this section presents a sample
application that displays a frequently updating chart of JVM memory usage and availability.
Figure 10.1: A dynamic chart demo
10.2
Background
10.2.1
Event notification
JFreeChart uses an event notification mechanism that allows it to respond to changes to any component of the chart. For example, whenever a dataset is updated, a DatasetChangeEvent is sent to
all listeners that are registered with the dataset. This triggers the following sequence of events:
• the plot (which registers itself with the dataset as a DatasetChangeListener) receives notification of the dataset change. It updates the axis ranges (if necessary) then passes on a
PlotChangeEvent to all its registered listeners;
• the chart receives notification of the plot change event, and passes on a ChartChangeEvent to
all its registered listeners;
• finally, for charts that are displayed in a ChartPanel, the panel will receive the chart change
event. It responds by redrawing the chart—a complete redraw, not just the updated data.
A similar sequence of events happens for all changes to a chart or its subcomponents.
72
CHAPTER 10. DYNAMIC CHARTS
10.2.2
73
Performance
Regarding performance, you need to be aware that JFreeChart wasn’t designed specifically for
generating real-time charts. Each time a dataset is updated, the ChartPanel reacts by redrawing
the entire chart. Optimisations, such as only drawing the most recently added data point, are
difficult to implement in the general case, even more so given the Graphics2D abstraction (in the
Java2D API) employed by JFreeChart. This limits the number of “frames per second” you will be
able to achieve with JFreeChart. Whether this will be an issue for you depends on your data, the
requirements of your application, and your operating environment.
10.3
The Demo Application
10.3.1
Overview
The MemoryUsageDemo.java demonstration is included in the JFreeChart demo collection (source
code available to purchasers of this guide). You can obtain this from:
http://www.object-refinery.com/jfreechart/premium/index.html
You will need to enter the username and password supplied with your original purchase of the
JFreeChart Developer Guide.
10.3.2
Creating the Dataset
The dataset is created using two TimeSeries objects (one for the total memory and the other for
the free memory) that are added to a single time series collection:
// create two series that automatically discard data > 30 seconds old...
this.total = new TimeSeries("Total", Millisecond.class);
this.total.setMaximumItemAge(30000);
this.free = new TimeSeries("Free", Millisecond.class);
this.free.setMaximumItemAge(30000);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(this.total);
dataset.addSeries(this.free);
The maximumItemAge attribute for each time series is set to 30,000 milliseconds (or 30 seconds) so
that whenever new data is added to the series, any observations that are older that 30 seconds are
automatically discarded.
10.3.3
Creating the Chart
The chart creation (and customisation) follows the standard pattern for all charts. No special steps
are required to create a dynamic chart, except that you should ensure that the axes have their
autoRange attribute set to true. It also helps to retain a reference to the dataset used in the chart.
10.3.4
Updating the Dataset
In the demo, the dataset is updated by adding data to the two time series from a separate thread,
managed by the following timer:
class DataGenerator extends Timer implements ActionListener {
DataGenerator(int interval) {
super(interval, null);
addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
long f = Runtime.getRuntime().freeMemory();
long t = Runtime.getRuntime().totalMemory();
addTotalObservation(t);
addFreeObservation(f);
CHAPTER 10. DYNAMIC CHARTS
74
}
}
Note that JFreeChart does not yet use thread synchronisation between the chart drawing code and
the dataset update code, so this approach is a little unsafe.
One other point to note, at one point while investigating reports of a memory leak in JFreeChart, I
left this demo running on a test machine for about six days. As the chart updates, you can see the
effect of the garbage collector. Over the six day period, the total memory used remained constant
while the free memory decreased as JFreeChart discarded temporary objects (garbage), and increased
at the points where the garbage collector did its work.
10.3.5
Source Code
For reference, here is the complete source code for the example:
/* -------------------* MemoryUsageDemo.java
* -------------------* (C) Copyright 2002-2006, by Object Refinery Limited.
*/
package demo;
import
import
import
import
import
import
import
import
java.awt.BasicStroke;
java.awt.BorderLayout;
java.awt.Color;
java.awt.Font;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.WindowAdapter;
java.awt.event.WindowEvent;
import
import
import
import
javax.swing.BorderFactory;
javax.swing.JFrame;
javax.swing.JPanel;
javax.swing.Timer;
import
import
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartPanel;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.DateAxis;
org.jfree.chart.axis.NumberAxis;
org.jfree.chart.plot.XYPlot;
org.jfree.chart.renderer.xy.XYItemRenderer;
org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
org.jfree.data.time.Millisecond;
org.jfree.data.time.TimeSeries;
org.jfree.data.time.TimeSeriesCollection;
org.jfree.ui.RectangleInsets;
/**
* A demo application showing a dynamically
* current JVM memory usage.
*
* IMPORTANT NOTE: THIS DEMO IS DOCUMENTED
* DO NOT MAKE CHANGES WITHOUT UPDATING THE
*/
public class MemoryUsageDemo extends JPanel
updated chart that displays the
IN THE JFREECHART DEVELOPER GUIDE.
GUIDE ALSO!!
{
/** Time series for total memory used. */
private TimeSeries total;
/** Time series for free memory. */
private TimeSeries free;
/**
* Creates a new application.
*
* @param maxAge the maximum age (in milliseconds).
*/
public MemoryUsageDemo(int maxAge) {
super(new BorderLayout());
// create two series that automatically discard data more than 30
CHAPTER 10. DYNAMIC CHARTS
// seconds old...
this.total = new TimeSeries("Total Memory", Millisecond.class);
this.total.setMaximumItemAge(maxAge);
this.free = new TimeSeries("Free Memory", Millisecond.class);
this.free.setMaximumItemAge(maxAge);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(this.total);
dataset.addSeries(this.free);
DateAxis domain = new DateAxis("Time");
NumberAxis range = new NumberAxis("Memory");
domain.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 12));
range.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 12));
domain.setLabelFont(new Font("SansSerif", Font.PLAIN, 14));
range.setLabelFont(new Font("SansSerif", Font.PLAIN, 14));
XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
renderer.setSeriesPaint(0, Color.red);
renderer.setSeriesPaint(1, Color.green);
renderer.setStroke(new BasicStroke(3f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL));
XYPlot plot = new XYPlot(dataset, domain, range, renderer);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
domain.setAutoRange(true);
domain.setLowerMargin(0.0);
domain.setUpperMargin(0.0);
domain.setTickLabelsVisible(true);
range.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
JFreeChart chart = new JFreeChart("JVM Memory Usage",
new Font("SansSerif", Font.BOLD, 24), plot, true);
chart.setBackgroundPaint(Color.white);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(4, 4, 4, 4),
BorderFactory.createLineBorder(Color.black)));
add(chartPanel);
}
/**
* Adds an observation to the ’total memory’ time series.
*
* @param y the total memory used.
*/
private void addTotalObservation(double y) {
this.total.add(new Millisecond(), y);
}
/**
* Adds an observation to the ’free memory’ time series.
*
* @param y the free memory.
*/
private void addFreeObservation(double y) {
this.free.add(new Millisecond(), y);
}
/**
* The data generator.
*/
class DataGenerator extends Timer implements ActionListener {
/**
* Constructor.
*
* @param interval the interval (in milliseconds)
*/
DataGenerator(int interval) {
super(interval, null);
addActionListener(this);
}
/**
* Adds a new free/total memory reading to the dataset.
*
* @param event the action event.
75
CHAPTER 10. DYNAMIC CHARTS
*/
public void actionPerformed(ActionEvent event) {
long f = Runtime.getRuntime().freeMemory();
long t = Runtime.getRuntime().totalMemory();
addTotalObservation(t);
addFreeObservation(f);
}
}
/**
* Entry point for the sample application.
*
* @param args ignored.
*/
public static void main(String[] args) {
JFrame frame = new JFrame("Memory Usage Demo");
MemoryUsageDemo panel = new MemoryUsageDemo(30000);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setBounds(200, 120, 600, 280);
frame.setVisible(true);
panel.new DataGenerator(100).start();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
76
Chapter 11
Tooltips
11.1
Overview
JFreeChart includes mechanisms for generating, collecting and displaying tool tips for individual
components of a chart.
In this section, I describe:
• how to generate tool tips (including customisation of tool tips);
• how tool tips are collected;
• how to display tool tips;
• how to disable tool tips if you don’t need them;
11.2
Generating Tool Tips
If you want to use tool tips, you need to make sure they are generated as your chart is being drawn.
You do this by setting a tool tip generator for your plot or, in many cases, the plot’s item renderer.
In the sub-sections that follow, I describe how to set a tool tip generator for the common chart
types.
11.2.1
Pie Charts
The PiePlot class generates tool tips using the PieToolTipGenerator interface. A standard implementation (StandardPieToolTipGenerator) is provided, and you are free to create your own implementations.
To set the tool tip generator, use the following method in the PiePlot class:
å public void setToolTipGenerator(PieToolTipGenerator generator);
Sets the tool tip generator for the pie chart. If you set this to null, no tool tips will be
generated.
11.2.2
Category Charts
Category charts—including most of the bar charts generated by JFreeChart—are based on the
CategoryPlot class and use a CategoryItemRenderer to draw each data item. The CategoryToolTipGenerator
interface specifies the method via which the renderer will obtain tool tips (if required).
To set the tool tip generator for a category plot’s item renderer, use the following method (defined
in the AbstractCategoryItemRenderer class):
77
CHAPTER 11. TOOLTIPS
78
å public void setToolTipGenerator(CategoryToolTipGenerator generator);
Sets the tool tip generator for the renderer. If you set this to null, no tool tips will be generated.
11.2.3
XY Charts
XY charts—including scatter plots and all the time series charts generated by JFreeChart—are
based on the XYPlot class and use an XYItemRenderer to draw each data item. The renderer generates
tool tips (if required) using an XYToolTipGenerator.
To set the tool tip generator for an XY plot’s item renderer, use the following method (defined in
the AbstractXYItemRenderer class):
å public void setToolTipGenerator(XYToolTipGenerator generator);
Sets the tool tip generator for the renderer. If you set this to null, no tool tips will be generated.
11.3
Collecting Tool Tips
Tool tips are collected, along with other chart entity information, using the ChartRenderingInfo
class. You need to supply an instance of this class to JFreeChart’s draw() method, otherwise no
tool tip information will be recorded (even if a generator has been registered with the plot or the
plot’s item renderer, as described in the previous sections).
Fortunately, the ChartPanel class takes care of this automatically, so if you are displaying your
charts using the ChartPanel class you do not need to worry about how tool tips are collected—it is
done for you.
11.4
Displaying Tool Tips
Tool tips are automatically displayed by the ChartPanel class, provided that you have set up a tool
tip generator for the plot (or the plot’s renderer).
You can also enable or disable the display of tool tips in the ChartPanel class, using this method:
å public void setDisplayToolTips(boolean flag);
Switches the display of tool tips on or off.
11.5
Disabling Tool Tips
The most effective way to disable tool tips is to set the tool tip generator to null. This ensures that
no tool tip information is even generated, which can save memory and processing time (particularly
for charts with large datasets).
You can also disable the display of tool tips in the ChartPanel class, using the method given in the
previous section.
11.6
Customising Tool Tips
You can take full control of the text generated for each tool tip by providing your own implementation of the appropriate tool tip generator interface.
Chapter 12
Item Labels
12.1
Introduction
12.1.1
Overview
For many chart types, JFreeChart will allow you to display item labels in, on or near to each data
item in a chart. For example, you can display the actual value represented by the bars in a bar
chart—see figure 12.1.
Figure 12.1: A bar chart with item labels
This chapter covers how to:
• make item labels visible (for the chart types that support item labels);
• change the appearance (font and color) of item labels;
• specify the location of item labels;
• customise the item label text.
A word of advice: use this feature sparingly. Charts are supposed to summarise your data—if you
feel it is necessary to display the actual data values all over your chart, then perhaps your data is
better presented in a table format.
79
CHAPTER 12. ITEM LABELS
12.1.2
80
Limitations
There are some limitations with respect to the item labels in the current release of JFreeChart:
• some renderers do not support item labels;
• axis ranges are not automatically adjusted to take into account the item labels—some labels
may disappear off the chart if sufficient margins are not set (use the setUpperMargin() and/or
setLowerMargin() methods in the relevant axis to adjust this).
In future releases of JFreeChart, some or all of these limitations will be addressed.
12.2
Displaying Item Labels
12.2.1
Overview
Item labels are not visible by default, so you need to configure the renderer to create and display
them. This involves two steps:
• assign a CategoryItemLabelGenerator or XYItemLabelGenerator to the renderer—this is an object that assumes responsibility for creating the labels;
• set a flag in the renderer to make the labels visible, either for all series or, if you prefer, on a
per series basis.
In addition, you have the option to customise the position, font and color of the item labels. These
steps are detailed in the following sections.
12.2.2
Assigning a Label Generator
Item labels are created by a label generator that is assigned to a renderer (the same mechanism is
also used for tooltips).
To assign a generator to a CategoryItemRenderer, use the following code:
CategoryItemRenderer renderer = plot.getRenderer();
CategoryItemLabelGenerator generator = new StandardCategoryItemLabelGenerator(
"{2}", new DecimalFormat("0.00"));
renderer.setLabelGenerator(generator);
Similarly, to assign a generator to an XYItemRenderer, use the following code:
XYItemRenderer renderer = plot.getRenderer();
XYItemLabelGenerator generator = new StandardXYItemLabelGenerator(
"{2}", new DecimalFormat("0.00"));
renderer.setLabelGenerator(generator);
You can customise the behaviour of the standard generator via settings that you can apply in the
constructor, or you can create your own generator as described in section 12.5.2.
12.2.3
Making Labels Visible For All Series
The setItemLabelsVisible() method sets a flag that controls whether or not the item labels are
displayed (note that a label generator must be assigned to the renderer, or there will be no labels
to display). For a CategoryItemRenderer:
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelsVisible(true);
Similarly, for a XYItemRenderer:
XYItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelsVisible(true);
Once set, this flag takes precedence over any per series settings you may have made elsewhere. In
order for the per series settings to apply, you need to set this flag to null (see section 12.2.4).
CHAPTER 12. ITEM LABELS
12.2.4
81
Making Labels Visible For Selected Series
If you prefer, you can set flags that control the visibility of the item labels on a per series basis.
For example, item labels are displayed only for the first series in figure 12.2.
Figure 12.2: Item labels for selected series only
You can use code similar to the following:
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelsVisible(null); // clears the ALL series flag
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelsVisible(1, false);
Notice that the flag for “all series” has been set to null—this is important, because the “all series”
flag takes precedence over the “per series” flags.
12.2.5
Troubleshooting
If, after following the steps outlined in the previous sections, you still can’t see any labels on your
chart, there are a couple of things to consider:
• the renderer must have a label generator assigned to it—this is an object that creates the text
items that are used for each label.
• some renderers don’t yet support the display of item labels (refer to the documentation for
the renderer you are using).
12.3
Item Label Appearance
12.3.1
Overview
You can change the appearance of the item labels by changing the font and/or the color used to
display the labels. As for most other renderer attributes, the settings can be made once for all
series, or on a per series basis.
In the current release of JFreeChart, labels are drawn with a transparent background.
You cannot set a background color for the labels, nor can you specify that a border be
drawn around the labels. This may change in the future.
CHAPTER 12. ITEM LABELS
12.3.2
82
Changing the Label Font
To change the font for the item labels in all series, you can use code similar to the following:
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelFont(new Font("SansSerif", Font.PLAIN, 10));
Similarly, to set the font for individual series:
CategoryItemRenderer renderer = plot.getRenderer();
// clear the settings for ALL series...
renderer.setItemLabelFont(null);
// add settings for individual series...
renderer.setSeriesItemLabelFont(0, new Font("SansSerif", Font.PLAIN, 10));
renderer.setSeruesItemLabelFont(1, new Font("SansSerif", Font.BOLD, 10));
Notice how the font for all series has be set to null to prevent it from overriding the per series
settings.
12.3.3
Changing the Label Color
To change the color for the item labels in all series, you can use code similar to the following:
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelPaint(Color.red);
Similarly, to set the color for individual series:
CategoryItemRenderer renderer = plot.getRenderer();
// clear the settings for ALL series...
renderer.setItemLabelPaint(null);
// add settings for individual series...
renderer.setSeriesItemLabelPaint(0, Color.red);
renderer.setSeriesItemLabelPaint(1, Color.blue);
Once again, notice how the paint for all series has been set to null to prevent it from overriding
the per series settings.
12.4
Item Label Positioning
12.4.1
Overview
The positioning of item labels is controlled by four attributes that are combined into an ItemLabelPosition
object. You can define label positions for items with positive and negative values independently,
via the following methods in the CategoryItemRenderer interface:
public void setPositiveItemLabelPosition(ItemLabelPosition position);
public void setNegativeItemLabelPosition(ItemLabelPosition position);
Understanding how these attributes impact the final position of individual labels is key to getting
good results from the item label features in JFreeChart.
There are four attributes:
• the item label anchor - determines the base location for the item label;
• the text anchor - determines the point on the label that is aligned to the base location;
• the rotation anchor - this is the point on the label text about which the rotation (if any) is
applied;
• the rotation angle - the angle through which the label is rotated.
These are described in the following sections.
CHAPTER 12. ITEM LABELS
12.4.2
83
The Item Label Anchor
The purpose of the item label anchor setting is to determine an (x, y) location on the chart that is
near to the data item that is being labelled. The label is then aligned to this anchor point when it
is being drawn. Refer to the ItemLabelAnchor documentation for more information.
12.4.3
The Text Anchor
The text anchor determines which point on the label should be aligned with the anchor point
described in the previous section. It is possible to align the center of the label with the anchor point,
or the top-right of the label, or the bottom-left, and so on...refer to the TextAnchor documentation
for all the options.
Running the DrawStringDemo application in the org.jfree.demo package (included in the JCommon
distribution) is a good way to gain an understanding of how the text anchor is used to align labels
to a point on the screen.
12.4.4
The Rotation Anchor
The rotation anchor defines a point on the label about which the rotation (if any) will be applied
to the label. The DrawStringDemo class also demonstrates this feature.
12.4.5
The Rotation Angle
The rotation angle defines the angle through which the label is rotated. The angle is specified in
radians, and the rotation point is defined by the rotation anchor described in the previous section.
12.5
Customising the Item Label Text
12.5.1
Overview
Up to this point, we’ve relied on the label generator built in to JFreeChart to create the text for
the item labels. If you want to have complete control over the label text, you can write your own
class that implements the CategoryItemLabelGenerator interface.
In this section I provide a brief overview of the technique for implementing a custom label generator,
then present two examples to illustrate the type of results you can achieve with this technique.
12.5.2
Implementing a Custom Item Label Generator
To develop a custom label generator, you simply need to write a class that implements the method
defined in the CategoryItemLabelGenerator interface:
public String generateLabel(CategoryDataset dataset, int series, int category);
The renderer will call this method at the point that it requires a String use for a label, and will
pass in the CategoryDataset and the series and category indices for the current item. This means
that you have full access to the entire dataset (not just the current item) for the creation of the
label.
The method can return an arbitrary String value, so you can apply any formatting you want to
the result. It is also valid to return null if you prefer no label to be displayed.
All this is best illustrated by way of examples, which are provided in the following sections.
CHAPTER 12. ITEM LABELS
12.6
Example 1 - Values Above a Threshold
12.6.1
Overview
84
In this first example, the goal is to display labels for the items that have a value greater than some
predefined threshold value (see figure 12.3).
Figure 12.3: Item labels above a threshold
It isn’t all that difficult to achieve, we simply need to:
• write a class that implements the CategoryItemLabelGenerator interface, and implement the
generateItemLabel() method in such a way that it returns null for any item where the value
is less than the threshold;
• create an instance of this new class, and assign it to the renderer using the setLabelGenerator()
method.
12.6.2
Source Code
The complete source code is presented below.
/* ------------------* ItemLabelDemo1.java
* ------------------* (C) Copyright 2004, 2005, by Object Refinery Limited.
*
*/
package demo;
import
import
import
import
java.awt.Color;
java.awt.Dimension;
java.awt.Font;
java.text.NumberFormat;
import javax.swing.JPanel;
import
import
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.ChartPanel;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.NumberAxis;
org.jfree.chart.labels.AbstractCategoryItemLabelGenerator;
org.jfree.chart.labels.CategoryItemLabelGenerator;
org.jfree.chart.plot.CategoryPlot;
org.jfree.chart.plot.PlotOrientation;
org.jfree.chart.renderer.category.CategoryItemRenderer;
org.jfree.data.category.CategoryDataset;
org.jfree.data.category.DefaultCategoryDataset;
CHAPTER 12. ITEM LABELS
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
/**
* A simple demo showing a label generator that only displays labels for items
* with a value that is greater than some threshold.
*/
public class ItemLabelDemo1 extends ApplicationFrame {
/**
* A custom label generator.
*/
static class LabelGenerator extends AbstractCategoryItemLabelGenerator
implements CategoryItemLabelGenerator {
/** The threshold. */
private double threshold;
/**
* Creates a new generator that only displays labels that are greater
* than or equal to the threshold value.
*
* @param threshold the threshold value.
*/
public LabelGenerator(double threshold) {
super("", NumberFormat.getInstance());
this.threshold = threshold;
}
/**
* Generates a label for the specified item. The label is typically a
* formatted version of the data value, but any text can be used.
*
* @param dataset the dataset (null not permitted).
* @param series the series index (zero-based).
* @param category the category index (zero-based).
*
* @return the label (possibly null).
*/
public String generateLabel(CategoryDataset dataset,
int series,
int category) {
String result = null;
Number value = dataset.getValue(series, category);
if (value != null) {
double v = value.doubleValue();
if (v > this.threshold) {
result = value.toString(); // could apply formatting here
}
}
return result;
}
}
/**
* Creates a new demo instance.
*
* @param title the frame title.
*/
public ItemLabelDemo1(String title) {
super(title);
CategoryDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return The dataset.
*/
private static CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
85
CHAPTER 12. ITEM LABELS
dataset.addValue(11.0,
dataset.addValue(44.3,
dataset.addValue(93.0,
dataset.addValue(35.6,
dataset.addValue(75.1,
return dataset;
"S1",
"S1",
"S1",
"S1",
"S1",
"C1");
"C2");
"C3");
"C4");
"C5");
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
*
* @return the chart.
*/
private static JFreeChart createChart(CategoryDataset dataset) {
// create the chart...
JFreeChart chart = ChartFactory.createBarChart(
"Item Label Demo 1",
// chart title
"Category",
// domain axis label
"Value",
// range axis label
dataset,
// data
PlotOrientation.VERTICAL, // orientation
false,
// include legend
true,
// tooltips?
false
// URLs?
);
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = chart.getCategoryPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setUpperMargin(0.15);
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelGenerator(new LabelGenerator(50.0));
renderer.setItemLabelFont(new Font("Serif", Font.PLAIN, 20));
renderer.setItemLabelsVisible(true);
return chart;
}
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
return new ChartPanel(chart);
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
ItemLabelDemo1 demo = new ItemLabelDemo1("Item Label Demo 1");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
86
CHAPTER 12. ITEM LABELS
12.7
Example 2 - Displaying Percentages
12.7.1
Overview
87
In this example, the requirement is to display a bar chart where each bar is labelled with the
value represented by the bar and also a percentage (where the percentage is calculated relative to
a particular bar within the series OR the total of all the values in the series)—see figure 12.4.
Figure 12.4: Percentage item labels
In this implementation, the label generator calculates the percentage value on-the-fly. If a category
index is supplied in the constructor, the base value used to calculate the percentage is taken from
the specified category within the current series. If no category index is available, then the total of
all the values in the current series is used as the base.
A default percentage formatter is created within the label generator—a more sophisticated implementation would provide the ability for the formatter to be customised via the generator’s
constructor.
12.7.2
Source Code
The complete source code follows.
/* ------------------* ItemLabelDemo2.java
* ------------------* (C) Copyright 2005, by Object Refinery Limited.
*
*/
package demo;
import java.awt.Color;
/**
* A simple demo showing a label generator that displays labels that include
* a percentage calculation.
*/
public class ItemLabelDemo2 extends ApplicationFrame {
/**
* A custom label generator.
*/
static class LabelGenerator extends AbstractCategoryItemLabelGenerator
implements CategoryItemLabelGenerator {
/**
* The index of the category on which to base the percentage
CHAPTER 12. ITEM LABELS
* (null = use series total).
*/
private Integer category;
/** A percent formatter. */
private NumberFormat formatter = NumberFormat.getPercentInstance();
/**
* Creates a new label generator that displays the item value and a
* percentage relative to the value in the same series for the
* specified category.
*
* @param category the category index (zero-based).
*/
public LabelGenerator(int category) {
this(new Integer(category));
}
/**
* Creates a new label generator that displays the item value and
* a percentage relative to the value in the same series for the
* specified category. If the category index is null,
* the total of all items in the series is used.
*
* @param category the category index (null permitted).
*/
public LabelGenerator(Integer category) {
super("", NumberFormat.getInstance());
this.category = category;
}
/**
* Generates a label for the specified item. The label is typically
* a formatted version of the data value, but any text can be used.
*
* @param dataset the dataset (null not permitted).
* @param series the series index (zero-based).
* @param category the category index (zero-based).
*
* @return the label (possibly null).
*/
public String generateLabel(CategoryDataset dataset,
int series,
int category) {
String result = null;
double base = 0.0;
if (this.category != null) {
final Number b = dataset.getValue(series, this.category.intValue());
base = b.doubleValue();
}
else {
base = calculateSeriesTotal(dataset, series);
}
Number value = dataset.getValue(series, category);
if (value != null) {
final double v = value.doubleValue();
// you could apply some formatting here
result = value.toString()
+ " (" + this.formatter.format(v / base) + ")";
}
return result;
}
/**
* Calculates a series total.
*
* @param dataset the dataset.
* @param series the series index.
*
* @return The total.
*/
private double calculateSeriesTotal(CategoryDataset dataset, int series) {
double result = 0.0;
for (int i = 0; i < dataset.getColumnCount(); i++) {
Number value = dataset.getValue(series, i);
if (value != null) {
result = result + value.doubleValue();
}
}
88
CHAPTER 12. ITEM LABELS
return result;
}
}
/**
* Creates a new demo instance.
*
* @param title the frame title.
*/
public ItemLabelDemo2(String title) {
super(title);
CategoryDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartPanel);
}
/**
* Returns a sample dataset.
*
* @return the dataset.
*/
private static CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(100.0, "S1", "C1");
dataset.addValue(44.3, "S1", "C2");
dataset.addValue(93.0, "S1", "C3");
dataset.addValue(80.0, "S2", "C1");
dataset.addValue(75.1, "S2", "C2");
dataset.addValue(15.1, "S2", "C3");
return dataset;
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
*
* @return the chart.
*/
private static JFreeChart createChart(CategoryDataset dataset) {
// create the chart...
JFreeChart chart = ChartFactory.createBarChart(
"Item Label Demo 2",
// chart title
"Category",
// domain axis label
"Value",
// range axis label
dataset,
// data
PlotOrientation.HORIZONTAL, // orientation
true,
// include legend
true,
// tooltips?
false
// URLs?
);
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = chart.getCategoryPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setUpperMargin(0.25);
CategoryItemRenderer renderer = plot.getRenderer();
renderer.setItemLabelsVisible(true);
// use one or the other of the following lines to see the
// different modes for the label generator...
renderer.setItemLabelGenerator(new LabelGenerator(null));
//renderer.setLabelGenerator(new LabelGenerator(0));
return chart;
89
CHAPTER 12. ITEM LABELS
}
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
return new ChartPanel(chart);
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
ItemLabelDemo2 demo = new ItemLabelDemo2("Item Label Demo 2");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
90
Chapter 13
Multiple Axes and Datasets
13.1
Introduction
JFreeChart supports the use of multiple axes and datasets in the CategoryPlot and XYPlot classes.
You can use this feature to display two or more datasets on a single chart, while making allowance
for the fact that the datasets may contain data of vastly different magnitudes—see figure 13.1 for
an example.
Figure 13.1: A chart with multiple axes
Typical charts constructed with JFreeChart use a plot that has a single dataset, a single renderer,
a single domain axis and a single range axis. However, it is possible to add multiple datasets,
renderers and axes to a plot. In this section, an example is presented showing how to use these
additional datasets, renderers and axes.
13.2
An Example
13.2.1
Introduction
The MultipleAxisDemo1.java application (included in the JFreeChart Demo distribution) provides
a good example of how to create a chart with multiple axes. This section provides some notes on
the steps taken within that code.
91
CHAPTER 13. MULTIPLE AXES AND DATASETS
13.2.2
92
Create a Chart
To create a chart with multiple axes, datasets, and renderers, you should first create a regular chart
(for example, using the ChartFactory class). You can use any chart that is constructed using a
CategoryPlot or an XYPlot. In the example, a time series chart is created as follows:
XYDataset dataset1
JFreeChart chart =
"Multiple Axis
"Time of Day",
"Primary Range
dataset1,
true,
true,
false
);
13.2.3
= createDataset("Series 1", 100.0, new Minute(), 200);
ChartFactory.createTimeSeriesChart(
Demo 1",
Axis",
Adding an Additional Axis
To add an additional axis to a plot, you can use the setRangeAxis() method:
NumberAxis axis2 = new NumberAxis("Range Axis 2");
plot.setRangeAxis(1, axis2);
plot.setRangeAxisLocation(1, AxisLocation.BOTTOM OR RIGHT);
The setRangeAxis() method is used to add the axis to the plot. Note that an index of 1 (one) has
been used—you can add as many additional axes as you require, by incrementing the index each
time you add a new axis.
The setRangeAxisLocation() method allows you to specify where the axis will appear on the chart,
using the AxisLocation class. You can have the axis on the same side as the primary axis, or on
the opposite side—the choice is yours. In the example, BOTTOM OR RIGHT is specified, which means
(for a range axis) on the right if the plot has a vertical orientation, or at the bottom if the plot has
a horizontal orientation.
At this point, no additional dataset has been added to the chart, so if you were to display the chart
you would see the additional axis, but it would have no data plotted against it.
13.2.4
Adding an Additional Dataset
To add an additional dataset to a plot, use the setDataset() method:
XYDataset dataset2 = ... // up to you
plot.setDataset(1, dataset2);
By default, the dataset will be plotted against the primary range axis. To have the dataset plotted
against a different axis, use the mapDatasetToDomainAxis() and mapDatasetToRangeAxis() methods.
These methods accept two arguments, the first is the index of the dataset, and the second is the
index of the axis.
13.2.5
Adding an Additional Renderer
When you add an additional dataset, usually it makes sense to add an additional renderer to go
with the dataset. Use the setRenderer() method:
XYItemRenderer renderer2 = ... // up to you
plot.setRenderer(1, renderer2);
The index (1 in this case) should correspond to the index of the dataset added previously.
Note: if you don’t specify an additional renderer, the primary renderer will be used instead. In
that case, the series colors will be shared between the primary dataset and the additional dataset.
CHAPTER 13. MULTIPLE AXES AND DATASETS
13.3
93
Hints and Tips
When using multiple axes, you need to provide some visual cue to readers to indicate which axis
applies to a particular series. In the MultipleAxisDemo1.java application, the color of the axis label
text has been changed to match the series color.
Additional demos available for download with the JFreeChart Developer Guide include:
• DualAxisDemo1.java
• DualAxisDemo2.java
• DualAxisDemo3.java
• DualAxisDemo4.java
• MultipleAxisDemo1.java
• MultipleAxisDemo2.java
• MultipleAxisDemo3.java
Chapter 14
Combined Charts
14.1
Introduction
JFreeChart supports combined charts via several plot classes that can manage any number of subplots:
• CombinedDomainCategoryPlot / CombinedRangeCategoryPlot;
• CombinedDomainXYPlot / CombinedRangeXYPlot;
This section presents a few examples that use the combined chart facilities provided by JFreeChart.
All the examples are included in the JFreeChart demo collection.
14.2
Combined Domain Category Plot
14.2.1
Overview
A combined domain category plot is a plot that displays two or more subplots (instances of CategoryPlot)
that share a common domain axis. Each subplot maintains its own range axis. An example is shown
in figure 14.1.
Figure 14.1: A combined domain category plot
It is possible to display this chart with a horizontal or vertical orientation—the example shown has
a vertical orientation.
94
CHAPTER 14. COMBINED CHARTS
14.2.2
95
Constructing the Chart
A demo application (CombinedCategoryPlotDemo1.java, available for download with the JFreeChart
Developer Guide) provides an example of how to create this type of chart. The key step is the
creation of a CombinedDomainCategoryPlot instance, to which subplots are added:
CategoryAxis domainAxis = new CategoryAxis("Category");
CombinedDomainCategoryPlot plot = new CombinedDomainCategoryPlot(domainAxis);
plot.add(subplot1, 2);
plot.add(subplot2, 1);
JFreeChart result = new JFreeChart(
"Combined Domain Category Plot Demo",
new Font("SansSerif", Font.BOLD, 12),
plot,
true
);
Notice how subplot1 has been added with a weight of 2 (the second argument in the add() method,
while subplot2 has been added with a weight of 1. This controls the amount of space allocated to
each plot.
The subplots are regular CategoryPlot instances that have had their domain axis set to null. For
example, in the demo application the following code is used (it includes some customisation of the
subplots):
CategoryDataset dataset1 = createDataset1();
NumberAxis rangeAxis1 = new NumberAxis("Value");
rangeAxis1.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
LineAndShapeRenderer renderer1 = new LineAndShapeRenderer();
renderer1.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
CategoryPlot subplot1 = new CategoryPlot(dataset1, null, rangeAxis1, renderer1);
subplot1.setDomainGridlinesVisible(true);
CategoryDataset dataset2 = createDataset2();
NumberAxis rangeAxis2 = new NumberAxis("Value");
rangeAxis2.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
BarRenderer renderer2 = new BarRenderer();
renderer2.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
CategoryPlot subplot2 = new CategoryPlot(dataset2, null, rangeAxis2, renderer2);
subplot2.setDomainGridlinesVisible(true);
14.3
Combined Range Category Plot
14.3.1
Overview
A combined range category plot is a plot that displays two or more subplots (instances of CategoryPlot)
that share a common range axis. Each subplot maintains its own domain axis. An example is shown
in figure 14.2.
It is possible to display this chart with a horizontal or vertical orientation (the example above has
a vertical orientation).
14.3.2
Constructing the Chart
A demo application (CombinedCategoryPlotDemo2.java, available for download with the JFreeChart
Developer Guide) provides an example of how to create this type of chart. The key step is the
creation of a CombinedRangeCategoryPlot instance, to which subplots are added:
ValueAxis rangeAxis = new NumberAxis("Value");
CombinedRangeCategoryPlot plot = new CombinedRangeCategoryPlot(rangeAxis);
plot.add(subplot1, 3);
plot.add(subplot2, 2);
JFreeChart result = new JFreeChart(
"Combined Range Category Plot Demo",
new Font("SansSerif", Font.BOLD, 12),
plot,
true
);
CHAPTER 14. COMBINED CHARTS
96
Figure 14.2: A combined range category plot.
Notice how subplot1 has been added with a weight of 3 (the second argument in the add() method),
while subplot2 has been added with a weight of 2. This controls the amount of space allocated to
each plot.
The subplots are regular CategoryPlot instances that have had their range axis set to null. For
example, in the demo application the following code is used (it includes some customisation of the
subplots):
CategoryDataset dataset1 = createDataset1();
CategoryAxis domainAxis1 = new CategoryAxis("Class 1");
domainAxis1.setCategoryLabelPositions(CategoryLabelPositions.UP 45);
domainAxis1.setMaxCategoryLabelWidthRatio(5.0f);
LineAndShapeRenderer renderer1 = new LineAndShapeRenderer();
renderer1.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
CategoryPlot subplot1 = new CategoryPlot(dataset1, domainAxis1, null, renderer1);
subplot1.setDomainGridlinesVisible(true);
CategoryDataset dataset2 = createDataset2();
CategoryAxis domainAxis2 = new CategoryAxis("Class 2");
domainAxis2.setCategoryLabelPositions(CategoryLabelPositions.UP 45);
domainAxis2.setMaxCategoryLabelWidthRatio(5.0f);
BarRenderer renderer2 = new BarRenderer();
renderer2.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
CategoryPlot subplot2 = new CategoryPlot(dataset2, domainAxis2, null, renderer2);
subplot2.setDomainGridlinesVisible(true);
14.4
Combined Domain XY Plot
14.4.1
Overview
A combined domain XY plot is a plot that displays two or more subplots (instances of XYPlot) that
share a common domain axis. Each subplot maintains its own range axis. An example is shown in
figure 14.3.
It is possible to display this chart with a horizontal or vertical orientation (the example shown has
a vertical orientation).
14.4.2
Constructing the Chart
A demo application (CombinedXYPlotDemo1.java, available for download with the JFreeChart Developer Guide) provides an example of how to create this type of chart. The key step is the creation
of a CombinedDomainXYPlot instance, to which subplots are added:
CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain"));
plot.setGap(10.0);
CHAPTER 14. COMBINED CHARTS
97
Figure 14.3: A combined domain XY plot
plot.add(subplot1, 1);
plot.add(subplot2, 1);
plot.setOrientation(PlotOrientation.VERTICAL);
return new JFreeChart(
"CombinedDomainXYPlot Demo",
JFreeChart.DEFAULT TITLE FONT, plot, true
);
Notice how the subplots are added with weights (both 1 in this case). This controls the amount of
space allocated to each plot.
The subplots are regular XYPlot instances that have had their domain axis set to null. For example,
in the demo application the following code is used (it includes some customisation of the subplots):
XYDataset data1 = createDataset1();
XYItemRenderer renderer1 = new StandardXYItemRenderer();
NumberAxis rangeAxis1 = new NumberAxis("Range 1");
XYPlot subplot1 = new XYPlot(data1, null, rangeAxis1, renderer1);
subplot1.setRangeAxisLocation(AxisLocation.BOTTOM OR LEFT);
XYTextAnnotation annotation = new XYTextAnnotation("Hello!", 50.0, 10000.0);
annotation.setFont(new Font("SansSerif", Font.PLAIN, 9));
annotation.setRotationAngle(Math.PI / 4.0);
subplot1.addAnnotation(annotation);
// create subplot 2...
XYDataset data2 = createDataset2();
XYItemRenderer renderer2 = new StandardXYItemRenderer();
NumberAxis rangeAxis2 = new NumberAxis("Range 2");
rangeAxis2.setAutoRangeIncludesZero(false);
XYPlot subplot2 = new XYPlot(data2, null, rangeAxis2, renderer2);
subplot2.setRangeAxisLocation(AxisLocation.TOP OR LEFT);
14.5
Combined Range XY Plot
14.5.1
Overview
A combined range XY plot is a plot that displays two or more subplots (instances of XYPlot) that
share a common range axis. Each subplot maintains its own domain axis. An example is shown in
figure 14.4.
It is possible to display this chart with a horizontal or vertical orientation (the example shown has
a vertical orientation).
CHAPTER 14. COMBINED CHARTS
98
Figure 14.4: A combined range XY plot
14.5.2
Constructing the Chart
A demo application (CombinedXYPlotDemo2.java, available for download with the JFreeChart Developer Guide) provides an example of how to create this type of chart. The key step is the creation
of a CombinedRangeXYPlot instance, to which subplots are added:
// create the plot...
CombinedRangeXYPlot plot = new CombinedRangeXYPlot(new NumberAxis("Value"));
plot.add(subplot1, 1);
plot.add(subplot2, 1);
return new JFreeChart(
"Combined (Range) XY Plot",
JFreeChart.DEFAULT TITLE FONT, plot, true
);
Notice how the subplots are added with weights (both 1 in this case). This controls the amount of
space allocated to each plot.
The subplots are regular XYPlot instances that have had their range axis set to null. For example,
in the demo application the following code is used (it includes some customisation of the subplots):
// create subplot 1...
IntervalXYDataset data1 = createDataset1();
XYItemRenderer renderer1 = new XYBarRenderer(0.20);
renderer1.setToolTipGenerator(
new StandardXYToolTipGenerator(
new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.0")
)
);
XYPlot subplot1 = new XYPlot(data1, new DateAxis("Date"), null, renderer1);
// create subplot 2...
XYDataset data2 = createDataset2();
XYItemRenderer renderer2 = new StandardXYItemRenderer();
renderer2.setToolTipGenerator(
new StandardXYToolTipGenerator(
new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.0")
)
);
XYPlot subplot2 = new XYPlot(data2, new DateAxis("Date"), null, renderer2);
Chapter 15
Datasets and JDBC
15.1
Introduction
In this section, I describe the use of several datasets that are designed to work with JDBC to obtain
data from database tables:
• JDBCPieDataset
• JDBCCategoryDataset
• JDBCXYDataset
These datasets have been developed by Bryan Scott of the Australian Antarctic Division.
15.2
About JDBC
JDBC is a high-level Java API for working with relational databases. JDBC does a good job of
furthering Java’s platform independence, making it possible to write portable code that will work
with many different database systems.
JDBC provides a mechanism for loading a JDBC driver specific to the database system actually
being used. JDBC drivers are available for many databases, on many different platforms.
15.3
Sample Data
To see the JDBC datasets in action, you need to create some sample data in a test database.
Here is listed some sample data that will be used to create a pie chart, a bar chart and a time series
chart.
A pie chart will be created using this data (in a table called piedata1):
CATEGORY | VALUE
---------+-----London
| 54.3
New York | 43.4
Paris
| 17.9
Similarly, a bar chart will be created using this data (in a table called categorydata1):
CATEGORY | SERIES1 | SERIES2 | SERIES3
---------+---------+---------+-------London
|
54.3 |
32.1 |
53.4
New York |
43.4 |
54.3 |
75.2
Paris
|
17.9 |
34.8 |
37.1
99
CHAPTER 15. DATASETS AND JDBC
100
Finally, a time series chart will be generated using this data (in a table called xydata1):
X
| SERIES1 | SERIES2 | SERIES3
-----------+---------+---------+-------1-Aug-2002 |
54.3 |
32.1 |
53.4
2-Aug-2002 |
43.4 |
54.3 |
75.2
3-Aug-2002 |
39.6 |
55.9 |
37.1
4-Aug-2002 |
35.4 |
55.2 |
27.5
5-Aug-2002 |
33.9 |
49.8 |
22.3
6-Aug-2002 |
35.2 |
48.4 |
17.7
7-Aug-2002 |
38.9 |
49.7 |
15.3
8-Aug-2002 |
36.3 |
44.4 |
12.1
9-Aug-2002 |
31.0 |
46.3 |
11.0
You should set up a test database containing these tables...ask your database administrator to help
you if necessary. I’ve called my test database jfreechartdb, but you can change the name if you
want to.
In the next section I document the steps I used to set up this sample data usingPostgreSQL, the
database system that I have available for testing purposes. If you are using a different system,
you may need to perform a slightly different procedure—refer to your database documentation for
information.
15.4
PostgreSQL
15.4.1
About PostgreSQL
PostgreSQL is a powerful object-relational database server, distributed under an open-source licence.
You can find out more about PostgreSQL at:
http://www.postgresql.org
Note: although PostgreSQL is free, it has most of the features of large commercial relational
database systems. I encourage you to install it and try it out.
15.4.2
Creating a New Database
First, while logged in as the database administrator, I create a test database called jfreechartdb:
CREATE DATABASE jfreechartdb;
Next, I create a user jfreechart:
CREATE USER jfreechart WITH PASSWORD ’password’;
This username and password will be used to connect to the database via JDBC.
15.4.3
Creating the Pie Chart Data
To create the table for the pie dataset:
CREATE TABLE piedata1 (
category VARCHAR(32),
value
FLOAT
);
...and to populate it:
INSERT INTO piedata1 VALUES (’London’,
54.3);
INSERT INTO piedata1 VALUES (’New York’, 43.4);
INSERT INTO piedata1 VALUES (’Paris’,
17.9);
CHAPTER 15. DATASETS AND JDBC
15.4.4
101
Creating the Category Chart Data
To create the table for the category dataset:
CREATE TABLE
category
series1
series2
series3
);
categorydata1 (
VARCHAR(32),
FLOAT,
FLOAT,
FLOAT
...and to populate it:
INSERT INTO categorydata1 VALUES (’London’,
54.3, 32.1, 53.4);
INSERT INTO categorydata1 VALUES (’New York’, 43.4, 54.3, 75.2);
INSERT INTO categorydata1 VALUES (’Paris’,
17.9, 34.8, 37.1);
15.4.5
Creating the XY Chart Data
To create the table for the XY dataset:
CREATE TABLE
date
series1
series2
series3
);
xydata1 (
DATE,
FLOAT,
FLOAT,
FLOAT
...and to populate it:
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
xydata1
xydata1
xydata1
xydata1
xydata1
xydata1
xydata1
xydata1
xydata1
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
(’1-Aug-2002’,
(’2-Aug-2002’,
(’3-Aug-2002’,
(’4-Aug-2002’,
(’5-Aug-2002’,
(’6-Aug-2002’,
(’7-Aug-2002’,
(’8-Aug-2002’,
(’9-Aug-2002’,
54.3,
43.4,
39.6,
35.4,
33.9,
35.2,
38.9,
36.3,
31.0,
32.1,
54.3,
55.9,
55.2,
49.8,
48.4,
49.7,
44.4,
46.3,
53.4);
75.2);
37.1);
27.5);
22.3);
17.7);
15.3);
12.1);
11.0);
Granting Table Permissions
The last step in setting up the sample database is to grant read access to the new tables to the user
jfreechart:
GRANT SELECT ON piedata1 TO jfreechart;
GRANT SELECT ON categorydata1 TO jfreechart;
GRANT SELECT ON xydata1 TO jfreechart;
15.5
The JDBC Driver
To access the sample data via JDBC, you need to obtain a JDBC driver for your database. For
PostgreSQL, I downloaded a free driver from:
http://jdbc.postgresql.org
In order to use this driver, I need to ensure that the jar file containing the driver is on the classpath.
CHAPTER 15. DATASETS AND JDBC
15.6
The Demo Applications
15.6.1
JDBCPieChartDemo
102
The JDBCPieChartDemo application will generate a pie chart using the data in the piedata1 table,
providing that you have configured your database correctly.
The code for reading the data is in the readData() method:
private PieDataset readData() {
JDBCPieDataset data = null;
String url = "jdbc:postgresql://nomad/jfreechartdb";
Connection con;
try {
Class.forName("org.postgresql.Driver");
}
catch (ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url, "jfreechart", "password");
data = new JDBCPieDataset(con);
String sql = "SELECT * FROM PIEDATA1;";
data.executeQuery(sql);
con.close();
}
catch (SQLException e) {
System.err.print("SQLException: ");
System.err.println(e.getMessage());
}
catch (Exception e) {
System.err.print("Exception: ");
System.err.println(e.getMessage());
}
return data;
}
Important things to note in the code are:
• the url used to reference the test database includes the name of my test server (nomad), you
will need to modify this;
• a connection is made to the database using the username/password combination jfreechart/password;
• the query used to pull the data from the database is a standard SELECT query, but you
can use any SQL query as long as it returns columns in the required format (refer to the
JDBCPieDataset class documentation for details).
15.6.2
JDBCCategoryChartDemo
The JDBCCategoryChartDemo application generates a bar chart using the data in the categorydata1
table. The code is almost identical to the JDBCPieChartDemo. Once again, you can use any SQL
query as long as it returns columns in the required format (refer to the JDBCCategoryDataset class
documentation for details).
15.6.3
JDBCXYChartDemo
The JDBCXYChartDemo application generates a time series chart using the data in the xydata1 table.
The code is almost identical to the JDBCPieChartDemo. Once again, you can use any SQL query as
long as it returns columns in the required format (refer to the JDBCXYDataset class documentation
for details).
Chapter 16
Exporting Charts to Acrobat PDF
16.1
Introduction
In this section, I describe how to export a chart to an Acrobat PDF file using JFreeChart and
iText. Along with the description, I provide a small demonstration application that creates a PDF
file containing a basic chart. The resulting file can be viewed using Acrobat Reader, or any other
software that is capable of reading and displaying PDF files.
16.2
What is Acrobat PDF?
Acrobat PDF is a widely used electronic document format. Its popularity is due, at least in part,
to its ability to reproduce high quality output on a variety of different platforms.
PDF was created by Adobe Systems Incorporated. Adobe provide a free (but closed source) application called Acrobat Reader for reading PDF documents. Acrobat Reader is available on most
end-user computing platforms, including GNU/Linux, Windows, Unix, Macintosh and others.
If your system doesn’t have Acrobat Reader installed, you can download a copy from:
http://www.adobe.com/products/acrobat/readstep.html
On some platforms, there are free (in the GNU sense) software packages available for viewing PDF
files. Ghostview on Linux is one example.
16.3
iText
iText is a popular free Java class library for creating documents in PDF format. It is developed by
Bruno Lowagie, Paulo Soares and others. The home page for iText is:
http://www.lowagie.com/iText
At the time of writing, the latest version of iText is 2.0.1.
16.4
Graphics2D
JFreeChart can work easily with iText because iText provides a Graphics2D implementation. Before
I proceed to the demonstration application, I will briefly review the Graphics2D class.
The java.awt.Graphics2D class, part of the standard Java 2D API, defines a range of methods for
drawing text and graphics in a two dimensional space. Particular subclasses of Graphics2D handle
all the details of mapping the output (text and graphics) to specific devices.
103
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
104
JFreeChart has been designed to draw charts using only the methods defined by the Graphics2D
class. This means that JFreeChart can generate output to any target that can provide a Graphics2D
subclass.
JFreeChart
+draw(Graphics2D)
Graphics2D
PDF
Figure 16.1: The JFreeChart draw() method
iText incorporates a PdfGraphics2D class, which means that iText is capable of generating PDF
content based on calls to the methods defined by the Graphics2D class...and this makes it easy to
produce charts in PDF format, as you will see in the following sections.
16.5
Getting Started
To compile and run the demonstration application, you will need the following jar files:
File:
Description:
jfreechart-1.0.9.jar
jcommon-1.0.12.jar
itext-2.0.1.jar
The JFreeChart class library.
The JCommon class library (used by JFreeChart).
The iText class library.
The first two files are included with JFreeChart, and the third is the iText runtime.
16.6
The Application
The first thing the sample application needs to do is create a chart. Here we create a time series
chart:
// create a chart...
XYDataset dataset = createDataset();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Legal & General Unit Trust Prices",
"Date",
"Price Per Unit",
dataset,
true,
true,
false
);
// some additional chart customisation here...
There is nothing special here—in fact you could replace the code above with any other code that
creates a JFreeChart object. You are encouraged to experiment.
Next, I will save a copy of the chart in a PDF file:
// write the chart to a PDF file...
File fileName = new File(System.getProperty("user.home") + "/jfreechart1.pdf");
saveChartAsPDF(fileName, chart, 400, 300, new DefaultFontMapper());
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
105
There are a couple of things to note here.
First, I have hard-coded the filename used for the PDF file. I’ve done this to keep the sample
code short. In a real application, you would provide some other means for the user to specify the
filename, perhaps by presenting a file chooser dialog.
Second, the saveChartAsPDF() method hasn’t been implemented yet! To create that method, I’ll
first write another more general method, writeChartAsPDF(). This method performs most of the
work that will be required by the saveChartAsPDF() method, but it writes data to an output stream
rather than a file.
public static void writeChartAsPDF(OutputStream out,
JFreeChart chart,
int width,
int height,
FontMapper mapper) throws IOException {
Rectangle pagesize = new Rectangle(width, height);
Document document = new Document(pagesize, 50, 50, 50, 50);
try {
PdfWriter writer = PdfWriter.getInstance(document, out);
document.addAuthor("JFreeChart");
document.addSubject("Demonstration");
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfTemplate tp = cb.createTemplate(width, height);
Graphics2D g2 = tp.createGraphics(width, height, mapper);
Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
chart.draw(g2, r2D);
g2.dispose();
cb.addTemplate(tp, 0, 0);
}
catch (DocumentException de) {
System.err.println(de.getMessage());
}
document.close();
}
Inside this method, you will see some code that sets up and opens an iText document, obtains a
Graphics2D instance from the document, draws the chart using the Graphics2D object, and closes
the document.
You will also notice that one of the parameters for this method is a FontMapper object. The
FontMapper interface maps Java Font objects to the BaseFont objects used by iText.
The DefaultFontMapper class is predefined with default mappings for the Java logical fonts. If you
use only these fonts, then it is enough to create a DefaultFontMapper using the default constructor.
If you want to use other fonts (for example, a font that supports a particular character set) then
you need to do more work. I’ll give an example of this later.
In the implementation of the writeChartAsPDF() method, I’ve chosen to create a PDF document
with a custom page size (matching the requested size of the chart). You can easily adapt the code
to use a different page size, alter the size and position of the chart and even draw multiple charts
inside one PDF document.
Now that I have a method to send PDF data to an output stream, it is straightforward to implement the saveChartAsPDF() method. Simply create a FileOutputStream and pass it on to the
writeChartAsPDF() method:
public static void saveChartAsPDF(File file,
JFreeChart chart,
int width,
int height,
FontMapper mapper) throws IOException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
writeChartAsPDF(out, chart, width, height, mapper);
out.close();
}
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
106
This is all the code that is required. The pieces can be assembled into the following program
(reproduced in full here so that you can see all the required import statements and the context in
which the code is run):
/* ------------------* PDFExportDemo1.java
* ------------------* (C) Copyright 2002-2005, by Object Refinery Limited.
*
*/
package demo.pdf;
import
import
import
import
import
import
import
import
java.awt.Graphics2D;
java.awt.geom.Rectangle2D;
java.io.BufferedOutputStream;
java.io.File;
java.io.FileOutputStream;
java.io.IOException;
java.io.OutputStream;
java.text.SimpleDateFormat;
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.DateAxis;
org.jfree.chart.plot.XYPlot;
org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
org.jfree.data.time.Month;
org.jfree.data.time.TimeSeries;
org.jfree.data.time.TimeSeriesCollection;
org.jfree.data.xy.XYDataset;
import
import
import
import
import
import
import
import
com.lowagie.text.Document;
com.lowagie.text.DocumentException;
com.lowagie.text.Rectangle;
com.lowagie.text.pdf.DefaultFontMapper;
com.lowagie.text.pdf.FontMapper;
com.lowagie.text.pdf.PdfContentByte;
com.lowagie.text.pdf.PdfTemplate;
com.lowagie.text.pdf.PdfWriter;
/**
* A simple demonstration showing how to write a chart to PDF format using
* JFreeChart and iText.
*
* You can download iText from http://www.lowagie.com/iText.
*/
public class PDFExportDemo1 {
/**
* Saves a chart to a PDF file.
*
* @param file the file.
* @param chart the chart.
* @param width the chart width.
* @param height the chart height.
*/
public static void saveChartAsPDF(File file,
JFreeChart chart,
int width,
int height,
FontMapper mapper) throws IOException {
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
writeChartAsPDF(out, chart, width, height, mapper);
out.close();
}
/**
* Writes a chart to an output stream in PDF format.
*
* @param out the output stream.
* @param chart the chart.
* @param width the chart width.
* @param height the chart height.
*
*/
public static void writeChartAsPDF(OutputStream out,
JFreeChart chart,
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
int width,
int height,
FontMapper mapper) throws IOException {
Rectangle pagesize = new Rectangle(width, height);
Document document = new Document(pagesize, 50, 50, 50, 50);
try {
PdfWriter writer = PdfWriter.getInstance(document, out);
document.addAuthor("JFreeChart");
document.addSubject("Demonstration");
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfTemplate tp = cb.createTemplate(width, height);
Graphics2D g2 = tp.createGraphics(width, height, mapper);
Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
chart.draw(g2, r2D);
g2.dispose();
cb.addTemplate(tp, 0, 0);
}
catch (DocumentException de) {
System.err.println(de.getMessage());
}
document.close();
}
/**
* Creates a dataset, consisting of two series of monthly data. * *
*
* @return the dataset.
*/
public static XYDataset createDataset() {
TimeSeries
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1.add(new
s1 = new TimeSeries("L&G European Index Trust", Month.class);
Month(2, 2001), 181.8);
Month(3, 2001), 167.3);
Month(4, 2001), 153.8);
Month(5, 2001), 167.6);
Month(6, 2001), 158.8);
Month(7, 2001), 148.3);
Month(8, 2001), 153.9);
Month(9, 2001), 142.7);
Month(10, 2001), 123.2);
Month(11, 2001), 131.8);
Month(12, 2001), 139.6);
Month(1, 2002), 142.9);
Month(2, 2002), 138.7);
Month(3, 2002), 137.3);
Month(4, 2002), 143.9);
Month(5, 2002), 139.8);
Month(6, 2002), 137.0);
Month(7, 2002), 132.8);
TimeSeries
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2.add(new
s2 = new TimeSeries("L&G UK Index Trust", Month.class);
Month(2, 2001), 129.6);
Month(3, 2001), 123.2);
Month(4, 2001), 117.2);
Month(5, 2001), 124.1);
Month(6, 2001), 122.6);
Month(7, 2001), 119.2);
Month(8, 2001), 116.5);
Month(9, 2001), 112.7);
Month(10, 2001), 101.5);
Month(11, 2001), 106.1);
Month(12, 2001), 110.3);
Month(1, 2002), 111.7);
Month(2, 2002), 111.0);
Month(3, 2002), 109.6);
Month(4, 2002), 113.2);
Month(5, 2002), 111.6);
Month(6, 2002), 108.8);
Month(7, 2002), 101.6);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(s1);
dataset.addSeries(s2);
return dataset;
}
public static void main(String[] args) {
try {
107
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
108
// create a chart...
XYDataset dataset = createDataset();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Legal & General Unit Trust Prices",
"Date",
"Price Per Unit",
dataset,
true,
true,
false
);
// some additional chart customisation here...
XYPlot plot = chart.getXYPlot();
XYLineAndShapeRenderer renderer
= (XYLineAndShapeRenderer) plot.getRenderer();
renderer.setShapesVisible(true);
DateAxis axis = (DateAxis) plot.getDomainAxis();
axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));
// write the chart to a PDF file...
File fileName = new File(System.getProperty("user.home")
+ "/jfreechart1.pdf");
saveChartAsPDF(fileName, chart, 400, 300, new DefaultFontMapper());
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
Before you compile and run the application, remember to change the file name used for the PDF
file to something appropriate for your system! And include the jar files listed in section 16.5 on
your classpath.
16.7
Viewing the PDF File
After compiling and running the sample application, you can view the resulting PDF file using a
PDF viewer like Acrobat Reader (or, in my case, Gnome PDF Viewer):
Most PDF viewer applications provide zooming features that allow you to get a close up view of
your charts.
16.8
Unicode Characters
It is possible to use the full range of Unicode characters in JFreeChart and iText, as long as you
are careful about which fonts you use. In this section, I present some modifications to the previous
example to show how to do this.
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
16.8.1
109
Background
Internally, Java uses the Unicode character encoding to represent text strings. This encoding uses
sixteen bits per character, which means there are potentially 65,536 different characters available
(the Unicode standard defines something like 38,000 characters).
You can use any of these characters in both JFreeChart and iText, subject to one proviso: the font
you use to display the text must define the characters used or you will not be able to see them.
Many fonts are not designed to display the entire Unicode character set. The following website
contains useful information about fonts that do support Unicode (at least to some extent):
http://www.slovo.info/unifonts.htm
I have tried out the tahoma.ttf font with success. In fact, I will use this font in the example
that follows. The Tahoma font doesn’t support every character defined in Unicode, so if you have
specific requirements then you need to choose an appropriate font. At one point I had the Arial
Unicode MS font (arialuni.ttf) installed on my system—this has support for the full Unicode
character set, although this means that the font definition file is quite large (around 24 megabytes!)
16.8.2
Fonts, iText and Java
iText has to handle fonts according to the PDF specification. This deals with document portability
by allowing fonts to be (optionally) embedded in a PDF file. This requires access to the font
definition file.
Java, on the other hand, abstracts away some of the details of particular font formats with the use
of the Font class.
To support the Graphics2D implementation in iText, it is necessary to map Font objects from Java
to BaseFont objects in iText. This is the role of the FontMapper interface.
If you create a new DefaultFontMapper instance using the default constructor, it will already
contain sensible mappings for the logical fonts defined by the Java specification. But if you want
to use additional fonts—and you must if you want to use a wide range of Unicode characters—then
you need to add extra mappings to the DefaultFontMapper object.
16.8.3
Mapping Additional Fonts
I’ve decided to use the Tahoma font to display a chart title that incorporates some Unicode characters. The font definition file (tahoma.ttf) is located, on my system, in the directory:
/opt/sun-jdk-1.4.2.08/jre/lib/fonts
Here’s the code used to create the FontMapper for use by iText—I’ve based this on an example
written by Paulo Soares:
DefaultFontMapper mapper = new DefaultFontMapper();
mapper.insertDirectory("/opt/sun-jdk-1.4.2.08/jre/lib/fonts");
DefaultFontMapper.BaseFontParameters pp =
mapper.getBaseFontParameters("Tahoma");
if (pp!=null) {
pp.encoding = BaseFont.IDENTITY_H;
}
Now I can modify the code that creates the chart, in order to add a custom title to the chart (I’ve
changed the data and chart type also):
// create a chart...
TimeSeries series = new TimeSeries("Random Data");
Day current = new Day(1, 1, 2000);
double value = 100.0;
for (int i = 0; i < 1000; i++) {
try {
value = value + Math.random() - 0.5;
CHAPTER 16. EXPORTING CHARTS TO ACROBAT PDF
110
series.add(current, new Double(value));
current = (Day) current.next();
}
catch (SeriesException e) {
System.err.println("Error adding to series");
}
}
XYDataset data = new TimeSeriesCollection(series);
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Test",
"Date",
"Value",
data,
true,
false,
false
);
// Unicode test...
String text = "\u278A\u20A0\u20A1\u20A2\u20A3\u20A4\u20A5\u20A6\u20A7\u20A8\u20A9";
//String text = "hi";
Font font = new Font("Tahoma", Font.PLAIN, 12);
TextTitle subtitle = new TextTitle(text, font);
chart.addSubtitle(subtitle);
Notice that the subtitle (a random collection of currency symbols) is defined using escape sequences
to specify each Unicode character. This avoids any problems with encoding conversions when I save
the Java source file.
The output from the modified sample program is shown in figure 16.2. The example has been
embedded in this document in PDF format, so it is a good example of the type of output you can
expect by following the instructions in this document.
Test
102.5
100.0
Value
97.5
95.0
92.5
90.0
87.5
85.0
Jan-2000
Jul-2000
Jan-2001
Jul-2001
Jan-2002
Date
Random Data
Figure 16.2: A Unicode subtitle
Jul-2002
Chapter 17
Exporting Charts to SVG Format
17.1
Introduction
In this section, I present an example that shows how to export charts to SVG format, using
JFreeChart and Batik (an open source library for working with SVG).
17.2
Background
17.2.1
What is SVG?
Scalable Vector Graphics (SVG) is a standard language for describing two-dimensional graphics in
XML format. It is a Recommendation of the World Wide Web Consortium (W3C).
17.2.2
Batik
Batik is an open source toolkit, written in Java, that allows you to generate SVG content. Batik is
available from:
http://xml.apache.org/batik
At the time of writing, the latest stable version of Batik is 1.6.
17.3
A Sample Application
17.3.1
JFreeChart and Batik
JFreeChart and Batik can work together relatively easily because:
• JFreeChart draws all chart output using Java’s Graphics2D abstraction; and
• Batik provides a concrete implementation of Graphics2D that generates SVG output (SVGGraphics2D).
In this section, a simple example is presented to get you started using JFreeChart and Batik. The
example is based on the technique described here:
http://xml.apache.org/batik/svggen.html
111
CHAPTER 17. EXPORTING CHARTS TO SVG FORMAT
17.3.2
112
Getting Started
First, you should download Batik and install it according to the instructions provided on the Batik
web page.
To compile and run the sample program presented in the next section, you need to ensure that the
following jar files are on your classpath:
File:
Description:
jcommon-1.0.12.jar
jfreechart-1.0.9.jar
batik-awt-util.jar
batik-dom.jar
batik-svggen.jar
batik-util.jar
Common classes from JFree.
The JFreeChart class library.
Batik runtime files.
Batik runtime files.
Batik runtime files.
Batik runtime files.
17.3.3
The Application
Create a project in your favourite Java development environment, add the libraries listed in the
previous section, and type in the following program (or easier, grab a copy of the source from the
JFreeChart demo collection):
/* -----------------* SVGExportDemo.java
* -----------------* (C) Copyright 2002-2005, by Object Refinery Limited.
*
*/
package demo.svg;
import
import
import
import
import
import
java.awt.geom.Rectangle2D;
java.io.File;
java.io.FileOutputStream;
java.io.IOException;
java.io.OutputStreamWriter;
java.io.Writer;
import
import
import
import
import
import
import
org.apache.batik.dom.GenericDOMImplementation;
org.apache.batik.svggen.SVGGraphics2D;
org.jfree.chart.ChartFactory;
org.jfree.chart.JFreeChart;
org.jfree.data.general.DefaultPieDataset;
org.w3c.dom.DOMImplementation;
org.w3c.dom.Document;
/**
* A demonstration showing the export of a chart to SVG format.
*/
public class SVGExportDemo {
/**
* Starting point for the demo.
*
* @param args ignored.
*/
public static void main(String[] args) throws IOException {
// create a dataset...
DefaultPieDataset data = new DefaultPieDataset();
data.setValue("Category 1", new Double(43.2));
data.setValue("Category 2", new Double(27.9));
data.setValue("Category 3", new Double(79.5));
// create a chart
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
data,
true,
false,
false
);
// THE FOLLOWING CODE BASED ON THE EXAMPLE IN THE BATIK DOCUMENTATION...
// Get a DOMImplementation
CHAPTER 17. EXPORTING CHARTS TO SVG FORMAT
113
DOMImplementation domImpl
= GenericDOMImplementation.getDOMImplementation();
// Create an instance of org.w3c.dom.Document
Document document = domImpl.createDocument(null, "svg", null);
// Create an instance of the SVG Generator
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
// set the precision to avoid a null pointer exception in Batik 1.5
svgGenerator.getGeneratorContext().setPrecision(6);
// Ask the chart to render into the SVG Graphics2D implementation
chart.draw(svgGenerator, new Rectangle2D.Double(0, 0, 400, 300), null);
// Finally, stream out SVG to a file using UTF-8 character to
// byte encoding
boolean useCSS = true;
Writer out = new OutputStreamWriter(
new FileOutputStream(new File("test.svg")), "UTF-8");
svgGenerator.stream(out, useCSS);
}
}
Running this program creates a file test.svg in SVG format.
17.3.4
Viewing the SVG
Batik includes a viewer application (“Squiggle”) which you can use to open and view the SVG file.
The Batik download includes instructions for running the viewer, effectively all you require is:
java -jar batik-squiggle.jar
The following screen shot shows the pie chart that we created earlier, displayed using the browser
application. A transformation (rotation) has been applied to the chart from within the browser:
If you play about with the viewer, zooming in and out and applying various transformations to the
chart, you will begin to appreciate the power of the SVG format.
Chapter 18
Applets
18.1
Introduction
Subject to a couple of provisos, using JFreeChart in an applet is relatively straightforward. This
section provides a brief overview of the important issues and describes a working example that
should be sufficient to get you started.
Figure 18.1: An applet using JFreeChart
Figure 18.1 shows a sample applet that uses JFreeChart. This applet is available online at:
http://www.object-refinery.com/jfreechart/applet.html
The source code for this applet appears later in this section.
18.2
Issues
The main issues to consider when developing applets (whether with or without JFreeChart) are:
• browser support;
• security restrictions;
• code size.
Be sure that you understand these issues before you commit significant resources to writing applets.
114
CHAPTER 18. APPLETS
18.2.1
115
Browser Support
The vast majority of web browsers provide support for the latest version of Java (JDK 1.5.0) and
will therefore have no problems running applets that use JFreeChart (recall that JFreeChart will
run on any version of the JDK from 1.3.1 onwards).
However, the vast majority of users on the web use (by default in most cases) the one web browser—
Microsoft Internet Explorer (MSIE)—that only supports a version of Java (JDK 1.1) that is now
hopelessly out-of-date. This is a problem, because applets that use JFreeChart will not work on
a default installation of MSIE. There is a workaround—users can download and install Sun’s Java
plugin—but, like many workarounds, it is too much effort and inconvenience for many people. The
end result is a deployment problem for developers who choose to write applets.
This single issue has caused many developers to abandon their plans to develop applets1 and instead
choose an easier-to-deploy technology such as Java Servlets (see the next chapter).
18.2.2
Security
Applets (and Java more generally) have been designed with security in mind. When an applet runs
in your web browser, it is restricted in the operations that it is permitted to perform. For example,
an applet typically will not be allowed to read or write to the local filesystem. Describing the details
of Java’s security mechanism is beyond the scope of this text, but you should be aware that some
functions provided by JFreeChart (for example, the option to save charts to PNG format via the
pop-up menu) will not work in applets that are subject to the default security policy. If you need
these functions to work, then you will need to study Java’s security mechanism in more detail.
18.2.3
Code Size
A final issue to consider is the size of the “runtime” code required for your applet. Before an applet
can run, the code (typically packed into jar files) has to be downloaded to the end user’s computer.
Clearly, for users with limited bandwidth connections, the size of the code can be an issue.
The JFreeChart code is distributed in a jar file that is around 1,000KB in size. That isn’t large—
especially when you consider the number and variety of charts that JFreeChart supports—but, at
the same time, it isn’t exactly optimal for a user on a dial-up modem connection. And you need to
add to that the JCommon jar file (around 290KB) plus whatever code you have for your applet.
As always with JFreeChart, you have the source code so you could improve this by repackaging the
JFreeChart jar file to include only those classes that are used by your applet (directly or indirectly).
18.3
A Sample Applet
As mentioned in the introduction, a sample applet that uses JFreeChart can be seen at the following
URL:2
http://www.object-refinery.com/jfreechart/applet.html
Two aspects of the sample applet are interesting, the source code that is used to create the applet
and the HTML file that is used to invoke the applet.
1 For some people this issue won’t be a concern. For example, you may be developing applets for internal corporate
use, and your standard desktop configuration includes a browser that supports JDK 1.5.0. Alternatively, you may
be providing an applet for public use via the World Wide Web, but it is not critical that every user be able to run
the applet.
2 If the applet does not work for you, please check that your web browser is configured correctly and supports
JDK 1.3.1 or later.
CHAPTER 18. APPLETS
18.3.1
116
The HTML
The HTML used to invoke the applet is important, since it needs to reference the necessary jar
files. The HTML applet tag used is:
Notice that three jar files are referenced. The first contains the applet class (source code in the
next section) only, while the remaining two jar files are the standard JFreeChart and JCommon
class libraries (the version numbers reflect the age of the demo rather than the current releases).
You can place the applet tag anywhere in your HTML file that you might place some other element
(such as an image).
18.3.2
The Source Code
The sample applet is created using the following source code (which is included in the “support
demos” package). There is very little applet-specific code here—we just extend JApplet:
/* -----------* Applet1.java
* -----------* (C) Copyright 2002-2005, by Object Refinery Limited.
*/
package demo.applet;
import
import
import
import
java.awt.BasicStroke;
java.awt.Color;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.Timer;
import
import
import
import
import
import
import
import
import
import
org.jfree.chart.ChartPanel;
org.jfree.chart.JFreeChart;
org.jfree.chart.axis.DateAxis;
org.jfree.chart.axis.NumberAxis;
org.jfree.chart.plot.XYPlot;
org.jfree.chart.renderer.xy.XYItemRenderer;
org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
org.jfree.data.time.Millisecond;
org.jfree.data.time.TimeSeries;
org.jfree.data.time.TimeSeriesCollection;
/**
* A simple applet demo.
*/
public class Applet1 extends JApplet {
/** Time series for total memory used. */
private TimeSeries total;
/** Time series for free memory. */
private TimeSeries free;
/**
* Creates a new instance.
*/
public Applet1() {
// create two series that automatically discard data more than
// 30 seconds old...
this.total = new TimeSeries("Total", Millisecond.class);
this.total.setMaximumItemAge(30000);
this.free = new TimeSeries("Free", Millisecond.class);
this.free.setMaximumItemAge(30000);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(total);
dataset.addSeries(free);
CHAPTER 18. APPLETS
DateAxis domain = new DateAxis("Time");
NumberAxis range = new NumberAxis("Memory");
XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
XYPlot plot = new XYPlot(dataset, domain, range, renderer);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
renderer.setSeriesPaint(0, Color.red);
renderer.setSeriesPaint(1, Color.green);
renderer.setSeriesStroke(0, new BasicStroke(1.5f));
renderer.setSeriesStroke(1, new BasicStroke(1.5f));
domain.setAutoRange(true);
domain.setLowerMargin(0.0);
domain.setUpperMargin(0.0);
domain.setTickLabelsVisible(true);
range.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
JFreeChart chart = new JFreeChart(
"Memory Usage", JFreeChart.DEFAULT_TITLE_FONT, plot, true
);
chart.setBackgroundPaint(Color.white);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPopupMenu(null);
getContentPane().add(chartPanel);
new Applet1.DataGenerator().start();
}
/**
* Adds an observation to the ’total memory’ time series.
*
* @param y the total memory used.
*/
private void addTotalObservation(double y) {
total.add(new Millisecond(), y);
}
/**
* Adds an observation to the ’free memory’ time series.
*
* @param y the free memory.
*/
private void addFreeObservation(double y) {
free.add(new Millisecond(), y);
}
/**
* The data generator.
*/
class DataGenerator extends Timer implements ActionListener {
/**
* Constructor.
*/
DataGenerator() {
super(100, null);
addActionListener(this);
}
/**
* Adds a new free/total memory reading to the dataset.
*
* @param event the action event.
*/
public void actionPerformed(ActionEvent event) {
long f = Runtime.getRuntime().freeMemory();
long t = Runtime.getRuntime().totalMemory();
addTotalObservation(t);
addFreeObservation(f);
}
}
}
117
Chapter 19
Servlets
19.1
Introduction
The Java Servlets API is a popular technology for creating web applications. JFreeChart is well
suited for use in a servlet environment and, in this section, some examples are presented to help
those developers that are interested in using JFreeChart for web applications.
All the sample code in this section is available for download from:
http://www.object-refinery.com/jfreechart/premium/index.html
The file to download is jfreechart-1.0.9-demo.zip.1
19.2
A Simple Servlet
The ServletDemo1 class implements a very simple servlet that returns a PNG image of a bar chart
generated using JFreeChart. When it is run, the servlet will return a raw image to the client (web
browser) which will display the image without any surrounding HTML—see figure 19.1. Typically,
Figure 19.1: ServletDemo1 in a browser
you will not present raw output in this way, so this servlet is not especially useful on its own, but
the example is:
1 To access this page you need to enter the username and password provided to you in the confirmation e-mail you
received when you purchased the JFreeChart Developer Guide.
118
CHAPTER 19. SERVLETS
119
• a good illustration of the request-response nature of servlets;
• useful as a test case if you are configuring a server environment and want to check that
everything is working.
We will move on to a more complex example later, showing how to request different charts using
HTML forms, and embedding the generated charts within HTML output.
Here is the code for the basic servlet:
/* ----------------* ServletDemo1.java
* ----------------* (C) Copyright 2002-2004, by Object Refinery Limited.
*
*/
package demo;
import java.io.IOException;
import java.io.OutputStream;
import
import
import
import
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
import
import
import
import
import
org.jfree.chart.ChartFactory;
org.jfree.chart.ChartUtilities;
org.jfree.chart.JFreeChart;
org.jfree.chart.plot.PlotOrientation;
org.jfree.data.category.DefaultCategoryDataset;
/**
* A basic servlet that returns a PNG image file generated by JFreeChart.
* This class is described in the JFreeChart Developer Guide in the
* "Servlets" chapter.
*/
public class ServletDemo1 extends HttpServlet {
/**
* Creates a new demo.
*/
public ServletDemo1() {
// nothing required
}
/**
* Processes a GET request.
*
* @param request the request.
* @param response the response.
*
* @throws ServletException if there is a servlet related problem.
* @throws IOException if there is an I/O problem.
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OutputStream out = response.getOutputStream();
try {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(10.0, "S1", "C1");
dataset.addValue(4.0, "S1", "C2");
dataset.addValue(15.0, "S1", "C3");
dataset.addValue(14.0, "S1", "C4");
dataset.addValue(-5.0, "S2", "C1");
dataset.addValue(-7.0, "S2", "C2");
dataset.addValue(14.0, "S2", "C3");
dataset.addValue(-3.0, "S2", "C4");
dataset.addValue(6.0, "S3", "C1");
dataset.addValue(17.0, "S3", "C2");
dataset.addValue(-12.0, "S3", "C3");
dataset.addValue( 7.0, "S3", "C4");
dataset.addValue(7.0, "S4", "C1");
dataset.addValue(15.0, "S4", "C2");
dataset.addValue(11.0, "S4", "C3");
dataset.addValue(0.0, "S4", "C4");
dataset.addValue(-8.0, "S5", "C1");
CHAPTER 19. SERVLETS
120
dataset.addValue(-6.0, "S5", "C2");
dataset.addValue(10.0, "S5", "C3");
dataset.addValue(-9.0, "S5", "C4");
dataset.addValue(9.0, "S6", "C1");
dataset.addValue(8.0, "S6", "C2");
dataset.addValue(null, "S6", "C3");
dataset.addValue(6.0, "S6", "C4");
dataset.addValue(-10.0, "S7", "C1");
dataset.addValue(9.0, "S7", "C2");
dataset.addValue(7.0, "S7", "C3");
dataset.addValue(7.0, "S7", "C4");
dataset.addValue(11.0, "S8", "C1");
dataset.addValue(13.0, "S8", "C2");
dataset.addValue(9.0, "S8", "C3");
dataset.addValue(9.0, "S8", "C4");
dataset.addValue(-3.0, "S9", "C1");
dataset.addValue(7.0, "S9", "C2");
dataset.addValue(11.0, "S9", "C3");
dataset.addValue(-10.0, "S9", "C4");
JFreeChart chart = ChartFactory.createBarChart(
"Bar Chart",
"Category",
"Value",
dataset,
PlotOrientation.VERTICAL,
true, true, false
);
response.setContentType("image/png");
ChartUtilities.writeChartAsPNG(out, chart, 400, 300);
}
catch (Exception e) {
System.err.println(e.toString());
}
finally {
out.close();
}
}
}
The doGet() method is called by the servlet engine when a request is made by a client (usually a
web browser). In response to the request, the servlet performs several steps:
• an OutputStream reference is obtained for returning output to the client;
• a chart is created;
• the content type for the response is set to image/png. This tells the client what type of data
it is receiving;
• a PNG image of the chart is written to the output stream;
• the output stream is closed.
19.3
Compiling the Servlet
Note that the classes in the javax.servlet.* package (and sub-packages), used by the demo servlet,
are not part of the Java 2 Standard Edition (J2SE). In order to compile the above code using J2SE,
you will need to obtain a servlet.jar file. I’ve used the one that is redistributed with Tomcat (an
open source servlet engine written using Java). You can find out more about Tomcat at:
http://tomcat.apache.org/
You will also require the JFreeChart and JCommon jar files to compile the above servlet. Change
your working directory to jfreechart-1.0.9-demo, then enter the following command (on Windows,
you need to change the colons to semi-colons, and the forward slashes to backward slashes):
javac -classpath jfreechart-1.0.9.jar:lib/jcommon-1.0.12.jar:lib/servlet.jar
source/demo/ServletDemo1.java
CHAPTER 19. SERVLETS
121
This should create a ServletDemo1.class file. The next section describes how to deploy this servlet
using Tomcat.
19.4
Deploying the Servlet
Servlets are deployed in the webapps directory provided by your servlet engine. In my case, I am
using Tomcat 5.5.15 on Ubuntu Linux 5.10, and the directory is:2
/home/dgilbert/apache-tomcat-5.5.15/webapps
Within the webapps directory, create a jfreechart1 directory to hold the first servlet demo, then
create the following structure within the directory:
.../jfreechart1/WEB-INF/web.xml
.../jfreechart1/WEB-INF/lib/jfreechart-1.0.9.jar
.../jfreechart1/WEB-INF/lib/jcommon-1.0.12.jar
.../jfreechart1/WEB-INF/classes/demo/ServletDemo1.class
You need to create the web.xml file—it provides information about the servlet:
ServletDemo1
demo.ServletDemo1
ServletDemo1
/servlet/ServletDemo1
Once you have all these files in place, restart your servlet engine and type in the following URL
using your favourite web browser:
http://localhost:8080/jfreechart1/servlet/ServletDemo1
If all is well, you will see the chart image displayed in your browser, as shown in figure 19.1.
19.5
Embedding Charts in HTML Pages
It is possible to embed a chart image generated by a servlet inside an HTML page (that is generated by another servlet). This is demonstrated by ServletDemo2, which is also available in the
jfreechart-1.0.9-demo.zip file.
ServletDemo2 processes a request by returning a page of HTML that, in turn, references another
servlet (ServletDemo2ChartGenerator) that returns a PNG image of a chart. The end result is a
chart embedded in an HTML page, as shown in figure 19.2.
Here is the code for ServletDemo2:
2 Servlets are portable between different servlet engines, so if you are using a different servlet engine, consult the
documentation to find the location of the webapps folder.
CHAPTER 19. SERVLETS
122
Figure 19.2: ServletDemo2 in a browser
/* ----------------* ServletDemo2.java
* ----------------* (C) Copyright 2002-2004, by Object Refinery Limited.
*
*/
package demo;
import java.io.IOException;
import java.io.PrintWriter;
import
import
import
import
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
/**
* A basic servlet that generates an HTML page that displays a chart generated by
* JFreeChart.
*
* This servlet uses another servlet (ServletDemo2ChartGenerator) to create a PNG image
* for the embedded chart.
*
* This class is described in the JFreeChart Developer Guide.
*/
public class ServletDemo2 extends HttpServlet {
/**
* Creates a new servlet demo.
*/
public ServletDemo2() {
// nothing required
}
/**
* Processes a POST request.
*
* The chart.html page contains a form for generating the first request, after that
* the HTML returned by this servlet contains the same form for generating subsequent
* requests.
*
* @param request the request.
* @param response the response.
*
* @throws ServletException if there is a servlet related problem.
* @throws IOException if there is an I/O problem.
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
CHAPTER 19. SERVLETS
123
throws ServletException, IOException {
PrintWriter out = new PrintWriter(response.getWriter());
try {
String param = request.getParameter("chart");
response.setContentType("text/html");
out.println("");
out.println("
");
out.println("JFreeChart Servlet Demo 2 ");
out.println("");
out.println("");
out.println("JFreeChart Servlet Demo
");
out.println("");
out.println("Please choose a chart type:");
out.println("
");
out.println("");
out.println("");
out.println("");
out.println("");
out.flush();
out.close();
}
catch (Exception e) {
System.err.println(e.toString());
}
finally {
out.close();
}
}
}
Notice how this code gets a reference to a Writer from the response parameter, rather than an
OutputStream as in the previous example. The reason for this is because this servlet will be returning
text (HTML), compared to the previous servlet which returned binary data (a PNG image).3
The response type is set to text/html since this servlet returns HTML text. An important point to
note is that the
tag in the HTML references another servlet (ServletDemo2ChartGenerator),
and this other servlet creates the required chart image. The actual chart returned is controlled by
the chart parameter, which is set up in the HTML using a