KickJava   Java API By Example, From Geeks To Geeks.

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


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

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

60 public class DefaultXYDataset extends AbstractXYDataset implements XYDataset {
61
62     /**
63      * Storage for the series keys. This list must be kept in sync with the
64      * seriesList.
65      */

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

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

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

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

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

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

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

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

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

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

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

235     public Number JavaDoc getY(int series, int item) {
236         return new Double JavaDoc(getYValue(series, item));
237     }
238
239     /**
240      * Adds a series or if a series with the same key already exists replaces
241      * the data for that series, then sends a {@link DatasetChangeEvent} to
242      * all registered listeners.
243      *
244      * @param seriesKey the series key (<code>null</code> not permitted).
245      * @param data the data (must be an array with length 2, containing two
246      * arrays of equal length, the first containing the x-values and the
247      * second containing the y-values).
248      */

249     public void addSeries(Comparable JavaDoc seriesKey, double[][] data) {
250         if (seriesKey == null) {
251             throw new IllegalArgumentException JavaDoc(
252                     "The 'seriesKey' cannot be null.");
253         }
254         if (data == null) {
255             throw new IllegalArgumentException JavaDoc("The 'data' is null.");
256         }
257         if (data.length != 2) {
258             throw new IllegalArgumentException JavaDoc(
259                     "The 'data' array must have length == 2.");
260         }
261         if (data[0].length != data[1].length) {
262             throw new IllegalArgumentException JavaDoc(
263                 "The 'data' array must contain two arrays with equal length.");
264         }
265         int seriesIndex = indexOf(seriesKey);
266         if (seriesIndex == -1) { // add a new series
267
this.seriesKeys.add(seriesKey);
268             this.seriesList.add(data);
269         }
270         else { // replace an existing series
271
this.seriesList.remove(seriesIndex);
272             this.seriesList.add(seriesIndex, data);
273         }
274         notifyListeners(new DatasetChangeEvent(this, this));
275     }
276
277     /**
278      * Removes a series from the dataset, then sends a
279      * {@link DatasetChangeEvent} to all registered listeners.
280      *
281      * @param seriesKey the series key (<code>null</code> not permitted).
282      *
283      */

284     public void removeSeries(Comparable JavaDoc seriesKey) {
285         int seriesIndex = indexOf(seriesKey);
286         if (seriesIndex >= 0) {
287             this.seriesKeys.remove(seriesIndex);
288             this.seriesList.remove(seriesIndex);
289             notifyListeners(new DatasetChangeEvent(this, this));
290         }
291     }
292     
293     /**
294      * Tests this <code>DefaultXYDataset</code> instance for equality with an
295      * arbitrary object. This method returns <code>true</code> if and only if:
296      * <ul>
297      * <li><code>obj</code> is not <code>null</code>;</li>
298      * <li><code>obj</code> is an instance of
299      * <code>DefaultXYDataset</code>;</li>
300      * <li>both datasets have the same number of series, each containing
301      * exactly the same values.</li>
302      * </ul>
303      *
304      * @param obj the object (<code>null</code> permitted).
305      *
306      * @return A boolean.
307      */

308     public boolean equals(Object JavaDoc obj) {
309         if (obj == this) {
310             return true;
311         }
312         if (!(obj instanceof DefaultXYDataset)) {
313             return false;
314         }
315         DefaultXYDataset that = (DefaultXYDataset) obj;
316         if (!this.seriesKeys.equals(that.seriesKeys)) {
317             return false;
318         }
319         for (int i = 0; i < this.seriesList.size(); i++) {
320             double[][] d1 = (double[][]) this.seriesList.get(i);
321             double[][] d2 = (double[][]) that.seriesList.get(i);
322             double[] d1x = d1[0];
323             double[] d2x = d2[0];
324             if (!Arrays.equals(d1x, d2x)) {
325                 return false;
326             }
327             double[] d1y = d1[1];
328             double[] d2y = d2[1];
329             if (!Arrays.equals(d1y, d2y)) {
330                 return false;
331             }
332         }
333         return true;
334     }
335     
336     /**
337      * Creates an independent copy of this dataset.
338      *
339      * @return The cloned dataset.
340      *
341      * @throws CloneNotSupportedException if there is a problem cloning the
342      * dataset (for instance, if a non-cloneable object is used for a
343      * series key).
344      */

345     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
346         DefaultXYDataset clone = (DefaultXYDataset) super.clone();
347         clone.seriesKeys = new java.util.ArrayList JavaDoc(this.seriesKeys);
348         clone.seriesList = new ArrayList JavaDoc(this.seriesList.size());
349         for (int i = 0; i < this.seriesList.size(); i++) {
350             double[][] data = (double[][]) this.seriesList.get(i);
351             double[] x = data[0];
352             double[] y = data[1];
353             double[] xx = new double[x.length];
354             double[] yy = new double[y.length];
355             System.arraycopy(x, 0, xx, 0, x.length);
356             System.arraycopy(y, 0, yy, 0, y.length);
357             clone.seriesList.add(i, new double[][] {xx, yy});
358         }
359         return clone;
360     }
361
362 }
363
Popular Tags