KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > renderer > category > StatisticalBarRenderer


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ---------------------------
28  * StatisticalBarRenderer.java
29  * ---------------------------
30  * (C) Copyright 2002-2006, by Pascal Collet and Contributors.
31  *
32  * Original Author: Pascal Collet;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  * Christian W. Zuckschwerdt;
35  *
36  * $Id: StatisticalBarRenderer.java,v 1.4.2.5 2006/07/12 14:30:11 mungady Exp $
37  *
38  * Changes
39  * -------
40  * 21-Aug-2002 : Version 1, contributed by Pascal Collet (DG);
41  * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
42  * 24-Oct-2002 : Changes to dataset interface (DG);
43  * 05-Nov-2002 : Base dataset is now TableDataset not CategoryDataset (DG);
44  * 05-Feb-2003 : Updates for new DefaultStatisticalCategoryDataset (DG);
45  * 25-Mar-2003 : Implemented Serializable (DG);
46  * 30-Jul-2003 : Modified entity constructor (CZ);
47  * 06-Oct-2003 : Corrected typo in exception message (DG);
48  * 05-Nov-2004 : Modified drawItem() signature (DG);
49  * 15-Jun-2005 : Added errorIndicatorPaint attribute (DG);
50  * ------------- JFREECHART 1.0.0 ---------------------------------------------
51  * 19-May-2006 : Added support for tooltips and URLs (DG);
52  * 12-Jul-2006 : Added support for item labels (DG);
53  *
54  */

55
56 package org.jfree.chart.renderer.category;
57
58 import java.awt.Color JavaDoc;
59 import java.awt.Graphics2D JavaDoc;
60 import java.awt.Paint JavaDoc;
61 import java.awt.geom.Line2D JavaDoc;
62 import java.awt.geom.Rectangle2D JavaDoc;
63 import java.io.IOException JavaDoc;
64 import java.io.ObjectInputStream JavaDoc;
65 import java.io.ObjectOutputStream JavaDoc;
66 import java.io.Serializable JavaDoc;
67
68 import org.jfree.chart.axis.CategoryAxis;
69 import org.jfree.chart.axis.ValueAxis;
70 import org.jfree.chart.entity.EntityCollection;
71 import org.jfree.chart.event.RendererChangeEvent;
72 import org.jfree.chart.labels.CategoryItemLabelGenerator;
73 import org.jfree.chart.plot.CategoryPlot;
74 import org.jfree.chart.plot.PlotOrientation;
75 import org.jfree.data.category.CategoryDataset;
76 import org.jfree.data.statistics.StatisticalCategoryDataset;
77 import org.jfree.io.SerialUtilities;
78 import org.jfree.ui.RectangleEdge;
79 import org.jfree.util.PaintUtilities;
80 import org.jfree.util.PublicCloneable;
81
82 /**
83  * A renderer that handles the drawing a bar plot where
84  * each bar has a mean value and a standard deviation line.
85  *
86  * @author Pascal Collet
87  */

