KickJava   Java API By Example, From Geeks To Geeks.

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


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  * StackedBarRenderer3D.java
24  * -------------------------
25  * (C) Copyright 2000-2003, by Serge V. Grachov and Contributors.
26  *
27  * Original Author: Serge V. Grachov;
28  * Contributor(s): David Gilbert (for Object Refinery Limited);
29  * Richard Atkinson;
30  * Christian W. Zuckschwerdt;
31  *
32  * $Id: StackedBarRenderer3D.java,v 1.23 2003/11/27 11:54:07 mungady Exp $
33  *
34  * Changes
35  * -------
36  * 31-Oct-2001 : Version 1, contributed by Serge V. Grachov (DG);
37  * 15-Nov-2001 : Modified to allow for null data values (DG);
38  * 13-Dec-2001 : Added tooltips (DG);
39  * 15-Feb-2002 : Added isStacked() method (DG);
40  * 24-May-2002 : Incorporated tooltips into chart entities (DG);
41  * 19-Jun-2002 : Added check for null info in drawCategoryItem method (DG);
42  * 25-Jun-2002 : Removed redundant imports (DG);
43  * 26-Jun-2002 : Small change to entity (DG);
44  * 05-Aug-2002 : Small modification to drawCategoryItem method to support URLs for HTML image
45  * maps (RA);
46  * 26-Sep-2002 : Fixed errors reported by Checkstyle (DG);
47  * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and CategoryToolTipGenerator
48  * interface (DG);
49  * 05-Nov-2002 : Replaced references to CategoryDataset with TableDataset (DG);
50  * 26-Nov-2002 : Replaced isStacked() method with getRangeType() method (DG);
51  * 17-Jan-2003 : Moved plot classes to a separate package (DG);
52  * 25-Mar-2003 : Implemented Serializable (DG);
53  * 01-May-2003 : Added default constructor (bug 726235) and fixed bug 726260) (DG);
54  * 13-May-2003 : Renamed StackedVerticalBarRenderer3D --> StackedBarRenderer3d (DG);
55  * 30-Jul-2003 : Modified entity constructor (CZ);
56  * 07-Oct-2003 : Added renderer state (DG);
57  * 21-Nov-2003 : Added a new constructor (DG);
58  * 27-Nov-2003 : Modified code to respect maxBarWidth setting (DG);
59  *
60  */

61
62 package org.jfree.chart.renderer;
63
64 import java.awt.Color JavaDoc;
65 import java.awt.Graphics2D JavaDoc;
66 import java.awt.Paint JavaDoc;
67 import java.awt.geom.GeneralPath JavaDoc;
68 import java.awt.geom.Rectangle2D JavaDoc;
69 import java.io.Serializable JavaDoc;
70
71 import org.jfree.chart.axis.CategoryAxis;
72 import org.jfree.chart.axis.ValueAxis;
73 import org.jfree.chart.entity.CategoryItemEntity;
74 import org.jfree.chart.entity.EntityCollection;
75 import org.jfree.chart.labels.CategoryItemLabelGenerator;
76 import org.jfree.chart.plot.CategoryPlot;
77 import org.jfree.chart.plot.PlotOrientation;
78 import org.jfree.data.CategoryDataset;
79 import org.jfree.ui.RectangleEdge;
80 import org.jfree.util.PublicCloneable;
81
82 /**
83  * Renders stacked bars with 3D-effect, for use with the {@link org.jfree.chart.plot.CategoryPlot}
84  * class.
85  *
86  * @author Serge V. Grachov
87  */

88 public class StackedBarRenderer3D extends BarRenderer3D
89                                   implements Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
90
91     /**
92      * Creates a new renderer with no tool tip generator and no URL generator.
93      * <P>
94      * The defaults (no tool tip or URL generators) have been chosen to minimise the processing
95      * required to generate a default chart. If you require tool tips or URLs, then you can
96      * easily add the required generators.
97      */

98     public StackedBarRenderer3D() {
99         super();
100     }
101
102     /**
103      * Constructs a new renderer with the specified '3D effect'.
104      *
105      * @param xOffset the x-offset for the 3D effect.
106      * @param yOffset the y-offset for the 3D effect.
107      */

108     public StackedBarRenderer3D(double xOffset, double yOffset) {
109         super(xOffset, yOffset);
110     }
111     
112     /**
113      * Returns the range type.
114      *
115      * @return the range type.
116      */

117     public RangeType getRangeType() {
118         return RangeType.STACKED;
119     }
120
121     /**
122      * Calculates the bar width and stores it in the renderer state.
123      *
124      * @param plot the plot.
125      * @param dataArea the data area.
126      * @param rendererIndex the renderer index.
127      * @param state the renderer state.
128      */

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

