KickJava   Java API By Example, From Geeks To Geeks.

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


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  * StatisticalLineAndShapeRenderer.java
29  * ------------------------------------
30  * (C) Copyright 2005, 2006, by Object Refinery Limited and Contributors.
31  *
32  * Original Author: Mofeed Shahin;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  *
35  * $Id: StatisticalLineAndShapeRenderer.java,v 1.4.2.7 2006/09/25 10:09:58 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 01-Feb-2005 : Version 1, contributed by Mofeed Shahin (DG);
40  * 16-Jun-2005 : Added errorIndicatorPaint to be consistent with
41  * StatisticalBarRenderer (DG);
42  * ------------- JFREECHART 1.0.0 ---------------------------------------------
43  * 11-Apr-2006 : Fixed bug 1468794, error bars drawn incorrectly when rendering
44  * plots with horizontal orientation (DG);
45  * 25-Sep-2006 : Fixed bug 1562759, constructor ignoring arguments (DG);
46  *
47  */

48
49 package org.jfree.chart.renderer.category;
50
51 import java.awt.Graphics2D JavaDoc;
52 import java.awt.Paint JavaDoc;
53 import java.awt.Shape JavaDoc;
54 import java.awt.geom.Line2D JavaDoc;
55 import java.awt.geom.Rectangle2D JavaDoc;
56 import java.io.IOException JavaDoc;
57 import java.io.ObjectInputStream JavaDoc;
58 import java.io.ObjectOutputStream 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.event.RendererChangeEvent;
66 import org.jfree.chart.labels.CategoryToolTipGenerator;
67 import org.jfree.chart.plot.CategoryPlot;
68 import org.jfree.chart.plot.PlotOrientation;
69 import org.jfree.data.category.CategoryDataset;
70 import org.jfree.data.statistics.StatisticalCategoryDataset;
71 import org.jfree.io.SerialUtilities;
72 import org.jfree.ui.RectangleEdge;
73 import org.jfree.util.PaintUtilities;
74 import org.jfree.util.PublicCloneable;
75 import org.jfree.util.ShapeUtilities;
76
77 /**
78  * A renderer that draws shapes for each data item, and lines between data
79  * items. Each point has a mean value and a standard deviation line. For use
80  * with the {@link CategoryPlot} class.
81  */

