KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > HistogramDataset


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  * HistogramDataset.java
24  * ---------------------
25  * (C) Copyright 2003, by Jelai Wang and Contributors.
26  *
27  * Original Author: Jelai Wang (jelaiw AT mindspring.com);
28  * Contributor(s): David Gilbert (for Object Refinery Limited);
29  *
30  * $Id: HistogramDataset.java,v 1.7 2003/11/03 14:20:04 mungady Exp $
31  *
32  * Changes
33  * -------
34  * 06-Jul-2003 : Version 1, contributed by Jelai Wang (DG);
35  * 07-Jul-2003 : Changed package and added Javadocs (DG);
36  * 15-Oct-2003 : Updated Javadocs and removed array sorting (JW);
37  *
38  */

39
40 package org.jfree.data;
41
42 import java.util.ArrayList JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.List JavaDoc;
45 import java.util.Map JavaDoc;
46
47 /**
48  * A dataset that can be used for creating histograms.
49  * <p>
50  * See the <code>HistogramDemo.java</code> file in the JFreeChart distribution for an example.
51  *
52  * @author Jelai Wang, jelaiw AT mindspring.com
53  */

54 public class HistogramDataset extends AbstractDataset implements IntervalXYDataset {
55
56     /** A constant to indicate a frequency histogram, also the default. */
57     public final static HistogramType FREQUENCY = new HistogramType();
58     
59     /** A constant to indicate a relative frequency histogram. */
60     public static HistogramType RELATIVE_FREQUENCY = new HistogramType();
61     
62     /** A constant to indicate a histogram where the total area is scaled to 1. */
63     public static HistogramType SCALE_AREA_TO_1 = new HistogramType();
64
65     /** A list of maps. */
66     private List JavaDoc list = new ArrayList JavaDoc();
67     
68     /** The histogram type. */
69     private HistogramType type = FREQUENCY;
70
71     /**
72      * Sets the histogram type.
73      *
74      * @param type the type (<code>null</code> not permitted).
75      */

76     public void setType(HistogramType type) {
77         if (type == null) {
78             throw new IllegalArgumentException JavaDoc(
79                 "HistogramDataset.setType(...): null not permitted.");
80         }
81         this.type = type;
82     }
83
84     /**
85      * Returns the histogram type.
86      *
87      * @return The type.
88      */

89     public HistogramType getType() {
90         return type;
91     }
92
93     /**
94      * Adds a series.
95      *
96      * @param name the series name.
97      * @param values the values (<code>null</code> not permitted).
98      * @param numberOfBins the number of bins (must be at least 1).
99      */

100     public void addSeries(String JavaDoc name, double[] values, int numberOfBins) {
101         if (values == null) {
102             throw new IllegalArgumentException JavaDoc(
103                 "HistogramDataset.addSeries(...): 'values' argument must not be null."
104             );
105         }
106         else if (numberOfBins < 1) {
107             throw new IllegalArgumentException JavaDoc(
108                 "HistogramDataset.addSeries(...): number of bins must be at least 1"
109             );
110         }
111         // work out bin strategy
112
double minimum = getMinimum(values);
113         double maximum = getMaximum(values);
114         double binWidth = (maximum - minimum) / numberOfBins;
115         // set up the bins
116
double tmp = minimum;
117         HistogramBin[] bins = new HistogramBin[numberOfBins];
118         for (int i = 0; i < bins.length; i++) {
119             HistogramBin bin = new HistogramBin(tmp, tmp + binWidth);
120             tmp = tmp + binWidth;
121             bins[i] = bin;
122         }
123         // fill the bins
124
for (int i = 0; i < values.length; i++) {
125             for (int j = 0; j < bins.length; j++) {
126                 if (values[i] >= bins[j].getStartBoundary()
127                     && values[i] <= bins[j].getEndBoundary()) {
128                     // note the greedy <=
129
bins[j].incrementCount();
130                     break; // break out of inner loop
131
}
132             }
133         }
134         // generic map for each series
135
Map JavaDoc map = new HashMap JavaDoc();
136         map.put("name", name);
137         map.put("bins", bins);
138         map.put("values.length", new Integer JavaDoc(values.length));
139         map.put("bin width", new Double JavaDoc(binWidth));
140         list.add(map);
141     }
142
143     /**
144      * Returns the minimum value from an array.
145      *
146      * @param values the values.
147      *
148      * @return The minimum value.
149      */

150     private double getMinimum(double[] values) {
151         if (values == null || values.length < 1) {
152             throw new IllegalArgumentException JavaDoc();
153         }
154
155         double min = Double.MAX_VALUE;
156         for (int i = 0; i < values.length; i++) {
157             if (values[i] < min) {
158                 min = values[i];
159             }
160         }
161         return min;
162     }
163
164     /**
165      * Returns the maximum value from an array.
166      *
167      * @param values the values.
168      *
169      * @return The maximum value.
170      */

171     private double getMaximum(double[] values) {
172         if (values == null || values.length < 1) {
173             throw new IllegalArgumentException JavaDoc();
174         }
175
176         double max = -Double.MAX_VALUE;
177         for (int i = 0; i < values.length; i++) {
178             if (values[i] > max) {
179                 max = values[i];
180             }
181         }
182         return max;
183     }
184
185     /**
186      * Returns the bins for a series.
187      *
188      * @param series the series index.
189      *
190      * @return An array of bins.
191      */

192     HistogramBin[] getBins(int series) {
193         Map JavaDoc map = (Map JavaDoc) list.get(series);
194         return (HistogramBin[]) map.get("bins");
195     }
196
197     /**
198      * Returns the total number of observations for a series.
199      *
200      * @param series the series index.
201      *
202      * @return The total.
203      */

204     private int getTotal(int series) {
205         Map JavaDoc map = (Map JavaDoc) list.get(series);
206         return ((Integer JavaDoc) map.get("values.length")).intValue();
207     }
208
209     /**
210      * Returns the bin width for a series.
211      *
212      * @param series the series index (zero based).
213      *
214      * @return The bin width.
215      */

216     private double getBinWidth(int series) {
217         Map JavaDoc map = (Map JavaDoc) list.get(series);
218         return ((Double JavaDoc) map.get("bin width")).doubleValue();
219     }
220
221     /**
222      * Returns the number of series in the dataset.
223      *
224      * @return The series count.
225      */

226     public int getSeriesCount() {
227         return list.size();
228     }
229     
230     /**
231      * Returns the name for a series.
232      *
233      * @param series the series index (zero based).
234      *
235      * @return The series name.
236      */

237     public String JavaDoc getSeriesName(int series) {
238         Map JavaDoc map = (Map JavaDoc) list.get(series);
239         return (String JavaDoc) map.get("name");
240     }
241
242     /**
243      * Returns the number of data items for a series.
244      *
245      * @param series the series index (zero based).
246      *
247      * @return The item count.
248      */

249     public int getItemCount(int series) {
250         return getBins(series).length;
251     }
252
253     /**
254      * Returns the X value for a bin.
255      * <p>
256      * This value won't be used for plotting histograms, since the renderer will ignore it.
257      * But other renderers can use it (for example, you could use the dataset to create a line
258      * chart).
259      *
260      * @param series the series index (zero based).
261      * @param item the item index (zero based).
262      *
263      * @return The start value.
264      */

265     public Number JavaDoc getXValue(int series, int item) {
266         HistogramBin[] bins = getBins(series);
267         HistogramBin bin = bins[item];
268         double x = (bin.getStartBoundary() + bin.getEndBoundary()) / 2.;
269         return new Double JavaDoc(x);
270     }
271
272     /**
273      * Returns the Y value for a bin.
274      *
275      * @param series the series index (zero based).
276      * @param item the item index (zero based).
277      *
278      * @return The Y value.
279      */

280     public Number JavaDoc getYValue(int series, int item) {
281         HistogramBin[] bins = getBins(series);
282         double total = getTotal(series);
283         double binWidth = getBinWidth(series);
284
285         if (type == FREQUENCY) {
286             return new Double JavaDoc(bins[item].getCount());
287         }
288         else if (type == RELATIVE_FREQUENCY) {
289             return new Double JavaDoc(bins[item].getCount() / total);
290         }
291         else if (type == SCALE_AREA_TO_1) {
292             return new Double JavaDoc(bins[item].getCount() / (binWidth * total));
293         }
294         else { // pretty sure this shouldn't ever happen
295
throw new IllegalStateException JavaDoc();
296         }
297     }
298
299     /**
300      * Returns the start value for a bin.
301      *
302      * @param series the series index (zero based).
303      * @param item the item index (zero based).
304      *
305      * @return The start value.
306      */

307     public Number JavaDoc getStartXValue(int series, int item) {
308         HistogramBin[] bins = getBins(series);
309         return new Double JavaDoc(bins[item].getStartBoundary());
310     }
311
312     /**
313      * Returns the end value for a bin.
314      *
315      * @param series the series index (zero based).
316      * @param item the item index (zero based).
317      *
318      * @return The end value.
319      */

320     public Number JavaDoc getEndXValue(int series, int item) {
321         HistogramBin[] bins = getBins(series);
322         return new Double JavaDoc(bins[item].getEndBoundary());
323     }
324
325     /**
326      * Returns the Y value for a bin.
327      *
328      * @param series the series index (zero based).
329      * @param item the item index (zero based).
330      *
331      * @return The Y value.
332      */

333     public Number JavaDoc getStartYValue(int series, int item) {
334         //HistogramBin[] bins = getBins(series);
335
return getYValue(series, item);
336     }
337
338     /**
339      * Returns the Y value for a bin.
340      *
341      * @param series the series index (zero based).
342      * @param item the item index (zero based).
343      *
344      * @return The Y value.
345      */

346     public Number JavaDoc getEndYValue(int series, int item) {
347         //HistogramBin[] bins = getBins(series);
348
return getYValue(series, item);
349     }
350
351     /**
352      * A class for creating constants to represent the histogram type. See Bloch's enum tip in
353      * 'Effective Java'
354      */

355     private static class HistogramType {
356         /**
357          * Creates a new type.
358          */

359         private HistogramType() {
360         }
361     }
362
363 }
364
Popular Tags