KickJava   Java API By Example, From Geeks To Geeks.

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


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  * StackedBarRenderer.java
24  * -----------------------
25  * (C) Copyright 2000-2003, by Object Refinery Limited.
26  *
27  * Original Author: David Gilbert (for Object Refinery Limited);
28  * Contributor(s): Richard Atkinson;
29  * Thierry Saura;
30  * Christian W. Zuckschwerdt;
31  *
32  * $Id: StackedBarRenderer.java,v 1.23 2003/11/27 11:53:31 mungady Exp $
33  *
34  * Changes
35  * -------
36  * 19-Oct-2001 : Version 1 (DG);
37  * 22-Oct-2001 : Renamed DataSource.java --> Dataset.java etc. (DG);
38  * 23-Oct-2001 : Changed intro and trail gaps on bar plots to use percentage of available space
39  * rather than a fixed number of units (DG);
40  * 15-Nov-2001 : Modified to allow for null data values (DG);
41  * 22-Nov-2001 : Modified to allow for negative data values (DG);
42  * 13-Dec-2001 : Added tooltips (DG);
43  * 16-Jan-2002 : Fixed bug for single category datasets (DG);
44  * 15-Feb-2002 : Added isStacked() method (DG);
45  * 14-Mar-2002 : Modified to implement the CategoryItemRenderer interface (DG);
46  * 24-May-2002 : Incorporated tooltips into chart entities (DG);
47  * 11-Jun-2002 : Added check for (permitted) null info object, bug and fix reported by David
48  * Basten. Also updated Javadocs. (DG);
49  * 25-Jun-2002 : Removed redundant import (DG);
50  * 26-Jun-2002 : Small change to entity (DG);
51  * 05-Aug-2002 : Small modification to drawCategoryItem method to support URLs for HTML image
52  * maps (RA);
53  * 08-Aug-2002 : Added optional linking lines, contributed by Thierry Saura (DG);
54  * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG);
55  * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and CategoryToolTipGenerator
56  * interface (DG);
57  * 05-Nov-2002 : Replaced references to CategoryDataset with TableDataset (DG);
58  * 26-Nov-2002 : Replaced isStacked() method with getRangeType() method (DG);
59  * 17-Jan-2003 : Moved plot classes to a separate package (DG);
60  * 25-Mar-2003 : Implemented Serializable (DG);
61  * 12-May-2003 : Merged horizontal and vertical stacked bar renderers (DG);
62  * 30-Jul-2003 : Modified entity constructor (CZ);
63  * 08-Sep-2003 : Fixed bug 799668 (isBarOutlineDrawn() ignored) (DG);
64  * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
65  * 21-Oct-2003 : Moved bar width into renderer state (DG);
66  * 26-Nov-2003 : Added code to respect maxBarWidth attribute (DG);
67  *
68  */

69
70 package org.jfree.chart.renderer;
71
72 import java.awt.Graphics2D JavaDoc;
73 import java.awt.Paint JavaDoc;
74 import java.awt.geom.Rectangle2D JavaDoc;
75 import java.io.Serializable JavaDoc;
76
77 import org.jfree.chart.axis.CategoryAxis;
78 import org.jfree.chart.axis.ValueAxis;
79 import org.jfree.chart.entity.CategoryItemEntity;
80 import org.jfree.chart.entity.EntityCollection;
81 import org.jfree.chart.labels.CategoryItemLabelGenerator;
82 import org.jfree.chart.plot.CategoryPlot;
83 import org.jfree.chart.plot.PlotOrientation;
84 import org.jfree.data.CategoryDataset;
85 import org.jfree.ui.RectangleEdge;
86 import org.jfree.ui.TextAnchor;
87 import org.jfree.util.PublicCloneable;
88
89 /**
90  * A stacked bar renderer for use with the {@link org.jfree.chart.plot.CategoryPlot} class.
91  *
92  * @author David Gilbert
93  */

94 public class StackedBarRenderer extends BarRenderer
95                                 implements Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
96
97     /**
98      * Creates a new renderer with no tool tip generator and no URL generator.
99      * <P>
100      * The defaults (no tool tip or URL generators) have been chosen to minimise the processing
101      * required to generate a default chart. If you require tool tips or URLs, then you can
102      * easily add the required generators.
103      */

104     public StackedBarRenderer() {
105         super();
106         
107         // set the default item label positions, which will only be used if the user
108
// requests visible item labels...
109
ItemLabelPosition p = new ItemLabelPosition(
110             ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, 0.0
111         );
112         setBasePositiveItemLabelPosition(p);
113         setBaseNegativeItemLabelPosition(p);
114         setPositiveItemLabelPositionFallback(null);
115         setNegativeItemLabelPositionFallback(null);
116     }
117
118     /**
119      * Returns the range type.
120      *
121      * @return the range type.
122      */

123     public RangeType getRangeType() {
124         return RangeType.STACKED;
125     }
126
127     /**
128      * Calculates the bar width and stores it in the renderer state.
129      *
130      * @param plot the plot.
131      * @param dataArea the data area.
132      * @param rendererIndex the renderer index.
133      * @param state the renderer state.
134      */

