KickJava   Java API By Example, From Geeks To Geeks.

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


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  * WaterfallBarRenderer.java
24  * -------------------------
25  * (C) Copyright 2003 by Object Refinery Limited and Contributors.
26  *
27  * Original Author: Darshan Shah;
28  * Contributor(s): David Gilbert (for Object Refinery Limited);
29  *
30  * $Id: WaterfallBarRenderer.java,v 1.5 2003/11/27 13:05:15 mungady Exp $
31  *
32  * Changes
33  * -------
34  * 20-Oct-2003 : Version 1, contributed by Darshan Shah (DG);
35  * 06-Nov-2003 : Changed order of parameters in constructor, and added support for
36  * GradientPaint (DG);
37  *
38  */

39
40 package org.jfree.chart.renderer;
41
42 import java.awt.Color JavaDoc;
43 import java.awt.GradientPaint JavaDoc;
44 import java.awt.Graphics2D JavaDoc;
45 import java.awt.Paint JavaDoc;
46 import java.awt.Stroke JavaDoc;
47 import java.awt.geom.Rectangle2D JavaDoc;
48 import java.io.IOException JavaDoc;
49 import java.io.ObjectInputStream JavaDoc;
50 import java.io.ObjectOutputStream JavaDoc;
51 import java.io.Serializable JavaDoc;
52
53 import org.jfree.chart.axis.CategoryAxis;
54 import org.jfree.chart.axis.ValueAxis;
55 import org.jfree.chart.entity.CategoryItemEntity;
56 import org.jfree.chart.entity.EntityCollection;
57 import org.jfree.chart.labels.CategoryItemLabelGenerator;
58 import org.jfree.chart.plot.CategoryPlot;
59 import org.jfree.chart.plot.PlotOrientation;
60 import org.jfree.data.CategoryDataset;
61 import org.jfree.io.SerialUtilities;
62 import org.jfree.ui.GradientPaintTransformType;
63 import org.jfree.ui.RectangleEdge;
64 import org.jfree.ui.StandardGradientPaintTransformer;
65 import org.jfree.util.PaintUtils;
66 import org.jfree.util.PublicCloneable;
67
68 /**
69  * A renderer that handles the drawing of waterfall bar charts, for use with the
70  * {@link CategoryPlot} class.
71  */

72 public class WaterfallBarRenderer extends BarRenderer
73                                   implements Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
74
75     /** The paint used to draw the first bar. */
76     private transient Paint JavaDoc firstBarPaint;
77
78     /** The paint used to draw the last bar. */
79     private transient Paint JavaDoc lastBarPaint;
80
81     /** The paint used to draw bars having positive values. */
82     private transient Paint JavaDoc positiveBarPaint;
83
84     /** The paint used to draw bars having negative values. */
85     private transient Paint JavaDoc negativeBarPaint;
86
87     /**
88      * Constructs a new renderer with default values for the bar colors.
89      */

90     public WaterfallBarRenderer() {
91         this(new GradientPaint JavaDoc(0.0f, 0.0f, new Color JavaDoc(0x22, 0x22, 0xFF),
92                                0.0f, 0.0f, new Color JavaDoc(0x66, 0x66, 0xFF)),
93              new GradientPaint JavaDoc(0.0f, 0.0f, new Color JavaDoc(0x22, 0xFF, 0x22),
94                                0.0f, 0.0f, new Color JavaDoc(0x66, 0xFF, 0x66)),
95              new GradientPaint JavaDoc(0.0f, 0.0f, new Color JavaDoc(0xFF, 0x22, 0x22),
96                                0.0f, 0.0f, new Color JavaDoc(0xFF, 0x66, 0x66)),
97              new GradientPaint JavaDoc(0.0f, 0.0f, new Color JavaDoc(0xFF, 0xFF, 0x22),
98                                0.0f, 0.0f, new Color JavaDoc(0xFF, 0xFF, 0x66)));
99     }
100
101     /**
102      * Constructs a new waterfall renderer.
103      *
104      * @param firstBarPaint the color of the first bar.
105      * @param positiveBarPaint the color for bars with positive values.
106      * @param negativeBarPaint the color for bars with negative values.
107      * @param lastBarPaint the color of the last bar.
108      */

109     public WaterfallBarRenderer(Paint JavaDoc firstBarPaint,
110                                 Paint JavaDoc positiveBarPaint,
111                                 Paint JavaDoc negativeBarPaint,
112                                 Paint JavaDoc lastBarPaint) {
113         super();
114         this.firstBarPaint = firstBarPaint;
115         this.lastBarPaint = lastBarPaint;
116         this.positiveBarPaint = positiveBarPaint;
117         this.negativeBarPaint = negativeBarPaint;
118         setGradientPaintTransformer(
119             new StandardGradientPaintTransformer(GradientPaintTransformType.CENTER_VERTICAL));
120         setMinimumBarLength(1.0);
121     }
122
123     /**
124      * Returns the range type.
125      *
126      * @return The range type.
127      */