88 public class StatisticalBarRenderer extends BarRenderer
89                                     implements CategoryItemRenderer,
90                                                Cloneable JavaDoc, PublicCloneable,
91                                                Serializable JavaDoc {
92
93     /** For serialization. */
94     private static final long serialVersionUID = -4986038395414039117L;
95     
96     /** The paint used to show the error indicator. */
97     private transient Paint JavaDoc errorIndicatorPaint;
98     
99     /**
100      * Default constructor.
101      */

102     public StatisticalBarRenderer() {
103         super();
104         this.errorIndicatorPaint = Color.gray;
105     }
106
107     /**
108      * Returns the paint used for the error indicators.
109      *
110      * @return The paint used for the error indicators (possibly
111      * <code>null</code>).
112      */

113     public Paint JavaDoc getErrorIndicatorPaint() {
114         return this.errorIndicatorPaint;
115     }
116
117     /**
118      * Sets the paint used for the error indicators (if <code>null</code>,
119      * the item outline paint is used instead)
120      *
121      * @param paint the paint (<code>null</code> permitted).
122      */

123     public void setErrorIndicatorPaint(Paint JavaDoc paint) {
124         this.errorIndicatorPaint = paint;
125         notifyListeners(new RendererChangeEvent(this));
126     }
127     
128     /**
129      * Draws the bar with its standard deviation line range for a single
130      * (series, category) data item.
131      *
132      * @param g2 the graphics device.
133      * @param state the renderer state.
134      * @param dataArea the data area.
135      * @param plot the plot.
136      * @param domainAxis the domain axis.
137      * @param rangeAxis the range axis.
138      * @param data the data.
139      * @param row the row index (zero-based).
140      * @param column the column index (zero-based).
141      * @param pass the pass index.
142      */

143     public void drawItem(Graphics2D JavaDoc g2,
144                          CategoryItemRendererState state,
145                          Rectangle2D JavaDoc dataArea,
146                          CategoryPlot plot,
147                          CategoryAxis domainAxis,
148                          ValueAxis rangeAxis,
149                          CategoryDataset data,
150                          int row,
151                          int column,
152                          int pass) {
153
154         // defensive check
155
if (!(data instanceof StatisticalCategoryDataset)) {
156             throw new IllegalArgumentException JavaDoc(
157                 "Requires StatisticalCategoryDataset.");
158         }
159         StatisticalCategoryDataset statData = (StatisticalCategoryDataset) data;
160
161         PlotOrientation orientation = plot.getOrientation();
162         if (orientation == PlotOrientation.HORIZONTAL) {
163             drawHorizontalItem(g2, state, dataArea, plot, domainAxis,
164                     rangeAxis, statData, row, column);
165         }
166         else if (orientation == PlotOrientation.VERTICAL) {
167             drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
168                     statData, row, column);
169         }
170     }
171                 
172     /**
173      * Draws an item for a plot with a horizontal orientation.
174      *
175      * @param g2 the graphics device.
176      * @param state the renderer state.
177      * @param dataArea the data area.
178      * @param plot the plot.
179      * @param domainAxis the domain axis.
180      * @param rangeAxis the range axis.
181      * @param dataset the data.
182      * @param row the row index (zero-based).
183      * @param column the column index (zero-based).
184      */

