KickJava   Java API By Example, From Geeks To Geeks.

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


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  * DefaultTableXYDataset.java
24  * -------------------
25  * (C) Copyright 2003 by Richard Atkinson.
26  *
27  * Original Author: Richard Atkinson;
28  * Contributor(s): -;
29  *
30  * $Id: DefaultTableXYDataset.java,v 1.2 2003/11/03 14:20:04 mungady Exp $
31  *
32  * Changes:
33  * --------
34  * 27-Jul-2003 : XYDataset that forces each series to have a value for every X-point
35  * which is essential for stacked XY area charts (RA);
36  * 18-Aug-2003 : Fixed event notification when removing and updating series (RA);
37  * 22-Sep-2003 : Functionality moved from TableXYDataset to DefaultTableXYDataset (RA);
38  *
39  */

40 package org.jfree.data;
41
42 import java.util.ArrayList JavaDoc;
43 import java.util.List JavaDoc;
44
45 import org.jfree.util.ObjectUtils;
46
47 /**
48  * An {@link XYDataset} where every series shares the same x-values (required for
49  * generating stacked area charts).
50  *
51  * @author Richard Atkinson
52  */

53 public class DefaultTableXYDataset extends AbstractSeriesDataset implements TableXYDataset {
54     
55     /** Storage for the data. */
56     private List JavaDoc data = null;
57     
58     /** Storage for the x values. */
59     private List JavaDoc xPoints = null;
60     
61     /** A flag that controls whether or not events are propogated. */
62     private boolean propagateEvents = true;
63
64     /**
65      * Creates a new empty dataset.
66      */

67     public DefaultTableXYDataset() {
68         this.data = new ArrayList JavaDoc();
69         this.xPoints = new ArrayList JavaDoc();
70     }
71
72     /**
73      * Constructs a dataset and populates it with a single time series.
74      *
75      * @param series the time series.
76      */

77     public DefaultTableXYDataset(XYSeries series) {
78
79         this.data = new ArrayList JavaDoc();
80         this.xPoints = new ArrayList JavaDoc();
81         if (series != null) {
82             if (series.getAllowDuplicateXValues()) {
83                 throw new IllegalArgumentException JavaDoc("Cannot accept XY Series that allow duplicate "
84                     + "values. Use XYSeries(seriesName, false) constructor.");
85             }
86             updateXPoints(series);
87             data.add(series);
88             series.addChangeListener(this);
89         }
90
91     }
92
93     /**
94      * Adds a series to the collection.
95      * <P>
96      * Notifies all registered listeners that the dataset has changed.
97      *
98      * @param series the series.
99      */

100     public void addSeries(XYSeries series) {
101
102         // check arguments...
103
if (series == null) {
104             throw new IllegalArgumentException JavaDoc(
105                 "XYSeriesCollection.addSeries(...): cannot add null series.");
106         }
107         if (series.getAllowDuplicateXValues()) {
108             throw new IllegalArgumentException JavaDoc("Cannot accept XY Series that allow duplicate "
109                 + "values. Use XYSeries(seriesName, false) constructor.");
110         }
111
112         // add the series...
113
this.updateXPoints(series);
114         data.add(series);
115         series.addChangeListener(this);
116         fireDatasetChanged();
117
118     }
119
120     /**
121      * Updates XPoints for a particular series.
122      *
123      * @param series the series.
124      */

125     private void updateXPoints(XYSeries series) {
126         ArrayList JavaDoc seriesXPoints = new ArrayList JavaDoc();
127         boolean savedState = this.propagateEvents;
128         this.propagateEvents = false;
129         for (int itemNo = 0; itemNo < series.getItemCount(); itemNo++) {
130             Number JavaDoc xValue = series.getXValue(itemNo);
131             seriesXPoints.add(xValue);
132             if (!xPoints.contains(xValue)) {
133                 xPoints.add(xValue);
134                 for (int seriesNo = 0; seriesNo < this.data.size(); seriesNo++) {
135                     XYSeries dataSeries = (XYSeries) data.get(seriesNo);
136                     if (!dataSeries.equals(series)) {
137                         dataSeries.add(xValue, null);
138                     }
139                 }
140             }
141         }
142         for (int itemNo = 0; itemNo < xPoints.size(); itemNo++) {
143             Number JavaDoc xPoint = (Number JavaDoc) this.xPoints.get(itemNo);
144             if (!seriesXPoints.contains(xPoint)) {
145                 series.add(xPoint, null);
146             }
147         }
148         this.propagateEvents = savedState;
149     }
150
151     /**
152      * Updates XPoints for all series.
153      */

154     public void updateXPoints() {
155         this.propagateEvents = false;
156         for (int seriesNo = 0; seriesNo < data.size(); seriesNo++) {
157             updateXPoints((XYSeries) data.get(seriesNo));
158         }
159         this.propagateEvents = true;
160     }
161
162     /**
163      * Returns the number of series in the collection.
164      *
165      * @return the number of series in the collection.
166      */

167     public int getSeriesCount() {
168         return this.data.size();
169     }
170
171     /**
172      * Returns the number of X points in the Dataset.
173      *
174      * @return the number of X points in the Dataset
175      */

176     public int getItemCount() {
177         if (this.xPoints == null) {
178             return 0;
179         }
180         else {
181             return this.xPoints.size();
182         }
183     }
184
185     /**
186      * Returns a series.
187      *
188      * @param series the series (zero-based index).
189      *
190      * @return The series.
191      */

192     public XYSeries getSeries(int series) {
193
194         // check arguments...
195
if ((series < 0) || (series > getSeriesCount())) {
196             throw new IllegalArgumentException JavaDoc(
197                 "XYSeriesCollection.getSeries(...): index outside valid range.");
198         }
199
200         // fetch the series...
201
XYSeries ts = (XYSeries) data.get(series);
202         return ts;
203
204     }
205
206     /**
207      * Returns the name of a series.
208      *
209      * @param series the series (zero-based index).
210      *
211      * @return the name of a series.
212      */

213     public String JavaDoc getSeriesName(int series) {
214
215         // check arguments...delegated
216

217         // fetch the result...
218
return getSeries(series).getName();
219
220     }
221
222     /**
223      * Returns the number of items in the specified series.
224      *
225      * @param series the series (zero-based index).
226      *
227      * @return the number of items in the specified series.
228      */

229     public int getItemCount(int series) {
230
231         // check arguments...delegated
232

233         // fetch the result...
234
return getSeries(series).getItemCount();
235
236     }
237
238     /**
239      * Returns the x-value for the specified series and item.
240      *
241      * @param series the series (zero-based index).
242      * @param item the item (zero-based index).
243      *
244      * @return the x-value for the specified series and item.
245      */

246     public Number JavaDoc getXValue(int series, int item) {
247
248         XYSeries ts = (XYSeries) data.get(series);
249         XYDataItem dataItem = ts.getDataItem(item);
250         return dataItem.getX();
251
252     }
253
254     /**
255      * Returns the y-value for the specified series and item.
256      *
257      * @param series the series (zero-based index).
258      * @param index the index of the item of interest (zero-based).
259      *
260      * @return the y-value for the specified series and item.
261      */

262     public Number JavaDoc getYValue(int series, int index) {
263
264         XYSeries ts = (XYSeries) data.get(series);
265         XYDataItem dataItem = ts.getDataItem(index);
266         return dataItem.getY();
267
268     }
269
270     /**
271      * Removes all the series from the collection.
272      * <P>
273      * Notifies all registered listeners that the dataset has changed.
274      */

275     public void removeAllSeries() {
276
277         // Unregister the collection as a change listener to each series in the collection.
278
for (int i = 0; i < this.data.size(); i++) {
279             XYSeries series = (XYSeries) this.data.get(i);
280             series.removeChangeListener(this);
281         }
282
283         // Remove all the series from the collection and notify listeners.
284
data.clear();
285         xPoints.clear();
286         fireDatasetChanged();
287
288     }
289
290     /**
291      * Removes a series from the collection.
292      * <P>
293      * Notifies all registered listeners that the dataset has changed.
294      *
295      * @param series the series.
296      */

297     public void removeSeries(XYSeries series) {
298
299         // check arguments...
300
if (series == null) {
301             throw new IllegalArgumentException JavaDoc(
302                 "XYSeriesCollection.removeSeries(...): cannot remove null series.");
303         }
304
305         // remove the series...
306
if (data.contains(series)) {
307             series.removeChangeListener(this);
308             data.remove(series);
309             if (data.size() == 0) xPoints.clear();
310             fireDatasetChanged();
311         }
312
313     }
314
315     /**
316      * Removes a series from the collection.
317      * <P>
318      * Notifies all registered listeners that the dataset has changed.
319      *
320      * @param series the series (zero based index).
321      */

322     public void removeSeries(int series) {
323
324         // check arguments...
325
if ((series < 0) || (series > getSeriesCount())) {
326             throw new IllegalArgumentException JavaDoc(
327                 "XYSeriesCollection.removeSeries(...): index outside valid range.");
328         }
329
330         // fetch the series, remove the change listener, then remove the series.
331
XYSeries ts = (XYSeries) data.get(series);
332         ts.removeChangeListener(this);
333         data.remove(series);
334         if (data.size() == 0) xPoints.clear();
335         fireDatasetChanged();
336
337     }
338
339     /**
340      * Called when a series belonging to the dataset changes.
341      *
342      * @param event information about the change.
343      */

344     public void seriesChanged(SeriesChangeEvent event) {
345         if (this.propagateEvents) {
346             updateXPoints();
347             fireDatasetChanged();
348         }
349     }
350
351     /**
352      * Tests this collection for equality with an arbitrary object.
353      *
354      * @param obj the object.
355      *
356      * @return A boolean.
357      */

358     public boolean equals(Object JavaDoc obj) {
359
360         if (obj == null) {
361             return false;
362         }
363
364         if (obj == this) {
365             return true;
366         }
367
368         if (obj instanceof DefaultTableXYDataset) {
369             DefaultTableXYDataset c = (DefaultTableXYDataset) obj;
370             return ObjectUtils.equal(this.data, c.data);
371         }
372
373         return false;
374
375     }
376
377 }
378
Popular Tags