82 public class StatisticalLineAndShapeRenderer extends LineAndShapeRenderer
83     implements Cloneable JavaDoc, PublicCloneable, Serializable JavaDoc {
84
85     /** For serialization. */
86     private static final long serialVersionUID = -3557517173697777579L;
87     
88     /** The paint used to show the error indicator. */
89     private transient Paint JavaDoc errorIndicatorPaint;
90
91     /**
92      * Constructs a default renderer (draws shapes and lines).
93      */

94     public StatisticalLineAndShapeRenderer() {
95         this(true, true);
96     }
97
98     /**
99      * Constructs a new renderer.
100      *
101      * @param linesVisible draw lines?
102      * @param shapesVisible draw shapes?
103      */

104     public StatisticalLineAndShapeRenderer(boolean linesVisible,
105                                            boolean shapesVisible) {
106         super(linesVisible, shapesVisible);
107         this.errorIndicatorPaint = null;
108     }
109
110     /**
111      * Returns the paint used for the error indicators.
112      *
113      * @return The paint used for the error indicators (possibly
114      * <code>null</code>).
115      */

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

126     public void setErrorIndicatorPaint(Paint JavaDoc paint) {
127         this.errorIndicatorPaint = paint;
128         notifyListeners(new RendererChangeEvent(this));
129     }
130     
131     /**
132      * Draw a single data item.
133      *
134      * @param g2 the graphics device.
135      * @param state the renderer state.
136      * @param dataArea the area in which the data is drawn.
137      * @param plot the plot.
138      * @param domainAxis the domain axis.
139      * @param rangeAxis the range axis.
140      * @param dataset the dataset (a {@link StatisticalCategoryDataset} is
141      * required).
142      * @param row the row index (zero-based).
143      * @param column the column index (zero-based).
144      * @param pass the pass.
145      */

146     public void drawItem(Graphics2D JavaDoc g2,
147                          CategoryItemRendererState state,
148                          Rectangle2D JavaDoc dataArea,
149                          CategoryPlot plot,
150                          CategoryAxis domainAxis,
151                          ValueAxis rangeAxis,
152                          CategoryDataset dataset,
153                          int row,
154                          int column,
155                          int pass) {
156
157         // nothing is drawn for null...
158
Number JavaDoc v = dataset.getValue(row, column);
159         if (v == null) {
160           return;
161         }
162
163         StatisticalCategoryDataset statData
164             = (StatisticalCategoryDataset) dataset;
165
166         Number JavaDoc meanValue = statData.getMeanValue(row, column);
167
168         PlotOrientation orientation = plot.getOrientation();
169
170         // current data point...
171
double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(),
172                 dataArea, plot.getDomainAxisEdge());
173
174         double y1 = rangeAxis.valueToJava2D(meanValue.doubleValue(), dataArea,
175                 plot.getRangeAxisEdge());
176
177         Shape JavaDoc shape = getItemShape(row, column);
178         if (orientation == PlotOrientation.HORIZONTAL) {
179             shape = ShapeUtilities.createTranslatedShape(shape, y1, x1);
180         }
181         else if (orientation == PlotOrientation.VERTICAL) {
182             shape = ShapeUtilities.createTranslatedShape(shape, x1, y1);
183         }
184         if (getItemShapeVisible(row, column)) {
185             
186             if (getItemShapeFilled(row, column)) {
187                 g2.setPaint(getItemPaint(row, column));
188                 g2.fill(shape);
189             }
190             else {
191                 if (getUseOutlinePaint()) {
192                     g2.setPaint(getItemOutlinePaint(row, column));
193                 }
194                 else {
195                     g2.setPaint(getItemPaint(row, column));
196                 }
197                 g2.setStroke(getItemOutlineStroke(row, column));
198                 g2.draw(shape);
199             }
200         }
201
202         if (getItemLineVisible(row, column)) {
203             if (column != 0) {
204
205                 Number JavaDoc previousValue = statData.getValue(row, column - 1);
206                 if (previousValue != null) {
207
208                     // previous data point...
209
double previous = previousValue.doubleValue();
210                     double x0 = domainAxis.getCategoryMiddle(column - 1,
211                             getColumnCount(), dataArea,
212                             plot.getDomainAxisEdge());
213                     double y0 = rangeAxis.valueToJava2D(previous, dataArea,
214                             plot.getRangeAxisEdge());
215
216                     Line2D JavaDoc line = null;
217                     if (orientation == PlotOrientation.HORIZONTAL) {
218                         line = new Line2D.Double JavaDoc(y0, x0, y1, x1);
219                     }
220                     else if (orientation == PlotOrientation.VERTICAL) {
221                         line = new Line2D.Double JavaDoc(x0, y0, x1, y1);
222                     }
223                     g2.setPaint(getItemPaint(row, column));
224                     g2.setStroke(getItemStroke(row, column));
225                     g2.draw(line);
226                 }
227             }
228         }
229
230         RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
231         RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
232         double rectX = domainAxis.getCategoryStart(column, getColumnCount(),
233                 dataArea, xAxisLocation);
234         
235         rectX = rectX + row * state.getBarWidth();
236         
237         g2.setPaint(getItemPaint(row, column));
238
239         //standard deviation lines
240
double valueDelta = statData.getStdDevValue(row, column).doubleValue();
241
242         double highVal, lowVal;
243         if ((meanValue.doubleValue() + valueDelta)
244                 > rangeAxis.getRange().getUpperBound()) {
245             highVal = rangeAxis.valueToJava2D(
246                     rangeAxis.getRange().getUpperBound(), dataArea,
247                     yAxisLocation);
248         }
249         else {
250             highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
251                     + valueDelta, dataArea, yAxisLocation);
252         }
253         
254         if ((meanValue.doubleValue() + valueDelta)
255                 < rangeAxis.getRange().getLowerBound()) {
256             lowVal = rangeAxis.valueToJava2D(
257                     rangeAxis.getRange().getLowerBound(), dataArea,
258                     yAxisLocation);
259         }
260         else {
261             lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
262                     - valueDelta, dataArea, yAxisLocation);
263         }
264         
265         if (this.errorIndicatorPaint != null) {
266             g2.setPaint(this.errorIndicatorPaint);
267         }
268         else {
269             g2.setPaint(getItemPaint(row, column));
270         }
271         Line2D JavaDoc line = new Line2D.Double JavaDoc();
272         if (orientation == PlotOrientation.HORIZONTAL) {
273             line.setLine(lowVal, x1, highVal, x1);
274             g2.draw(line);
275             line.setLine(lowVal, x1 - 5.0d, lowVal, x1 + 5.0d);
276             g2.draw(line);
277             line.setLine(highVal, x1 - 5.0d, highVal, x1 + 5.0d);
278             g2.draw(line);
279         }
280         else { // PlotOrientation.VERTICAL
281
line.setLine(x1, lowVal, x1, highVal);
282             g2.draw(line);
283             line.setLine(x1 - 5.0d, highVal, x1 + 5.0d, highVal);
284             g2.draw(line);
285             line.setLine(x1 - 5.0d, lowVal, x1 + 5.0d, lowVal);
286             g2.draw(line);
287         }
288         
289         // draw the item label if there is one...
290
if (isItemLabelVisible(row, column)) {
291             if (orientation == PlotOrientation.HORIZONTAL) {
292               drawItemLabel(g2, orientation, dataset, row, column,
293                   y1, x1, (meanValue.doubleValue() < 0.0));
294             }
295             else if (orientation == PlotOrientation.VERTICAL) {
296               drawItemLabel(g2, orientation, dataset, row, column,
297                   x1, y1, (meanValue.doubleValue() < 0.0));
298             }
299         }
300
301         // collect entity and tool tip information...
302
if (state.getInfo() != null) {
303             EntityCollection entities = state.getEntityCollection();
304             if (entities != null && shape != null) {
305                 String JavaDoc tip = null;
306                 CategoryToolTipGenerator tipster = getToolTipGenerator(row,
307                         column);
308                 if (tipster != null) {
309                     tip = tipster.generateToolTip(dataset, row, column);
310                 }
311                 String JavaDoc url = null;
312                 if (getItemURLGenerator(row, column) != null) {
313                     url = getItemURLGenerator(row, column).generateURL(
314                             dataset, row, column);
315                 }
316                 CategoryItemEntity entity = new CategoryItemEntity(shape, tip,
317                         url, dataset, row, dataset.getColumnKey(column),
318                         column);
319                 entities.add(entity);
320
321             }
322
323         }
324
325     }
326
327     /**
328      * Tests this renderer for equality with an arbitrary object.
329      *
330      * @param obj the object (<code>null</code> permitted).
331      *
332      * @return A boolean.
333      */