128     public RangeType getRangeType() {
129         return RangeType.SERIES_CUMULATIVE;
130     }
131
132     /**
133      * Returns the paint used to draw the first bar.
134      *
135      * @return The paint.
136      */

137     public Paint JavaDoc getFirstBarPaint() {
138         return this.firstBarPaint;
139     }
140     
141     /**
142      * Sets the paint that will be used to draw the first bar.
143      *
144      * @param paint the paint.
145      */

146     public void setFirstBarPaint(Paint JavaDoc paint) {
147         this.firstBarPaint = paint;
148     }
149
150     /**
151      * Returns the paint used to draw the last bar.
152      *
153      * @return The paint.
154      */

155     public Paint JavaDoc getLastBarPaint() {
156         return this.lastBarPaint;
157     }
158     
159     /**
160      * Sets the paint that will be used to draw the last bar.
161      *
162      * @param paint the paint.
163      */

164     public void setLastBarPaint(Paint JavaDoc paint) {
165         this.lastBarPaint = paint;
166     }
167
168     /**
169      * Returns the paint used to draw bars with positive values.
170      *
171      * @return The paint.
172      */

173     public Paint JavaDoc getPositiveBarPaint() {
174         return this.positiveBarPaint;
175     }
176     
177     /**
178      * Sets the paint that will be used to draw bars having positive values.
179      *
180      * @param paint the paint.
181      */

182     public void setPositiveBarPaint(Paint JavaDoc paint) {
183         this.positiveBarPaint = paint;
184     }
185
186     /**
187      * Returns the paint used to draw bars with negative values.
188      *
189      * @return The paint.
190      */

191     public Paint JavaDoc getNegativeBarPaint() {
192         return this.negativeBarPaint;
193     }
194     
195     /**
196      * Sets the paint that will be used to draw bars having negative values.
197      *
198      * @param paint the paint.
199      */

200     public void setNegativeBarPaint(Paint JavaDoc paint) {
201         this.negativeBarPaint = paint;
202     }
203
204     /**
205      * Draws the bar for a single (series, category) data item.
206      *
207      * @param g2 the graphics device.
208      * @param state the renderer state.
209      * @param dataArea the data area.
210      * @param plot the plot.
211      * @param domainAxis the domain axis.
212      * @param rangeAxis the range axis.
213      * @param dataset the dataset.
214      * @param row the row index (zero-based).
215      * @param column the column index (zero-based).
216      */

