KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > xy > DefaultWindDataset


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  * DefaultWindDataset.java
29  * -----------------------
30  * (C) Copyright 2001-2006, by Achilleus Mantzios and Contributors.
31  *
32  * Original Author: Achilleus Mantzios;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  *
35  * $Id: DefaultWindDataset.java,v 1.5.2.2 2006/07/12 13:50:48 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 06-Feb-2002 : Version 1, based on code contributed by Achilleus
40  * Mantzios (DG);
41  * 05-May-2004 : Now extends AbstractXYDataset (DG);
42  * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
43  * getYValue() (DG);
44  *
45  */

46
47 package org.jfree.data.xy;
48
49 import java.io.Serializable JavaDoc;
50 import java.util.Arrays JavaDoc;
51 import java.util.Collections JavaDoc;
52 import java.util.Date JavaDoc;
53 import java.util.List JavaDoc;
54
55 /**
56  * A default implementation of the {@link WindDataset} interface.
57  */

58 public class DefaultWindDataset extends AbstractXYDataset
59                                 implements WindDataset {
60
61     /** The keys for the series. */
62     private List JavaDoc seriesKeys;
63
64     /** Storage for the series data. */
65     private List JavaDoc allSeriesData;
66
67     /**
68      * Constructs a new, empty, dataset. Since there are currently no methods
69      * to add data to an existing dataset, you should probably use a different
70      * constructor.
71      */

72     public DefaultWindDataset() {
73         this.seriesKeys = new java.util.ArrayList JavaDoc();
74         this.allSeriesData = new java.util.ArrayList JavaDoc();
75     }
76
77     /**
78      * Constructs a dataset based on the specified data array.
79      *
80      * @param data the data (<code>null</code> not permitted).
81      *
82      * @throws NullPointerException if <code>data</code> is <code>null</code>.
83      */

84     public DefaultWindDataset(Object JavaDoc[][][] data) {
85         this(seriesNameListFromDataArray(data), data);
86     }
87
88     /**
89      * Constructs a dataset based on the specified data array.
90      *
91      * @param seriesNames the names of the series (<code>null</code> not
92      * permitted).
93      * @param data the wind data.
94      *
95      * @throws NullPointerException if <code>seriesNames</code> is
96      * <code>null</code>.
97      */

98     public DefaultWindDataset(String JavaDoc[] seriesNames, Object JavaDoc[][][] data) {
99         this(Arrays.asList(seriesNames), data);
100     }
101
102     /**
103      * Constructs a dataset based on the specified data array. The array
104      * can contain multiple series, each series can contain multiple items,
105      * and each item is as follows:
106      * <ul>
107      * <li><code>data[series][item][0]</code> - the date (either a
108      * <code>Date</code> or a <code>Number</code> that is the milliseconds
109      * since 1-Jan-1970);</li>
110      * <li><code>data[series][item][1]</code> - the wind direction (1 - 12,
111      * like the numbers on a clock face);</li>
112      * <li><code>data[series][item][2]</code> - the wind force (1 - 12 on the
113      * Beaufort scale)</li>
114      * </ul>
115      *
116      * @param seriesKeys the names of the series (<code>null</code> not
117      * permitted).
118      * @param data the wind dataset (<code>null</code> not permitted).
119      *
120      * @throws IllegalArgumentException if <code>seriesKeys</code> is
121      * <code>null</code>.
122      * @throws IllegalArgumentException if the number of series keys does not
123      * match the number of series in the array.
124      * @throws NullPointerException if <code>data</code> is <code>null</code>.
125      */

126     public DefaultWindDataset(List JavaDoc seriesKeys, Object JavaDoc[][][] data) {
127         if (seriesKeys == null) {
128             throw new IllegalArgumentException JavaDoc("Null 'seriesKeys' argument.");
129         }
130         if (seriesKeys.size() != data.length) {
131             throw new IllegalArgumentException JavaDoc("The number of series keys does "
132                     + "not match the number of series in the data array.");
133         }
134         this.seriesKeys = seriesKeys;
135         int seriesCount = data.length;
136         this.allSeriesData = new java.util.ArrayList JavaDoc(seriesCount);
137
138         for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) {
139             List JavaDoc oneSeriesData = new java.util.ArrayList JavaDoc();
140             int maxItemCount = data[seriesIndex].length;
141             for (int itemIndex = 0; itemIndex < maxItemCount; itemIndex++) {
142                 Object JavaDoc xObject = data[seriesIndex][itemIndex][0];
143                 if (xObject != null) {
144                     Number JavaDoc xNumber;
145                     if (xObject instanceof Number JavaDoc) {
146                         xNumber = (Number JavaDoc) xObject;
147                     }
148                     else {
149                         if (xObject instanceof Date JavaDoc) {
150                             Date JavaDoc xDate = (Date JavaDoc) xObject;
151                             xNumber = new Long JavaDoc(xDate.getTime());
152                         }
153                         else {
154                             xNumber = new Integer JavaDoc(0);
155                         }
156                     }
157                     Number JavaDoc windDir = (Number JavaDoc) data[seriesIndex][itemIndex][1];
158                     Number JavaDoc windForce = (Number JavaDoc) data[seriesIndex][itemIndex][2];
159                     oneSeriesData.add(new WindDataItem(xNumber, windDir,
160                             windForce));
161                 }
162             }
163             Collections.sort(oneSeriesData);
164             this.allSeriesData.add(seriesIndex, oneSeriesData);
165         }
166
167     }
168
169     /**
170      * Returns the number of series in the dataset.
171      *
172      * @return The series count.
173      */