185     protected void drawHorizontalItem(Graphics2D JavaDoc g2,
186                                       CategoryItemRendererState state,
187                                       Rectangle2D JavaDoc dataArea,
188                                       CategoryPlot plot,
189                                       CategoryAxis domainAxis,
190                                       ValueAxis rangeAxis,
191                                       StatisticalCategoryDataset dataset,
192                                       int row,
193                                       int column) {
194                                      
195         RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
196         
197         // BAR Y
198
double rectY = domainAxis.getCategoryStart(column, getColumnCount(),
199                 dataArea, xAxisLocation);
200
201         int seriesCount = getRowCount();
202         int categoryCount = getColumnCount();
203         if (seriesCount > 1) {
204             double seriesGap = dataArea.getHeight() * getItemMargin()
205                                / (categoryCount * (seriesCount - 1));
206             rectY = rectY + row * (state.getBarWidth() + seriesGap);
207         }
208         else {
209             rectY = rectY + row * state.getBarWidth();
210         }
211
212         // BAR X
213
Number JavaDoc meanValue = dataset.getMeanValue(row, column);
214
215         double value = meanValue.doubleValue();
216         double base = 0.0;
217         double lclip = getLowerClip();
218         double uclip = getUpperClip();
219
220         if (uclip <= 0.0) { // cases 1, 2, 3 and 4
221
if (value >= uclip) {
222                 return; // bar is not visible
223
}
224             base = uclip;
225             if (value <= lclip) {
226                 value = lclip;
227             }
228         }
229         else if (lclip <= 0.0) { // cases 5, 6, 7 and 8
230
if (value >= uclip) {
231                 value = uclip;
232             }
233             else {
234                 if (value <= lclip) {
235                     value = lclip;
236                 }
237             }
238         }
239         else { // cases 9, 10, 11 and 12
240
if (value <= lclip) {
241                 return; // bar is not visible
242
}
243             base = getLowerClip();
244             if (value >= uclip) {
245                value = uclip;
246             }
247         }
248
249         RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
250         double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation);
251         double transY2 = rangeAxis.valueToJava2D(value, dataArea,
252                 yAxisLocation);
253         double rectX = Math.min(transY2, transY1);
254
255         double rectHeight = state.getBarWidth();
256         double rectWidth = Math.abs(transY2 - transY1);
257
258         Rectangle2D JavaDoc bar = new Rectangle2D.Double JavaDoc(rectX, rectY, rectWidth,
259                 rectHeight);
260         Paint JavaDoc seriesPaint = getItemPaint(row, column);
261         g2.setPaint(seriesPaint);
262         g2.fill(bar);
263         if (state.getBarWidth() > 3) {
264             g2.setStroke(getItemStroke(row, column));
265             g2.setPaint(getItemOutlinePaint(row, column));
266             g2.draw(bar);
267         }
268
269         // standard deviation lines
270
double valueDelta = dataset.getStdDevValue(row, column).doubleValue();
271         double highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
272                 + valueDelta, dataArea, yAxisLocation);
273         double lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
274                 - valueDelta, dataArea, yAxisLocation);
275
276         if (this.errorIndicatorPaint != null) {
277             g2.setPaint(this.errorIndicatorPaint);
278         }
279         else {
280             g2.setPaint(getItemOutlinePaint(row, column));
281         }
282         Line2D JavaDoc line = null;
283         line = new Line2D.Double JavaDoc(lowVal, rectY + rectHeight / 2.0d,
284                                  highVal, rectY + rectHeight / 2.0d);
285         g2.draw(line);
286         line = new Line2D.Double JavaDoc(highVal, rectY + rectHeight * 0.25,
287                                  highVal, rectY + rectHeight * 0.75);
288         g2.draw(line);
289         line = new Line2D.Double JavaDoc(lowVal, rectY + rectHeight * 0.25,
290                                  lowVal, rectY + rectHeight * 0.75);
291         g2.draw(line);
292         
293         CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
294                 column);
295         if (generator != null && isItemLabelVisible(row, column)) {
296             drawItemLabel(g2, dataset, row, column, plot, generator, bar,
297                 (value < 0.0));
298         }
299
300         // add an item entity, if this information is being collected
301
EntityCollection entities = state.getEntityCollection();
302         if (entities != null) {
303             addItemEntity(entities, dataset, row, column, bar);
304         }
305
306     }
307
308     /**
309      * Draws an item for a plot with a vertical orientation.
310      *
311      * @param g2 the graphics device.
312      * @param state the renderer state.
313      * @param dataArea the data area.
314      * @param plot the plot.
315      * @param domainAxis the domain axis.
316      * @param rangeAxis the range axis.
317      * @param dataset the data.
318      * @param row the row index (zero-based).
319      * @param column the column index (zero-based).
320      */