217     public void drawItem(Graphics2D JavaDoc g2,
218                          CategoryItemRendererState state,
219                          Rectangle2D JavaDoc dataArea,
220                          CategoryPlot plot,
221                          CategoryAxis domainAxis,
222                          ValueAxis rangeAxis,
223                          CategoryDataset dataset,
224                          int row,
225                          int column) {
226
227         double previous = state.getSeriesRunningTotal();
228         if (column == dataset.getColumnCount() - 1) {
229             previous = 0.0;
230         }
231         double current = 0.0;
232         Number JavaDoc n = dataset.getValue(row, column);
233         if (n != null) {
234             current = previous + n.doubleValue();
235         }
236         state.setSeriesRunningTotal(current);
237         
238         int seriesCount = getRowCount();
239         int categoryCount = getColumnCount();
240         PlotOrientation orientation = plot.getOrientation();
241         
242         double rectX = 0.0;
243         double rectY = 0.0;
244
245         RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
246         RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
247         
248         // Y0
249
double j2dy0 = rangeAxis.translateValueToJava2D(previous, dataArea, rangeAxisLocation);
250
251         // Y1
252
double j2dy1 = rangeAxis.translateValueToJava2D(current, dataArea, rangeAxisLocation);
253
254         double valDiff = current - previous;
255         if (j2dy1 < j2dy0) {
256             double temp = j2dy1;
257             j2dy1 = j2dy0;
258             j2dy0 = temp;
259         }
260
261         // BAR WIDTH
262
double rectWidth = state.getBarWidth();
263
264         // BAR HEIGHT
265
double rectHeight = Math.abs(j2dy1 - j2dy0);
266
267         if (orientation == PlotOrientation.HORIZONTAL) {
268             // BAR Y
269
rectY = domainAxis.getCategoryStart(column, getColumnCount(), dataArea,
270                                                 domainAxisLocation);
271             if (seriesCount > 1) {
272                 double seriesGap = dataArea.getHeight() * getItemMargin()
273                                    / (categoryCount * (seriesCount - 1));
274                 rectY = rectY + row * (state.getBarWidth() + seriesGap);
275             }
276             else {
277                 rectY = rectY + row * state.getBarWidth();
278             }
279              
280             rectX = j2dy0;
281             rectHeight = state.getBarWidth();
282             rectWidth = Math.abs(j2dy1 - j2dy0);
283
284         }
285         else if (orientation == PlotOrientation.VERTICAL) {
286             // BAR X
287
rectX = domainAxis.getCategoryStart(column, getColumnCount(), dataArea,
288                                                 domainAxisLocation);
289
290             if (seriesCount > 1) {
291                 double seriesGap = dataArea.getWidth() * getItemMargin()
292                                    / (categoryCount * (seriesCount - 1));
293                 rectX = rectX + row * (state.getBarWidth() + seriesGap);
294             }
295             else {
296                 rectX = rectX + row * state.getBarWidth();
297             }
298
299             rectY = j2dy0;
300         }
301         Rectangle2D JavaDoc bar = new Rectangle2D.Double JavaDoc(rectX, rectY, rectWidth, rectHeight);
302         Paint JavaDoc seriesPaint = this.firstBarPaint;
303         if (column == 0) {
304             seriesPaint = this.firstBarPaint;
305         }
306         else if (column == categoryCount - 1) {
307             seriesPaint = this.lastBarPaint;
308         }
309         else {
310             if (valDiff < 0.0) {
311                 seriesPaint = this.negativeBarPaint;
312             }
313             else if (valDiff > 0.0) {
314                 seriesPaint = this.positiveBarPaint;
315             }
316             else {
317                 seriesPaint = this.lastBarPaint;
318             }
319         }
320         if (getGradientPaintTransformer() != null && seriesPaint instanceof GradientPaint JavaDoc) {
321             GradientPaint JavaDoc gp = (GradientPaint JavaDoc) seriesPaint;
322             seriesPaint = getGradientPaintTransformer().transform(gp, bar);
323         }
324         g2.setPaint(seriesPaint);
325         g2.fill(bar);
326         
327         // draw the outline...
328
if (isDrawBarOutline() &&state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
329             Stroke JavaDoc stroke = getItemOutlineStroke(row, column);
330             Paint JavaDoc paint = getItemOutlinePaint(row, column);
331             if (stroke != null && paint != null) {
332                 g2.setStroke(stroke);
333                 g2.setPaint(paint);
334                 g2.draw(bar);
335             }
336         }
337         
338         CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
339         if (generator != null && isItemLabelVisible(row, column)) {
340             drawItemLabel(g2, dataset, row, column, plot, generator, bar, (valDiff < 0.0));
341         }
342
343         // collect entity and tool tip information...
344
if (state.getInfo() != null) {
345             EntityCollection entities = state.getInfo().getOwner().getEntityCollection();
346             if (entities != null) {
347                 String JavaDoc tip = null;
348                 if (generator != null) {
349                     tip = generator.generateToolTip(dataset, row, column);
350                 }
351                 String JavaDoc url = null;
352                 if (getItemURLGenerator(row, column) != null) {
353                     url = getItemURLGenerator(row, column).generateURL(dataset, row, column);
354                 }
355                 CategoryItemEntity entity = new CategoryItemEntity(
356                     bar, tip, url, dataset, row, dataset.getColumnKey(column), column
357                 );
358                 entities.addEntity(entity);
359             }
360         }
361
362     }
363     
364     /**
365      * Tests an object for equality with this instance.
366      *
367      * @param object the object.
368      *
369      * @return A boolean.
370      */

371     public boolean equals(Object JavaDoc object) {
372         
373         if (object == null) {
374             return false;
375         }
376         
377         if (object == this) {
378             return true;
379         }
380         
381         if (super.equals(object) && (object instanceof WaterfallBarRenderer)) {
382
383             WaterfallBarRenderer r = (WaterfallBarRenderer) object;
384             boolean b0 = PaintUtils.equal(this.firstBarPaint, r.firstBarPaint);
385             boolean b1 = PaintUtils.equal(this.lastBarPaint, r.lastBarPaint);
386             boolean b2 = PaintUtils.equal(this.positiveBarPaint, r.positiveBarPaint);
387             boolean b3 = PaintUtils.equal(this.negativeBarPaint, r.negativeBarPaint);
388             return b0 && b1 && b2 && b3;
389         }
390         
391         return false;
392         
393     }
394     
395     /**
396      * Provides serialization support.
397      *
398      * @param stream the output stream.
399      *
400      * @throws IOException if there is an I/O error.
401      */

402     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
403
404         stream.defaultWriteObject();
405         SerialUtilities.writePaint(this.firstBarPaint, stream);
406         SerialUtilities.writePaint(this.lastBarPaint, stream);
407         SerialUtilities.writePaint(this.positiveBarPaint, stream);
408         SerialUtilities.writePaint(this.negativeBarPaint, stream);
409
410     }
411
412     /**
413      * Provides serialization support.
414      *
415      * @param stream the input stream.
416      *
417      * @throws IOException if there is an I/O error.
418      * @throws ClassNotFoundException if there is a classpath problem.
419      */

420     private void readObject(ObjectInputStream JavaDoc stream) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
421
422         stream.defaultReadObject();
423         this.firstBarPaint = SerialUtilities.readPaint(stream);
424         this.lastBarPaint = SerialUtilities.readPaint(stream);
425         this.positiveBarPaint = SerialUtilities.readPaint(stream);
426         this.negativeBarPaint = SerialUtilities.readPaint(stream);
427
428     }
429
430 }
431
Popular Tags