174     public int getSeriesCount() {
175         return this.allSeriesData.size();
176     }
177
178     /**
179      * Returns the number of items in a series.
180      *
181      * @param series the series (zero-based index).
182      *
183      * @return The item count.
184      */

185     public int getItemCount(int series) {
186         if (series < 0 || series >= getSeriesCount()) {
187             throw new IllegalArgumentException JavaDoc("Invalid series index: "
188                     + series);
189         }
190         List JavaDoc oneSeriesData = (List JavaDoc) this.allSeriesData.get(series);
191         return oneSeriesData.size();
192     }
193
194     /**
195      * Returns the key for a series.
196      *
197      * @param series the series (zero-based index).
198      *
199      * @return The series key.
200      */

201     public Comparable JavaDoc getSeriesKey(int series) {
202         if (series < 0 || series >= getSeriesCount()) {
203             throw new IllegalArgumentException JavaDoc("Invalid series index: "
204                     + series);
205         }
206         return (Comparable JavaDoc) this.seriesKeys.get(series);
207     }
208
209     /**
210      * Returns the x-value for one item within a series. This should represent
211      * a point in time, encoded as milliseconds in the same way as
212      * java.util.Date.
213      *
214      * @param series the series (zero-based index).
215      * @param item the item (zero-based index).
216      *
217      * @return The x-value for the item within the series.
218      */

219     public Number JavaDoc getX(int series, int item) {
220         List JavaDoc oneSeriesData = (List JavaDoc) this.allSeriesData.get(series);
221         WindDataItem windItem = (WindDataItem) oneSeriesData.get(item);
222         return windItem.getX();
223     }
224
225     /**
226      * Returns the y-value for one item within a series. This maps to the
227      * {@link #getWindForce(int, int)} method and is implemented because
228      * <code>WindDataset</code> is an extension of {@link XYDataset}.
229      *
230      * @param series the series (zero-based index).
231      * @param item the item (zero-based index).
232      *
233      * @return The y-value for the item within the series.
234      */

235     public Number JavaDoc getY(int series, int item) {
236         return getWindForce(series, item);
237     }
238
239     /**
240      * Returns the wind direction for one item within a series. This is a
241      * number between 0 and 12, like the numbers on an upside-down clock face.
242      *
243      * @param series the series (zero-based index).
244      * @param item the item (zero-based index).
245      *
246      * @return The wind direction for the item within the series.
247      */

248     public Number JavaDoc getWindDirection(int series, int item) {
249         List JavaDoc oneSeriesData = (List JavaDoc) this.allSeriesData.get(series);
250         WindDataItem windItem = (WindDataItem) oneSeriesData.get(item);
251         return windItem.getWindDirection();
252     }
253
254     /**
255      * Returns the wind force for one item within a series. This is a number
256      * between 0 and 12, as defined by the Beaufort scale.
257      *
258      * @param series the series (zero-based index).
259      * @param item the item (zero-based index).
260      *
261      * @return The wind force for the item within the series.
262      */

263     public Number JavaDoc getWindForce(int series, int item) {
264         List JavaDoc oneSeriesData = (List JavaDoc) this.allSeriesData.get(series);
265         WindDataItem windItem = (WindDataItem) oneSeriesData.get(item);
266         return windItem.getWindForce();
267     }
268
269     /**
270      * Utility method for automatically generating series names.
271      *
272      * @param data the wind data (<code>null</code> not permitted).
273      *
274      * @return An array of <i>Series N</i> with N = { 1 .. data.length }.
275      *
276      * @throws NullPointerException if <code>data</code> is <code>null</code>.
277      */