178     public void drawItem(Graphics2D JavaDoc g2,
179                          CategoryItemRendererState state,
180                          Rectangle2D JavaDoc dataArea,
181                          CategoryPlot plot,
182                          CategoryAxis domainAxis,
183                          ValueAxis rangeAxis,
184                          CategoryDataset dataset,
185                          int row,
186                          int column) {
187
188         // check the value we are plotting...
189
Number JavaDoc dataValue = dataset.getValue(row, column);
190         if (dataValue == null) {
191             return;
192         }
193         
194         double value = dataValue.doubleValue();
195         
196         Rectangle2D JavaDoc adjusted = new Rectangle2D.Double JavaDoc(dataArea.getX(),
197                                                       dataArea.getY() + getYOffset(),
198                                                       dataArea.getWidth() - getXOffset(),
199                                                       dataArea.getHeight() - getYOffset());
200
201         PlotOrientation orientation = plot.getOrientation();
202
203         double barW0 = domainAxis.getCategoryMiddle(column, getColumnCount(), adjusted,
204                                                     plot.getDomainAxisEdge())
205                                                     - state.getBarWidth() / 2.0;
206
207         double positiveBase = 0.0;
208         double negativeBase = 0.0;
209         for (int i = 0; i < row; i++) {
210             Number JavaDoc v = dataset.getValue(i, column);
211             if (v != null) {
212                 double d = v.doubleValue();
213                 if (d > 0) {
214                     positiveBase = positiveBase + d;
215                 }
216                 else {
217                     negativeBase = negativeBase + d;
218                 }
219             }
220         }
221
222         double translatedBase;
223         double translatedValue;
224         RectangleEdge location = plot.getRangeAxisEdge();
225         if (value > 0.0) {
226             translatedBase = rangeAxis.translateValueToJava2D(positiveBase, adjusted, location);
227             translatedValue = rangeAxis.translateValueToJava2D(positiveBase + value, adjusted,
228                                                                location);
229         }
230         else {
231             translatedBase = rangeAxis.translateValueToJava2D(negativeBase, adjusted, location);
232             translatedValue = rangeAxis.translateValueToJava2D(negativeBase + value, adjusted,
233                                                                location);
234         }
235         double barL0 = Math.min(translatedBase, translatedValue);
236         double barLength = Math.max(Math.abs(translatedValue - translatedBase),
237                                     getMinimumBarLength());
238
239         Rectangle2D JavaDoc bar = null;
240         if (orientation == PlotOrientation.HORIZONTAL) {
241             bar = new Rectangle2D.Double JavaDoc(barL0, barW0, barLength, state.getBarWidth());
242         }
243         else {
244             bar = new Rectangle2D.Double JavaDoc(barW0, barL0, state.getBarWidth(), barLength);
245         }
246         Paint JavaDoc itemPaint = getItemPaint(row, column);
247         g2.setPaint(itemPaint);
248         g2.fill(bar);
249
250         double x0 = bar.getMinX();
251         double x1 = x0 + getXOffset();
252         double x2 = bar.getMaxX();
253         double x3 = x2 + getXOffset();
254         
255         double y0 = bar.getMinY() - getYOffset();
256         double y1 = bar.getMinY();
257         double y2 = bar.getMaxY() - getYOffset();
258         double y3 = bar.getMaxY();
259         
260         GeneralPath JavaDoc bar3dRight = null;
261         GeneralPath JavaDoc bar3dTop = null;
262         if (value > 0.0 || orientation == PlotOrientation.VERTICAL) {
263             bar3dRight = new GeneralPath JavaDoc();
264             bar3dRight.moveTo((float) x2, (float) y3);
265             bar3dRight.lineTo((float) x2, (float) y1);
266             bar3dRight.lineTo((float) x3, (float) y0);
267             bar3dRight.lineTo((float) x3, (float) y2);
268             bar3dRight.closePath();
269
270             if (itemPaint instanceof Color JavaDoc) {
271                 g2.setPaint(((Color JavaDoc) itemPaint).darker());
272             }
273             g2.fill(bar3dRight);
274         }
275
276         if (value > 0.0 || orientation == PlotOrientation.HORIZONTAL) {
277             bar3dTop = new GeneralPath JavaDoc();
278             bar3dTop.moveTo((float) x0, (float) y1);
279             bar3dTop.lineTo((float) x1, (float) y0);
280             bar3dTop.lineTo((float) x3, (float) y0);
281             bar3dTop.lineTo((float) x2, (float) y1);
282             bar3dTop.closePath();
283             g2.fill(bar3dTop);
284         }
285
286         if (state.getBarWidth() > 3) {
287             g2.setStroke(getItemOutlineStroke(row, column));
288             g2.setPaint(getItemOutlinePaint(row, column));
289             g2.draw(bar);
290             if (bar3dRight != null) {
291                 g2.draw(bar3dRight);
292             }
293             if (bar3dTop != null) {
294                 g2.draw(bar3dTop);
295             }
296         }
297
298         // collect entity and tool tip information...
299
if (state.getInfo() != null) {
300             EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
301             if (entities != null) {
302                 String JavaDoc tip = null;
303                 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
304                 if (generator != null) {
305                     tip = generator.generateToolTip(dataset, row, column);
306                 }
307                 String JavaDoc url = null;
308                 if (getItemURLGenerator(row, column) != null) {
309                     url = getItemURLGenerator(row, column).generateURL(dataset, row, column);
310                 }
311                 CategoryItemEntity entity = new CategoryItemEntity(
312                     bar, tip, url, dataset, row, dataset.getColumnKey(column), column
313                 );
314                 entities.addEntity(entity);
315             }
316         }
317
318     }
319
320 }
321
Popular Tags