KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > StackedAreaRenderer


1 /* ======================================
2  * JFreeChart : a free Java chart library
3  * ======================================
4  *
5  * Project Info: http://www.jfree.org/jfreechart/index.html
6  * Project Lead: David Gilbert (david.gilbert@object-refinery.com);
7  *
8  * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
9  *
10  * This library is free software; you can redistribute it and/or modify it under the terms
11  * of the GNU Lesser General Public License as published by the Free Software Foundation;
12  * either version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with this
19  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * ------------------------
23  * StackedAreaRenderer.java
24  * ------------------------
25  * (C) Copyright 2002, 2003 by Dan Rivett (d.rivett@ukonline.co.uk) and Contributors.
26  *
27  * Original Author: Dan Rivett (adapted from AreaCategoryItemRenderer);
28  * Contributor(s): Jon Iles;
29  * David Gilbert (for Object Refinery Limited);
30  * Christian W. Zuckschwerdt;
31  *
32  * $Id: StackedAreaRenderer.java,v 1.20 2003/11/03 14:21:28 mungady Exp $
33  *
34  * Changes:
35  * --------
36  * 20-Sep-2002 : Version 1, contributed by Dan Rivett;
37  * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and CategoryToolTipGenerator
38  * interface (DG);
39  * 01-Nov-2002 : Added tooltips (DG);
40  * 06-Nov-2002 : Renamed drawCategoryItem(...) --> drawItem(...) and now using axis for
41  * category spacing.
42  * Renamed StackedAreaCategoryItemRenderer --> StackedAreaRenderer (DG);
43  * 26-Nov-2002 : Switched CategoryDataset --> TableDataset (DG);
44  * 26-Nov-2002 : Replaced isStacked() method with getRangeType() method (DG);
45  * 17-Jan-2003 : Moved plot classes to a separate package (DG);
46  * 25-Mar-2003 : Implemented Serializable (DG);
47  * 13-May-2003 : Modified to take into account the plot orientation (DG);
48  * 30-Jul-2003 : Modified entity constructor (CZ);
49  * 07-Oct-2003 : Added renderer state (DG);
50  *
51  */

52
53 package org.jfree.chart.renderer;
54
55 import java.awt.Graphics2D JavaDoc;
56 import java.awt.Polygon JavaDoc;
57 import java.awt.Shape JavaDoc;
58 import java.awt.geom.Rectangle2D JavaDoc;
59 import java.io.Serializable JavaDoc;
60
61 import org.jfree.chart.axis.CategoryAxis;
62 import org.jfree.chart.axis.ValueAxis;
63 import org.jfree.chart.entity.CategoryItemEntity;
64 import org.jfree.chart.entity.EntityCollection;
65 import org.jfree.chart.labels.CategoryItemLabelGenerator;
66 import org.jfree.chart.plot.CategoryPlot;
67 import org.jfree.chart.plot.PlotOrientation;
68 import org.jfree.data.CategoryDataset;
69 import org.jfree.ui.RectangleEdge;
70 import org.jfree.util.PublicCloneable;
71
72 /**
73  * A renderer that draws stacked area charts for a {@link org.jfree.chart.plot.CategoryPlot}.
74  *
75  * @author Dan Rivett
76  */

77 public class StackedAreaRenderer extends AreaRenderer
78                                  implements Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
79
80     /**
81      * Creates a new renderer.
82      */

83     public StackedAreaRenderer() {
84         super();
85     }
86
87     /**
88      * Returns the range type.
89      *
90      * @return the range type.
91      */

92     public RangeType getRangeType() {
93         return RangeType.STACKED;
94     }
95
96     /**
97      * Draw a single data item.
98      *
99      * @param g2 the graphics device.
100      * @param state the renderer state.
101      * @param dataArea the data plot area.
102      * @param plot the plot.
103      * @param domainAxis the domain axis.
104      * @param rangeAxis the range axis.
105      * @param dataset the data.
106      * @param row the row index (zero-based).
107      * @param column the column index (zero-based).
108      */