334     public boolean equals(Object JavaDoc obj) {
335         if (obj == this) {
336             return true;
337         }
338         if (!(obj instanceof StatisticalLineAndShapeRenderer)) {
339             return false;
340         }
341         if (!super.equals(obj)) {
342             return false;
343         }
344         StatisticalLineAndShapeRenderer that
345             = (StatisticalLineAndShapeRenderer) obj;
346         if (!PaintUtilities.equal(this.errorIndicatorPaint,
347                 that.errorIndicatorPaint)) {
348             return false;
349         }
350         return true;
351     }
352     
353     /**
354      * Provides serialization support.
355      *
356      * @param stream the output stream.
357      *
358      * @throws IOException if there is an I/O error.
359      */

360     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
361         stream.defaultWriteObject();
362         SerialUtilities.writePaint(this.errorIndicatorPaint, stream);
363     }
364
365     /**
366      * Provides serialization support.
367      *
368      * @param stream the input stream.
369      *
370      * @throws IOException if there is an I/O error.
371      * @throws ClassNotFoundException if there is a classpath problem.
372      */

373     private void readObject(ObjectInputStream JavaDoc stream)
374         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
375         stream.defaultReadObject();
376         this.errorIndicatorPaint = SerialUtilities.readPaint(stream);
377     }
378
379 }
380
Popular Tags