135     protected void calculateBarWidth(CategoryPlot plot,
136                                      Rectangle2D JavaDoc dataArea,
137                                      Integer JavaDoc rendererIndex,
138                                      CategoryItemRendererState state) {
139
140         // calculate the bar width
141
CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
142         CategoryDataset data = getDataset(plot, rendererIndex);
143         if (data != null) {
144             PlotOrientation orientation = plot.getOrientation();
145             double space = 0.0;
146             if (orientation == PlotOrientation.HORIZONTAL) {
147                 space = dataArea.getHeight();
148             }
149             else if (orientation == PlotOrientation.VERTICAL) {
150                 space = dataArea.getWidth();
151             }
152             double maxWidth = space * getMaxBarWidth();
153             int columns = data.getColumnCount();
154             double categoryMargin = 0.0;
155             if (columns > 1) {
156                 categoryMargin = domainAxis.getCategoryMargin();
157             }
158
159             double used = space * (1 - domainAxis.getLowerMargin() - domainAxis.getUpperMargin()
160                                      - categoryMargin);
161             if (columns > 0) {
162                 state.setBarWidth(Math.min(used / columns, maxWidth));
163             }
164             else {
165                 state.setBarWidth(Math.min(used, maxWidth));
166             }
167         }
168
169     }
170
171     /**
172      * Draws a stacked bar for a specific item.
173      *
174      * @param g2 the graphics device.
175      * @param state the renderer state.
176      * @param dataArea the plot area.
177      * @param plot the plot.
178      * @param domainAxis the domain (category) axis.
179      * @param rangeAxis the range (value) axis.
180      * @param dataset the data.
181      * @param row the row index (zero-based).
182      * @param column the column index (zero-based).
183      */

184     public void drawItem(Graphics2D JavaDoc g2,
185                          CategoryItemRendererState state,
186                          Rectangle2D JavaDoc dataArea,
187                          CategoryPlot plot,
188                          CategoryAxis domainAxis,
189                          ValueAxis rangeAxis,
190                          CategoryDataset dataset,
191                          int row,
192                          int column) {
193      
194         // nothing is drawn for null values...
195
Number JavaDoc dataValue = dataset.getValue(row, column);
196         if (dataValue == null) {
197             return;
198         }
199         
200         double value = dataValue.doubleValue();
201         
202         PlotOrientation orientation = plot.getOrientation();
203         double barW0 = domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea,
204                                                     plot.getDomainAxisEdge())
205                                                     - state.getBarWidth() / 2.0;
206
207         double positiveBase = 0.0;
208         double negativeBase = 0.0;
209
210         for (int i = 0; i < row; i++) {
211             Number JavaDoc v = dataset.getValue(i, column);
212             if (v != null) {
213                 double d = v.doubleValue();
214                 if (d > 0) {
215                     positiveBase = positiveBase + d;
216                 }
217                 else {
218                     negativeBase = negativeBase + d;
219                 }
220             }
221         }
222
223         double translatedBase;
224         double translatedValue;
225         RectangleEdge location = plot.getRangeAxisEdge();
226         if (value > 0.0) {
227             translatedBase = rangeAxis.translateValueToJava2D(positiveBase, dataArea, location);
228             translatedValue = rangeAxis.translateValueToJava2D(positiveBase + value, dataArea,
229                                                                location);
230         }
231         else {
232             translatedBase = rangeAxis.translateValueToJava2D(negativeBase, dataArea, location);
233             translatedValue = rangeAxis.translateValueToJava2D(negativeBase + value, dataArea,
234                                                                location);
235         }
236         double barL0 = Math.min(translatedBase, translatedValue);
237         double barLength = Math.max(Math.abs(translatedValue - translatedBase),
238                                     getMinimumBarLength());
239
240         Rectangle2D JavaDoc bar = null;
241         if (orientation == PlotOrientation.HORIZONTAL) {
242             bar = new Rectangle2D.Double JavaDoc(barL0, barW0, barLength, state.getBarWidth());
243         }
244         else {
245             bar = new Rectangle2D.Double JavaDoc(barW0, barL0, state.getBarWidth(), barLength);
246         }
247         Paint JavaDoc seriesPaint = getItemPaint(row, column);
248         g2.setPaint(seriesPaint);
249         g2.fill(bar);
250         if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
251             g2.setStroke(getItemStroke(row, column));
252             g2.setPaint(getItemOutlinePaint(row, column));
253             g2.draw(bar);
254         }
255
256         CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
257         if (generator != null && isItemLabelVisible(row, column)) {
258             drawItemLabel(g2, dataset, row, column, plot, generator, bar, (value < 0.0));
259         }
260                 
261         // collect entity and tool tip information...
262
if (state.getInfo() != null) {
263             EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
264             if (entities != null) {
265                 String JavaDoc tip = null;
266                 if (generator != null) {
267                     tip = generator.generateToolTip(dataset, row, column);
268                 }
269                 String JavaDoc url = null;
270                 if (getItemURLGenerator(row, column) != null) {
271                     url = getItemURLGenerator(row, column).generateURL(dataset, row, column);
272                 }
273                 CategoryItemEntity entity = new CategoryItemEntity(
274                     bar, tip, url, dataset, row, dataset.getColumnKey(column), column
275                 );
276                 entities.addEntity(entity);
277             }
278         }
279         
280     }
281
282 }
283
Popular Tags