KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > statistics > DefaultBoxAndWhiskerXYDataset


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, 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 License
20  * along with this library; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
24  * in the United States and other countries.]
25  *
26  * ----------------------------------
27  * DefaultBoxAndWhiskerXYDataset.java
28  * ----------------------------------
29  * (C) Copyright 2003-2005, by David Browning and Contributors.
30  *
31  * Original Author: David Browning (for Australian Institute of Marine
32  * Science);
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  *
35  * $Id: DefaultBoxAndWhiskerXYDataset.java,v 1.10 2005/05/20 08:58:08 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 05-Aug-2003 : Version 1, contributed by David Browning (DG);
40  * 08-Aug-2003 : Minor changes to comments (DB)
41  * Allow average to be null - average is a perculiar AIMS
42  * requirement which probably should be stripped out and overlaid
43  * if required...
44  * Added a number of methods to allow the max and min non-outlier
45  * and non-farout values to be calculated
46  * 12-Aug-2003 Changed the getYValue to return the highest outlier value
47  * Added getters and setters for outlier and farout coefficients
48  * 27-Aug-2003 : Renamed DefaultBoxAndWhiskerDataset
49  * --> DefaultBoxAndWhiskerXYDataset (DG);
50  * 06-May-2004 : Now extends AbstractXYDataset (DG);
51  * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
52  * getYValue() (DG);
53  * 18-Nov-2004 : Updated for changes in RangeInfo interface (DG);
54  * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0
55  * release (DG);
56  *
57  */

58
59 package org.jfree.data.statistics;
60
61 import java.util.ArrayList JavaDoc;
62 import java.util.Date JavaDoc;
63 import java.util.List JavaDoc;
64
65 import org.jfree.data.Range;
66 import org.jfree.data.RangeInfo;
67 import org.jfree.data.xy.AbstractXYDataset;
68
69 /**
70  * A simple implementation of the {@link BoxAndWhiskerXYDataset}. The dataset
71  * can hold only one series.
72  *
73  * @author David Browning
74  */