321     protected void drawVerticalItem(Graphics2D JavaDoc g2,
322                                     CategoryItemRendererState state,
323                                     Rectangle2D JavaDoc dataArea,
324                                     CategoryPlot plot,
325                                     CategoryAxis domainAxis,
326                                     ValueAxis rangeAxis,
327                                     StatisticalCategoryDataset dataset,
328                                     int row,
329                                     int column) {
330                                      
331         RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
332         
333         // BAR X
334
double rectX = domainAxis.getCategoryStart(
335             column, getColumnCount(), dataArea, xAxisLocation
336         );
337
338         int seriesCount = getRowCount();
339         int categoryCount = getColumnCount();
340         if (seriesCount > 1) {
341             double seriesGap = dataArea.getWidth() * getItemMargin()
342                                / (categoryCount * (seriesCount - 1));
343             rectX = rectX + row * (state.getBarWidth() + seriesGap);
344         }
345         else {
346             rectX = rectX + row * state.getBarWidth();
347         }
348
349         // BAR Y
350
Number JavaDoc meanValue = dataset.getMeanValue(row, column);
351
352         double value = meanValue.doubleValue();
353         double base = 0.0;
354         double lclip = getLowerClip();
355         double uclip = getUpperClip();
356
357         if (uclip <= 0.0) { // cases 1, 2, 3 and 4
358
if (value >= uclip) {
359                 return; // bar is not visible
360
}
361             base = uclip;
362             if (value <= lclip) {
363                 value = lclip;
364             }
365         }
366         else if (lclip <= 0.0) { // cases 5, 6, 7 and 8
367
if (value >= uclip) {
368                 value = uclip;
369             }
370             else {
371                 if (value <= lclip) {
372                     value = lclip;
373                 }
374             }
375         }
376         else { // cases 9, 10, 11 and 12
377
if (value <= lclip) {
378                 return; // bar is not visible
379
}
380             base = getLowerClip();
381             if (value >= uclip) {
382                value = uclip;
383             }
384         }
385
386         RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
387         double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation);
388         double transY2 = rangeAxis.valueToJava2D(value, dataArea,
389                 yAxisLocation);
390         double rectY = Math.min(transY2, transY1);
391
392         double rectWidth = state.getBarWidth();
393         double rectHeight = Math.abs(transY2 - transY1);
394
395         Rectangle2D JavaDoc bar = new Rectangle2D.Double JavaDoc(rectX, rectY, rectWidth,
396                 rectHeight);
397         Paint JavaDoc seriesPaint = getItemPaint(row, column);
398         g2.setPaint(seriesPaint);
399         g2.fill(bar);
400         if (state.getBarWidth() > 3) {
401             g2.setStroke(getItemStroke(row, column));
402             g2.setPaint(getItemOutlinePaint(row, column));
403             g2.draw(bar);
404         }
405
406         // standard deviation lines
407
double valueDelta = dataset.getStdDevValue(row, column).doubleValue();
408         double highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
409                 + valueDelta, dataArea, yAxisLocation);
410         double lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
411                 - valueDelta, dataArea, yAxisLocation);
412
413         if (this.errorIndicatorPaint != null) {
414             g2.setPaint(this.errorIndicatorPaint);
415         }
416         else {
417             g2.setPaint(getItemOutlinePaint(row, column));
418         }
419         Line2D JavaDoc line = null;
420         line = new Line2D.Double JavaDoc(rectX + rectWidth / 2.0d, lowVal,
421                                  rectX + rectWidth / 2.0d, highVal);
422         g2.draw(line);
423         line = new Line2D.Double JavaDoc(rectX + rectWidth / 2.0d - 5.0d, highVal,
424                                  rectX + rectWidth / 2.0d + 5.0d, highVal);
425         g2.draw(line);
426         line = new Line2D.Double JavaDoc(rectX + rectWidth / 2.0d - 5.0d, lowVal,
427                                  rectX + rectWidth / 2.0d + 5.0d, lowVal);
428         g2.draw(line);
429         
430         CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
431                 column);
432         if (generator != null && isItemLabelVisible(row, column)) {
433             drawItemLabel(g2, dataset, row, column, plot, generator, bar,
434                 (value < 0.0));
435         }
436
437         // add an item entity, if this information is being collected
438
EntityCollection entities = state.getEntityCollection();
439         if (entities != null) {
440             addItemEntity(entities, dataset, row, column, bar);
441         }
442     }
443     
444     /**
445      * Tests this renderer for equality with an arbitrary object.
446      *
447      * @param obj the object (<code>null</code> permitted).
448      *
449      * @return A boolean.
450      */

451     public boolean equals(Object JavaDoc obj) {
452         if (obj == this) {
453             return true;
454         }
455         if (!(obj instanceof StatisticalBarRenderer)) {
456             return false;
457         }
458         if (!super.equals(obj)) {
459             return false;
460         }
461         StatisticalBarRenderer that = (StatisticalBarRenderer) obj;
462         if (!PaintUtilities.equal(this.errorIndicatorPaint,
463                 that.errorIndicatorPaint)) {
464             return false;
465         }
466         return true;
467     }
468     
469     /**
470      * Provides serialization support.
471      *
472      * @param stream the output stream.
473      *
474      * @throws IOException if there is an I/O error.
475      */

476     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
477         stream.defaultWriteObject();
478         SerialUtilities.writePaint(this.errorIndicatorPaint, stream);
479     }
480
481     /**
482      * Provides serialization support.
483      *
484      * @param stream the input stream.
485      *
486      * @throws IOException if there is an I/O error.
487      * @throws ClassNotFoundException if there is a classpath problem.
488      */

489     private void readObject(ObjectInputStream JavaDoc stream)
490         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
491         stream.defaultReadObject();
492         this.errorIndicatorPaint = SerialUtilities.readPaint(stream);
493     }
494
495 }
496
Popular Tags