KickJava   Java API By Example, From Geeks To Geeks.

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


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  * DefaultXYZDataset.java
29  * ----------------------
30  * (C) Copyright 2006, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): -;
34  *
35  * $Id: DefaultXYZDataset.java,v 1.1.2.3 2006/11/02 20:55:21 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 12-Jul-2006 : Version 1 (DG);
40  * 06-Oct-2006 : Fixed API doc warnings (DG);
41  * 02-Nov-2006 : Fixed a problem with adding a new series with the same key
42  * as an existing series (see bug 1589392) (DG);
43  *
44  */

45
46 package org.jfree.data.xy;
47
48 import java.util.ArrayList JavaDoc;
49 import java.util.Arrays JavaDoc;
50 import java.util.List JavaDoc;
51
52 import org.jfree.data.DomainOrder;
53 import org.jfree.data.general.DatasetChangeEvent;
54
55 /**
56  * A default implementation of the {@link XYZDataset} interface that stores
57  * data values in arrays of double primitives.
58  *
59  * @since 1.0.2
60  */

61 public class DefaultXYZDataset extends AbstractXYZDataset
62         implements XYZDataset {
63
64     /**
65      * Storage for the series keys. This list must be kept in sync with the
66      * seriesList.
67      */

68     private List JavaDoc seriesKeys;
69     
70     /**
71      * Storage for the series in the dataset. We use a list because the
72      * order of the series is significant. This list must be kept in sync
73      * with the seriesKeys list.
74      */

75     private List JavaDoc seriesList;
76     
77     /**
78      * Creates a new <code>DefaultXYZDataset</code> instance, initially
79      * containing no data.
80      */

81     public DefaultXYZDataset() {
82         this.seriesKeys = new java.util.ArrayList JavaDoc();
83         this.seriesList = new java.util.ArrayList JavaDoc();
84     }
85     
86     /**
87      * Returns the number of series in the dataset.
88      *
89      * @return The series count.
90      */

91     public int getSeriesCount() {
92         return this.seriesList.size();
93     }
94
95     /**
96      * Returns the key for a series.
97      *
98      * @param series the series index (in the range <code>0</code> to
99      * <code>getSeriesCount() - 1</code>).
100      *
101      * @return The key for the series.
102      *
103      * @throws IllegalArgumentException if <code>series</code> is not in the
104      * specified range.
105      */

106     public Comparable JavaDoc getSeriesKey(int series) {
107         if ((series < 0) || (series >= getSeriesCount())) {
108             throw new IllegalArgumentException JavaDoc("Series index out of bounds");
109         }
110         return (Comparable JavaDoc) this.seriesKeys.get(series);
111     }
112
113     /**
114      * Returns the index of the series with the specified key, or -1 if there
115      * is no such series in the dataset.
116      *
117      * @param seriesKey the series key (<code>null</code> permitted).
118      *
119      * @return The index, or -1.
120      */

121     public int indexOf(Comparable JavaDoc seriesKey) {
122         return this.seriesKeys.indexOf(seriesKey);
123     }
124
125     /**
126      * Returns the order of the domain (x-) values in the dataset. In this
127      * implementation, we cannot guarantee that the x-values are ordered, so
128      * this method returns <code>DomainOrder.NONE</code>.
129      *
130      * @return <code>DomainOrder.NONE</code>.
131      */

132     public DomainOrder getDomainOrder() {
133         return DomainOrder.NONE;
134     }
135
136     /**
137      * Returns the number of items in the specified series.
138      *
139      * @param series the series index (in the range <code>0</code> to
140      * <code>getSeriesCount() - 1</code>).
141      *
142      * @return The item count.
143      *
144      * @throws IllegalArgumentException if <code>series</code> is not in the
145      * specified range.
146      */

147     public int getItemCount(int series) {
148         if ((series < 0) || (series >= getSeriesCount())) {
149             throw new IllegalArgumentException JavaDoc("Series index out of bounds");
150         }
151         double[][] seriesArray = (double[][]) this.seriesList.get(series);
152         return seriesArray[0].length;
153     }
154
155     /**
156      * Returns the x-value for an item within a series.
157      *
158      * @param series the series index (in the range <code>0</code> to
159      * <code>getSeriesCount() - 1</code>).
160      * @param item the item index (in the range <code>0</code> to
161      * <code>getItemCount(series)</code>).
162      *
163      * @return The x-value.
164      *
165      * @throws ArrayIndexOutOfBoundsException if <code>series</code> is not
166      * within the specified range.
167      * @throws ArrayIndexOutOfBoundsException if <code>item</code> is not
168      * within the specified range.
169      *
170      * @see #getX(int, int)
171      */

172     public double getXValue(int series, int item) {
173         double[][] seriesData = (double[][]) this.seriesList.get(series);
174         return seriesData[0][item];
175     }
176
177     /**
178      * Returns the x-value for an item within a series.
179      *
180      * @param series the series index (in the range <code>0</code> to
181      * <code>getSeriesCount() - 1</code>).
182      * @param item the item index (in the range <code>0</code> to
183      * <code>getItemCount(series)</code>).
184      *
185      * @return The x-value.
186      *
187      * @throws ArrayIndexOutOfBoundsException if <code>series</code> is not
188      * within the specified range.
189      * @throws ArrayIndexOutOfBoundsException if <code>item</code> is not
190      * within the specified range.
191      *
192      * @see #getXValue(int, int)
193      */

194     public Number JavaDoc getX(int series, int item) {
195         return new Double JavaDoc(getXValue(series, item));
196     }
197
198     /**
199      * Returns the y-value for an item within a series.
200      *
201      * @param series the series index (in the range <code>0</code> to
202      * <code>getSeriesCount() - 1</code>).
203      * @param item the item index (in the range <code>0</code> to
204      * <code>getItemCount(series)</code>).
205      *
206      * @return The y-value.
207      *
208      * @throws ArrayIndexOutOfBoundsException if <code>series</code> is not
209      * within the specified range.
210      * @throws ArrayIndexOutOfBoundsException if <code>item</code> is not
211      * within the specified range.
212      *
213      * @see #getY(int, int)
214      */

215     public double getYValue(int series, int item) {
216         double[][] seriesData = (double[][]) this.seriesList.get(series);
217         return seriesData[1][item];
218     }
219
220     /**
221      * Returns the y-value for an item within a series.
222      *
223      * @param series the series index (in the range <code>0</code> to
224      * <code>getSeriesCount() - 1</code>).
225      * @param item the item index (in the range <code>0</code> to
226      * <code>getItemCount(series)</code>).
227      *
228      * @return The y-value.
229      *
230      * @throws ArrayIndexOutOfBoundsException if <code>series</code> is not
231      * within the specified range.
232      * @throws ArrayIndexOutOfBoundsException if <code>item</code> is not
233      * within the specified range.
234      *
235      * @see #getX(int, int)
236      */

237     public Number JavaDoc getY(int series, int item) {
238         return new Double JavaDoc(getYValue(series, item));
239     }
240
241     /**
242      * Returns the z-value for an item within a series.
243      *
244      * @param series the series index (in the range <code>0</code> to
245      * <code>getSeriesCount() - 1</code>).
246      * @param item the item index (in the range <code>0</code> to
247      * <code>getItemCount(series)</code>).
248      *
249      * @return The z-value.
250      *
251      * @throws ArrayIndexOutOfBoundsException if <code>series</code> is not
252      * within the specified range.
253      * @throws ArrayIndexOutOfBoundsException if <code>item</code> is not
254      * within the specified range.
255      *
256      * @see #getZ(int, int)
257      */

258     public double getZValue(int series, int item) {
259         double[][] seriesData = (double[][]) this.seriesList.get(series);
260         return seriesData[2][item];
261     }
262
263     /**
264      * Returns the z-value for an item within a series.
265      *
266      * @param series the series index (in the range <code>0</code> to
267      * <code>getSeriesCount() - 1</code>).
268      * @param item the item index (in the range <code>0</code> to
269      * <code>getItemCount(series)</code>).
270      *
271      * @return The z-value.
272      *
273      * @throws ArrayIndexOutOfBoundsException if <code>series</code> is not
274      * within the specified range.
275      * @throws ArrayIndexOutOfBoundsException if <code>item</code> is not
276      * within the specified range.
277      *
278      * @see #getZ(int, int)
279      */

280     public Number JavaDoc getZ(int series, int item) {
281         return new Double JavaDoc(getZValue(series, item));
282     }
283
284     /**
285      * Adds a series or if a series with the same key already exists replaces
286      * the data for that series, then sends a {@link DatasetChangeEvent} to
287      * all registered listeners.
288      *
289      * @param seriesKey the series key (<code>null</code> not permitted).
290      * @param data the data (must be an array with length 3, containing three
291      * arrays of equal length, the first containing the x-values, the
292      * second containing the y-values and the third containing the
293      * z-values).
294      */

295     public void addSeries(Comparable JavaDoc seriesKey, double[][] data) {
296         if (seriesKey == null) {
297             throw new IllegalArgumentException JavaDoc(
298                     "The 'seriesKey' cannot be null.");
299         }
300         if (data == null) {
301             throw new IllegalArgumentException JavaDoc("The 'data' is null.");
302         }
303         if (data.length != 3) {
304             throw new IllegalArgumentException JavaDoc(
305                     "The 'data' array must have length == 3.");
306         }
307         if (data[0].length != data[1].length
308                 || data[0].length != data[2].length) {
309             throw new IllegalArgumentException JavaDoc("The 'data' array must contain "
310                     + "three arrays all having the same length.");
311         }
312         int seriesIndex = indexOf(seriesKey);
313         if (seriesIndex == -1) { // add a new series
314
this.seriesKeys.add(seriesKey);
315             this.seriesList.add(data);
316         }
317         else { // replace an existing series
318
this.seriesList.remove(seriesIndex);
319             this.seriesList.add(seriesIndex, data);
320         }
321         notifyListeners(new DatasetChangeEvent(this, this));
322     }
323
324     /**
325      * Removes a series from the dataset, then sends a
326      * {@link DatasetChangeEvent} to all registered listeners.
327      *
328      * @param seriesKey the series key (<code>null</code> not permitted).
329      *
330      */

331     public void removeSeries(Comparable JavaDoc seriesKey) {
332         int seriesIndex = indexOf(seriesKey);
333         if (seriesIndex >= 0) {
334             this.seriesKeys.remove(seriesIndex);
335             this.seriesList.remove(seriesIndex);
336             notifyListeners(new DatasetChangeEvent(this, this));
337         }
338     }
339     
340     /**
341      * Tests this <code>DefaultXYDataset</code> instance for equality with an
342      * arbitrary object. This method returns <code>true</code> if and only if:
343      * <ul>
344      * <li><code>obj</code> is not <code>null</code>;</li>
345      * <li><code>obj</code> is an instance of
346      * <code>DefaultXYDataset</code>;</li>
347      * <li>both datasets have the same number of series, each containing
348      * exactly the same values.</li>
349      * </ul>
350      *
351      * @param obj the object (<code>null</code> permitted).
352      *
353      * @return A boolean.
354      */

355     public boolean equals(Object JavaDoc obj) {
356         if (obj == this) {
357             return true;
358         }
359         if (!(obj instanceof DefaultXYZDataset)) {
360             return false;
361         }
362         DefaultXYZDataset that = (DefaultXYZDataset) obj;
363         if (!this.seriesKeys.equals(that.seriesKeys)) {
364             return false;
365         }
366         for (int i = 0; i < this.seriesList.size(); i++) {
367             double[][] d1 = (double[][]) this.seriesList.get(i);
368             double[][] d2 = (double[][]) that.seriesList.get(i);
369             double[] d1x = d1[0];
370             double[] d2x = d2[0];
371             if (!Arrays.equals(d1x, d2x)) {
372                 return false;
373             }
374             double[] d1y = d1[1];
375             double[] d2y = d2[1];
376             if (!Arrays.equals(d1y, d2y)) {
377                 return false;
378             }
379             double[] d1z = d1[2];
380             double[] d2z = d2[2];
381             if (!Arrays.equals(d1z, d2z)) {
382                 return false;
383             }
384         }
385         return true;
386     }
387     
388     /**
389      * Creates an independent copy of this dataset.
390      *
391      * @return The cloned dataset.
392      *
393      * @throws CloneNotSupportedException if there is a problem cloning the
394      * dataset (for instance, if a non-cloneable object is used for a
395      * series key).
396      */

397     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
398         DefaultXYZDataset clone = (DefaultXYZDataset) super.clone();
399         clone.seriesKeys = new java.util.ArrayList JavaDoc(this.seriesKeys);
400         clone.seriesList = new ArrayList JavaDoc(this.seriesList.size());
401         for (int i = 0; i < this.seriesList.size(); i++) {
402             double[][] data = (double[][]) this.seriesList.get(i);
403             double[] x = data[0];
404             double[] y = data[1];
405             double[] z = data[2];
406             double[] xx = new double[x.length];
407             double[] yy = new double[y.length];
408             double[] zz = new double[z.length];
409             System.arraycopy(x, 0, xx, 0, x.length);
410             System.arraycopy(y, 0, yy, 0, y.length);
411             System.arraycopy(z, 0, zz, 0, z.length);
412             clone.seriesList.add(i, new double[][] {xx, yy, zz});
413         }
414         return clone;
415     }
416
417 }
418
Popular Tags