75 public class DefaultBoxAndWhiskerXYDataset extends AbstractXYDataset
76                                            implements BoxAndWhiskerXYDataset,
77                                                       RangeInfo {
78
79     /** The series key. */
80     private Comparable JavaDoc seriesKey;
81
82     /** Storage for the dates. */
83     private List JavaDoc dates;
84
85     /** Storage for the box and whisker statistics. */
86     private List JavaDoc items;
87
88     /** The minimum range value. */
89     private Number JavaDoc minimumRangeValue;
90
91     /** The maximum range value. */
92     private Number JavaDoc maximumRangeValue;
93
94     /** The range of values. */
95     private Range rangeBounds;
96
97     /**
98      * The coefficient used to calculate outliers. Tukey's default value is
99      * 1.5 (see EDA) Any value which is greater than Q3 + (interquartile range
100      * * outlier coefficient) is considered to be an outlier. Can be altered
101      * if the data is particularly skewed.
102      */

103     private double outlierCoefficient = 1.5;
104
105     /**
106      * The coefficient used to calculate farouts. Tukey's default value is 2
107      * (see EDA) Any value which is greater than Q3 + (interquartile range *
108      * farout coefficient) is considered to be a farout. Can be altered if the
109      * data is particularly skewed.
110      */

111     private double faroutCoefficient = 2.0;
112
113     /**
114      * Constructs a new box and whisker dataset.
115      * <p>
116      * The current implementation allows only one series in the dataset.
117      * This may be extended in a future version.
118      *
119      * @param seriesKey the key for the series.
120      */

121     public DefaultBoxAndWhiskerXYDataset(Comparable JavaDoc seriesKey) {
122         this.seriesKey = seriesKey;
123         this.dates = new ArrayList JavaDoc();
124         this.items = new ArrayList JavaDoc();
125         this.minimumRangeValue = null;
126         this.maximumRangeValue = null;
127         this.rangeBounds = null;
128     }
129
130     /**
131      * Adds an item to the dataset.
132      *
133      * @param date the date.
134      * @param item the item.
135      */

136     public void add(Date JavaDoc date, BoxAndWhiskerItem item) {
137         this.dates.add(date);
138         this.items.add(item);
139         if (this.minimumRangeValue == null) {
140             this.minimumRangeValue = item.getMinRegularValue();
141         }
142         else {
143             if (item.getMinRegularValue().doubleValue()
144                     < this.minimumRangeValue.doubleValue()) {
145                 this.minimumRangeValue = item.getMinRegularValue();
146             }
147         }
148         if (this.maximumRangeValue == null) {
149             this.maximumRangeValue = item.getMaxRegularValue();
150         }
151         else {
152             if (item.getMaxRegularValue().doubleValue()
153                     > this.maximumRangeValue.doubleValue()) {
154                 this.maximumRangeValue = item.getMaxRegularValue();
155             }
156         }
157         this.rangeBounds = new Range(
158             this.minimumRangeValue.doubleValue(),
159             this.maximumRangeValue.doubleValue()
160         );
161     }
162     
163     /**
164      * Returns the name of the series stored in this dataset.
165      *
166      * @param i the index of the series. Currently ignored.
167      *
168      * @return The name of this series.
169      */

170     public Comparable JavaDoc getSeriesKey(int i) {
171         return this.seriesKey;
172     }
173     
174     /**
175      * Return an item from within the dataset.
176      *
177      * @param series the series index (ignored, since this dataset contains
178      * only one series).
179      * @param item the item within the series (zero-based index)
180      *
181      * @return The item.
182      */

183     public BoxAndWhiskerItem getItem(int series, int item) {
184         return (BoxAndWhiskerItem) this.items.get(item);
185     }
186
187     /**
188      * Returns the x-value for one item in a series.
189      * <p>
190      * The value returned is a Long object generated from the underlying Date
191      * object.
192      *
193      * @param series the series (zero-based index).
194      * @param item the item (zero-based index).
195      *
196      * @return The x-value.
197      */

198     public Number JavaDoc getX(int series, int item) {
199         return new Long JavaDoc(((Date JavaDoc) this.dates.get(item)).getTime());
200     }
201
202     /**
203      * Returns the x-value for one item in a series, as a Date.
204      * <p>
205      * This method is provided for convenience only.
206      *
207      * @param series the series (zero-based index).
208      * @param item the item (zero-based index).
209      *
210      * @return The x-value as a Date.
211      */

212     public Date JavaDoc getXDate(int series, int item) {
213         return (Date JavaDoc) this.dates.get(item);
214     }
215
216     /**
217      * Returns the y-value for one item in a series.
218      * <p>
219      * This method (from the XYDataset interface) is mapped to the
220      * getMaxNonOutlierValue() method.
221      *
222      * @param series the series (zero-based index).
223      * @param item the item (zero-based index).
224      *
225      * @return The y-value.
226      */

227     public Number JavaDoc getY(int series, int item) {
228         return new Double JavaDoc(getMeanValue(series, item).doubleValue());
229     }
230
231     /**
232      * Returns the mean for the specified series and item.
233      *
234      * @param series the series (zero-based index).
235      * @param item the item (zero-based index).
236      *
237      * @return The mean for the specified series and item.
238      */

239     public Number JavaDoc getMeanValue(int series, int item) {
240         Number JavaDoc result = null;
241         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
242         if (stats != null) {
243             result = stats.getMean();
244         }
245         return result;
246     }
247
248     /**
249      * Returns the median-value for the specified series and item.
250      *
251      * @param series the series (zero-based index).
252      * @param item the item (zero-based index).
253      *
254      * @return The median-value for the specified series and item.
255      */

256     public Number JavaDoc getMedianValue(int series, int item) {
257         Number JavaDoc result = null;
258         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
259         if (stats != null) {
260             result = stats.getMedian();
261         }
262         return result;
263     }
264
265     /**
266      * Returns the Q1 median-value for the specified series and item.
267      *
268      * @param series the series (zero-based index).
269      * @param item the item (zero-based index).
270      *
271      * @return The Q1 median-value for the specified series and item.
272      */

273     public Number JavaDoc getQ1Value(int series, int item) {
274         Number JavaDoc result = null;
275         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
276         if (stats != null) {
277             result = stats.getQ1();
278         }
279         return result;
280     }
281
282     /**
283      * Returns the Q3 median-value for the specified series and item.
284      *
285      * @param series the series (zero-based index).
286      * @param item the item (zero-based index).
287      *
288      * @return The Q3 median-value for the specified series and item.
289      */

290     public Number JavaDoc getQ3Value(int series, int item) {
291         Number JavaDoc result = null;
292         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
293         if (stats != null) {
294             result = stats.getQ3();
295         }
296         return result;
297     }
298
299     /**
300      * Returns the min-value for the specified series and item.
301      *
302      * @param series the series (zero-based index).
303      * @param item the item (zero-based index).
304      *
305      * @return The min-value for the specified series and item.
306      */

307     public Number JavaDoc getMinRegularValue(int series, int item) {
308         Number JavaDoc result = null;
309         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
310         if (stats != null) {
311             result = stats.getMinRegularValue();
312         }
313         return result;
314     }
315
316     /**
317      * Returns the max-value for the specified series and item.
318      *
319      * @param series the series (zero-based index).
320      * @param item the item (zero-based index).
321      *
322      * @return The max-value for the specified series and item.
323      */

324     public Number JavaDoc getMaxRegularValue(int series, int item) {
325         Number JavaDoc result = null;
326         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
327         if (stats != null) {
328             result = stats.getMaxRegularValue();
329         }
330         return result;
331     }
332
333     /**
334      * Returns the minimum value which is not a farout.
335      * @param series the series (zero-based index).
336      * @param item the item (zero-based index).
337      *
338      * @return A <code>Number</code> representing the maximum non-farout value.
339      */

340     public Number JavaDoc getMinOutlier(int series, int item) {
341         Number JavaDoc result = null;
342         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
343         if (stats != null) {
344             result = stats.getMinOutlier();
345         }
346         return result;
347     }
348  
349     /**
350      * Returns the maximum value which is not a farout, ie Q3 + (interquartile
351      * range * farout coefficient).
352      *
353      * @param series the series (zero-based index).
354      * @param item the item (zero-based index).
355      *
356      * @return A <code>Number</code> representing the maximum non-farout value.
357      */

358     public Number JavaDoc getMaxOutlier(int series, int item) {
359         Number JavaDoc result = null;
360         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
361         if (stats != null) {
362             result = stats.getMaxOutlier();
363         }
364         return result;
365     }
366
367     /**
368      * Returns an array of outliers for the specified series and item.
369      *
370      * @param series the series (zero-based index).
371      * @param item the item (zero-based index).
372      *
373      * @return The array of outliers for the specified series and item.
374      */

375     public List JavaDoc getOutliers(int series, int item) {
376         List JavaDoc result = null;
377         BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
378         if (stats != null) {
379             result = stats.getOutliers();
380         }
381         return result;
382     }
383
384     /**
385      * Returns the value used as the outlier coefficient. The outlier
386      * coefficient gives an indication of the degree of certainty in an
387      * unskewed distribution. Increasing the coefficient increases the number
388      * of values included. Currently only used to ensure farout coefficient is
389      * greater than the outlier coefficient
390      *
391      * @return A <code>double</code> representing the value used to calculate
392      * outliers.
393      */

394     public double getOutlierCoefficient() {
395         return this.outlierCoefficient;
396     }
397
398     /**
399      * Returns the value used as the farout coefficient. The farout coefficient
400      * allows the calculation of which values will be off the graph.
401      *
402      * @return A <code>double</code> representing the value used to calculate
403      * farouts.
404      */

405     public double getFaroutCoefficient() {
406         return this.faroutCoefficient;
407     }
408
409     /**
410      * Returns the number of series in the dataset.
411      * <p>
412      * This implementation only allows one series.
413      *
414      * @return The number of series.
415      */

416     public int getSeriesCount() {
417         return 1;
418     }
419
420     /**
421      * Returns the number of items in the specified series.
422      *
423      * @param series the index (zero-based) of the series.
424      *
425      * @return The number of items in the specified series.
426      */

427     public int getItemCount(int series) {
428         return this.dates.size();
429     }
430
431     /**
432      * Sets the value used as the outlier coefficient
433      *
434      * @param outlierCoefficient being a <code>double</code> representing the
435      * value used to calculate outliers.
436      */

437     public void setOutlierCoefficient(double outlierCoefficient) {
438         this.outlierCoefficient = outlierCoefficient;
439     }
440
441     /**
442      * Sets the value used as the farouts coefficient. The farout coefficient
443      * must b greater than the outlier coefficient.
444      *
445      * @param faroutCoefficient being a <code>double</code> representing the
446      * value used to calculate farouts.
447      */

448     public void setFaroutCoefficient(double faroutCoefficient) {
449
450         if (faroutCoefficient > getOutlierCoefficient()) {
451             this.faroutCoefficient = faroutCoefficient;
452         }
453         else {
454             throw new IllegalArgumentException JavaDoc("Farout value must be greater "
455                 + "than the outlier value, which is currently set at: ("
456                 + getOutlierCoefficient() + ")");
457         }
458     }
459
460     /**
461      * Returns the minimum y-value in the dataset.
462      *
463      * @param includeInterval a flag that determines whether or not the
464      * y-interval is taken into account.
465      *
466      * @return The minimum value.
467      */

468     public double getRangeLowerBound(boolean includeInterval) {
469         double result = Double.NaN;
470         if (this.minimumRangeValue != null) {
471             result = this.minimumRangeValue.doubleValue();
472         }
473         return result;
474     }
475
476     /**
477      * Returns the maximum y-value in the dataset.
478      *
479      * @param includeInterval a flag that determines whether or not the
480      * y-interval is taken into account.
481      *
482      * @return The maximum value.
483      */

484     public double getRangeUpperBound(boolean includeInterval) {
485         double result = Double.NaN;
486         if (this.maximumRangeValue != null) {
487             result = this.maximumRangeValue.doubleValue();
488         }
489         return result;
490     }
491
492     /**
493      * Returns the range of the values in this dataset's range.
494      *
495      * @param includeInterval a flag that determines whether or not the
496      * y-interval is taken into account.
497      *
498      * @return The range.
499      */

500     public Range getRangeBounds(boolean includeInterval) {
501         return this.rangeBounds;
502     }
503
504 }
505
Popular Tags