109     public void drawItem(Graphics2D JavaDoc g2,
110                          CategoryItemRendererState state,
111                          Rectangle2D JavaDoc dataArea,
112                          CategoryPlot plot,
113                          CategoryAxis domainAxis,
114                          ValueAxis rangeAxis,
115                          CategoryDataset dataset,
116                          int row,
117                          int column) {
118
119         // plot non-null values...
120
Number JavaDoc value = dataset.getValue(row, column);
121         if (value == null) {
122             return;
123         }
124
125         // leave the y values (y1, y0) untranslated as it is going to be be stacked
126
// up later by previous series values, after this it will be translated.
127
double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea,
128                                                  plot.getDomainAxisEdge());
129         double y1 = 0.0; // calculate later
130
double y1Untranslated = value.doubleValue();
131
132         g2.setPaint(getItemPaint(row, column));
133         g2.setStroke(getItemStroke(row, column));
134
135         if (column != 0) {
136
137             Number JavaDoc previousValue = dataset.getValue(row, column - 1);
138             if (previousValue != null) {
139
140                 double x0 = domainAxis.getCategoryMiddle(column - 1,
141                                                          getColumnCount(), dataArea,
142                                                          plot.getDomainAxisEdge());
143                 double y0Untranslated = previousValue.doubleValue();
144
145                 // Get the previous height, but this will be different for both y0 and y1 as
146
// the previous series values could differ.
147
double previousHeightx0Untranslated = getPreviousHeight(dataset, row, column - 1);
148                 double previousHeightx1Untranslated = getPreviousHeight(dataset, row, column);
149
150                 // Now stack the current y values on top of the previous values.
151
y0Untranslated += previousHeightx0Untranslated;
152                 y1Untranslated += previousHeightx1Untranslated;
153
154                 // Now translate the previous heights
155
RectangleEdge location = plot.getRangeAxisEdge();
156                 double previousHeightx0
157                     = rangeAxis.translateValueToJava2D(previousHeightx0Untranslated, dataArea,
158                                                        location);
159                 double previousHeightx1
160                     = rangeAxis.translateValueToJava2D(previousHeightx1Untranslated, dataArea,
161                                                        location);
162
163                 // Now translate the current y values.
164
double y0 = rangeAxis.translateValueToJava2D(y0Untranslated, dataArea, location);
165                 y1 = rangeAxis.translateValueToJava2D(y1Untranslated, dataArea, location);
166
167                 Polygon JavaDoc p = null;
168                 PlotOrientation orientation = plot.getOrientation();
169                 if (orientation == PlotOrientation.HORIZONTAL) {
170                     p = new Polygon JavaDoc();
171                     p.addPoint((int) y0, (int) x0);
172                     p.addPoint((int) y1, (int) x1);
173                     p.addPoint((int) previousHeightx1, (int) x1);
174                     p.addPoint((int) previousHeightx0, (int) x0);
175                 }
176                 else if (orientation == PlotOrientation.VERTICAL) {
177                     p = new Polygon JavaDoc();
178                     p.addPoint((int) x0, (int) y0);
179                     p.addPoint((int) x1, (int) y1);
180                     p.addPoint((int) x1, (int) previousHeightx1);
181                     p.addPoint((int) x0, (int) previousHeightx0);
182                 }
183                 g2.setPaint(getItemPaint(row, column));
184                 g2.setStroke(getItemStroke(row, column));
185                 g2.fill(p);
186             }
187
188         }
189
190         // collect entity and tool tip information...
191
if (state.getInfo() != null) {
192             EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
193             Shape JavaDoc shape = new Rectangle2D.Double JavaDoc(x1 - 3.0, y1 - 3.0, 6.0, 6.0);
194             if (entities != null && shape != null) {
195                 String JavaDoc tip = null;
196                 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
197                 if (generator != null) {
198                     tip = generator.generateToolTip(dataset, row, column);
199                 }
200                 String JavaDoc url = null;
201                 if (getItemURLGenerator(row, column) != null) {
202                     url = getItemURLGenerator(row, column).generateURL(dataset, row, column);
203                 }
204                 CategoryItemEntity entity = new CategoryItemEntity(
205                     shape, tip, url, dataset, row, dataset.getColumnKey(column), column
206                 );
207                 entities.addEntity(entity);
208             }
209         }
210
211     }
212
213     /**
214      * Calculates the stacked value of the all series up to, but not including <code>series</code>
215      * for the specified category, <code>category</code>. It returns 0.0 if <code>series</code>
216      * is the first series, i.e. 0.
217      *
218      * @param data the data.
219      * @param series the series.
220      * @param category the category.
221      *
222      * @return double returns a cumulative value for all series' values up to but excluding
223      * <code>series</code> for Object <code>category</code>.
224      */

225     protected double getPreviousHeight(CategoryDataset data, int series, int category) {
226
227         double result = 0.0;
228
229         Number JavaDoc tmp;
230         for (int i = 0; i < series; i++) {
231             tmp = data.getValue(i, category);
232             if (tmp != null) {
233                 result += tmp.doubleValue();
234             }
235         }
236
237         return result;
238
239     }
240
241 }
242
Popular Tags