278     public static List JavaDoc seriesNameListFromDataArray(Object JavaDoc[][] data) {
279
280         int seriesCount = data.length;
281         List JavaDoc seriesNameList = new java.util.ArrayList JavaDoc(seriesCount);
282         for (int i = 0; i < seriesCount; i++) {
283             seriesNameList.add("Series " + (i + 1));
284         }
285         return seriesNameList;
286
287     }
288     
289     /**
290      * Checks this <code>WindDataset</code> for equality with an arbitrary
291      * object. This method returns <code>true</code> if and only if:
292      * <ul>
293      * <li><code>obj</code> is not <code>null</code>;</li>
294      * <li><code>obj</code> is an instance of
295      * <code>DefaultWindDataset</code>;</li>
296      * <li>both datasets have the same number of series containing identical
297      * values.</li>
298      * <ul>
299      *
300      * @param obj the object (<code>null</code> permitted).
301      *
302      * @return A boolean.
303      */

304     public boolean equals(Object JavaDoc obj) {
305         if (this == obj) {
306             return true;
307         }
308         if (! (obj instanceof DefaultWindDataset)) {
309             return false;
310         }
311         DefaultWindDataset that = (DefaultWindDataset) obj;
312         if (!this.seriesKeys.equals(that.seriesKeys)) {
313             return false;
314         }
315         if (!this.allSeriesData.equals(that.allSeriesData)) {
316             return false;
317         }
318         return true;
319     }
320
321 }
322
323 /**
324  * A wind data item.
325  *
326  * @author Achilleus Mantzios
327  */

328 class WindDataItem implements Comparable JavaDoc, Serializable JavaDoc {
329
330     /** The x-value. */
331     private Number JavaDoc x;
332
333     /** The wind direction. */
334     private Number JavaDoc windDir;
335
336     /** The wind force. */
337     private Number JavaDoc windForce;
338
339     /**
340      * Creates a new wind data item.
341      *
342      * @param x the x-value.
343      * @param windDir the direction.
344      * @param windForce the force.
345      */

346     public WindDataItem(Number JavaDoc x, Number JavaDoc windDir, Number JavaDoc windForce) {
347         this.x = x;
348         this.windDir = windDir;
349         this.windForce = windForce;
350     }
351
352     /**
353      * Returns the x-value.
354      *
355      * @return The x-value.
356      */

357     public Number JavaDoc getX() {
358         return this.x;
359     }
360
361     /**
362      * Returns the wind direction.
363      *
364      * @return The wind direction.
365      */

366     public Number JavaDoc getWindDirection() {
367         return this.windDir;
368     }
369
370     /**
371      * Returns the wind force.
372      *
373      * @return The wind force.
374      */

375     public Number JavaDoc getWindForce() {
376         return this.windForce;
377     }
378
379     /**
380      * Compares this item to another object.
381      *
382      * @param object the other object.
383      *
384      * @return An int that indicates the relative comparison.
385      */

386     public int compareTo(Object JavaDoc object) {
387         if (object instanceof WindDataItem) {
388             WindDataItem item = (WindDataItem) object;
389             if (this.x.doubleValue() > item.x.doubleValue()) {
390                 return 1;
391             }
392             else if (this.x.equals(item.x)) {
393                 return 0;
394             }
395             else {
396                 return -1;
397             }
398         }
399         else {
400             throw new ClassCastException JavaDoc("WindDataItem.compareTo(error)");
401         }
402     }
403     
404     /**
405      * Tests this <code>WindDataItem</code> for equality with an arbitrary
406      * object.
407      *
408      * @param obj the object (<code>null</code> permitted).
409      *
410      * @return A boolean.
411      */

412     public boolean equals(Object JavaDoc obj) {
413         if (this == obj) {
414             return false;
415         }
416         if (! (obj instanceof WindDataItem)) {
417             return false;
418         }
419         WindDataItem that = (WindDataItem) obj;
420         if (!this.x.equals(that.x)) {
421             return false;
422         }
423         if (!this.windDir.equals(that.windDir)) {
424             return false;
425         }
426         if (!this.windForce.equals(that.windForce)) {
427             return false;
428         }
429         return true;
430     }
431
432 }
433
Popular Tags