KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > contour > DefaultContourDataset


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, 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  * DefaultContourDataset.java
29  * --------------------------
30  * (C) Copyright 2002-2005, by David M. O'Donnell and Contributors.
31  *
32  * Original Author: David M. O'Donnell;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  *
35  * $Id: DefaultContourDataset.java,v 1.6.2.1 2005/10/25 21:30:20 mungady Exp $
36  *
37  * Changes (from 23-Jan-2003)
38  * --------------------------
39  * 23-Jan-2003 : Added standard header (DG);
40  * 20-May-2003 : removed member vars numX and numY, which were never used (TM);
41  * 06-May-2004 : Now extends AbstractXYZDataset (DG);
42  * 15-Jul-2004 : Switched getX() with getXValue(), getY() with getYValue() and
43  * getZ() with getZValue() methods (DG);
44  *
45  */

46
47 package org.jfree.data.contour;
48
49 import java.util.Arrays JavaDoc;
50 import java.util.Date JavaDoc;
51 import java.util.Vector JavaDoc;
52
53 import org.jfree.data.Range;
54 import org.jfree.data.xy.AbstractXYZDataset;
55 import org.jfree.data.xy.XYDataset;
56
57 /**
58  * A convenience class that provides a default implementation of the
59  * {@link ContourDataset} interface.
60  *
61  * @author David M. O'Donnell
62  */

63 public class DefaultContourDataset extends AbstractXYZDataset
64                                    implements ContourDataset {
65
66     /** The series name (this dataset supports only one series). */
67     protected Comparable JavaDoc seriesKey = null;
68
69     /** Storage for the x values. */
70     protected Number JavaDoc[] xValues = null;
71
72     /** Storage for the y values. */
73     protected Number JavaDoc[] yValues = null;
74
75     /** Storage for the z values. */
76     protected Number JavaDoc[] zValues = null;
77
78     /** The index for the start of each column in the data. */
79     protected int[] xIndex = null;
80
81     /** Flags that track whether x, y and z are dates. */
82     boolean[] dateAxis = new boolean[3];
83
84     /**
85      * Creates a new dataset, initially empty.
86      */

87     public DefaultContourDataset() {
88         super();
89     }
90
91     /**
92      * Constructs a new dataset with the given data.
93      *
94      * @param seriesKey the series key.
95      * @param xData the x values.
96      * @param yData the y values.
97      * @param zData the z values.
98      */

99     public DefaultContourDataset(Comparable JavaDoc seriesKey,
100                                  Object JavaDoc[] xData,
101                                  Object JavaDoc[] yData,
102                                  Object JavaDoc[] zData) {
103
104         this.seriesKey = seriesKey;
105         initialize(xData, yData, zData);
106     }
107
108     /**
109      * Initialises the dataset.
110      *
111      * @param xData the x values.
112      * @param yData the y values.
113      * @param zData the z values.
114      */

115     public void initialize(Object JavaDoc[] xData,
116                            Object JavaDoc[] yData,
117                            Object JavaDoc[] zData) {
118
119         this.xValues = new Double JavaDoc[xData.length];
120         this.yValues = new Double JavaDoc[yData.length];
121         this.zValues = new Double JavaDoc[zData.length];
122
123         // We organise the data with the following assumption:
124
// 1) the data are sorted by x then y
125
// 2) that the data will be represented by a rectangle formed by
126
// using x[i+1], x, y[j+1], and y.
127
// 3) we march along the y-axis at the same value of x until a new
128
// value x is found at which point we will flag the index
129
// where x[i+1]<>x[i]
130

131         Vector JavaDoc tmpVector = new Vector JavaDoc(); //create a temporary vector
132
double x = 1.123452e31; // set x to some arbitary value (used below)
133
for (int k = 0; k < this.xValues.length; k++) {
134             if (xData[k] != null) {
135                 Number JavaDoc xNumber;
136                 if (xData[k] instanceof Number JavaDoc) {
137                     xNumber = (Number JavaDoc) xData[k];
138                 }
139                 else if (xData[k] instanceof Date JavaDoc) {
140                     this.dateAxis[0] = true;
141                     Date JavaDoc xDate = (Date JavaDoc) xData[k];
142                     xNumber = new Long JavaDoc(xDate.getTime()); //store data as Long
143
}
144                 else {
145                     xNumber = new Integer JavaDoc(0);
146                 }
147                 this.xValues[k] = new Double JavaDoc(xNumber.doubleValue());
148                     // store Number as Double
149

150                 // check if starting new column
151
if (x != this.xValues[k].doubleValue()) {
152                     tmpVector.add(new Integer JavaDoc(k)); //store index where new
153
//column starts
154
x = this.xValues[k].doubleValue();
155                                              // set x to most recent value
156
}
157             }
158         }
159
160         Object JavaDoc[] inttmp = tmpVector.toArray();
161         this.xIndex = new int[inttmp.length]; // create array xIndex to hold
162
// new column indices
163

164         for (int i = 0; i < inttmp.length; i++) {
165             this.xIndex[i] = ((Integer JavaDoc) inttmp[i]).intValue();
166         }
167         for (int k = 0; k < this.yValues.length; k++) { // store y and z axes
168
// as Doubles
169
this.yValues[k] = (Double JavaDoc) yData[k];
170             if (zData[k] != null) {
171                 this.zValues[k] = (Double JavaDoc) zData[k];
172             }
173         }
174     }
175
176     /**
177      * Creates an object array from an array of doubles.
178      *
179      * @param data the data.
180      *
181      * @return An array of <code>Double</code> objects.
182      */

183     public static Object JavaDoc[][] formObjectArray(double[][] data) {
184         Object JavaDoc[][] object = new Double JavaDoc[data.length][data[0].length];
185
186         for (int i = 0; i < object.length; i++) {
187             for (int j = 0; j < object[i].length; j++) {
188                 object[i][j] = new Double JavaDoc(data[i][j]);
189             }
190         }
191         return object;
192     }
193
194     /**
195      * Creates an object array from an array of doubles.
196      *
197      * @param data the data.
198      *
199      * @return An array of <code>Double</code> objects.
200      */

201     public static Object JavaDoc[] formObjectArray(double[] data) {
202         Object JavaDoc[] object = new Double JavaDoc[data.length];
203         for (int i = 0; i < object.length; i++) {
204             object[i] = new Double JavaDoc(data[i]);
205         }
206         return object;
207     }
208
209     /**
210      * Returns the number of items in the specified series. This method
211      * is provided to satisfy the {@link XYDataset} interface implementation.
212      *
213      * @param series must be zero, as this dataset only supports one series.
214      *
215      * @return The item count.
216      */

217     public int getItemCount(int series) {
218         if (series > 0) {
219             throw new IllegalArgumentException JavaDoc("Only one series for contour");
220         }
221         return this.zValues.length;
222     }
223
224     /**
225      * Returns the maximum z-value.
226      *
227      * @return The maximum z-value.
228      */

229     public double getMaxZValue() {
230         double zMax = -1.e20;
231         for (int k = 0; k < this.zValues.length; k++) {
232             if (this.zValues[k] != null) {
233                 zMax = Math.max(zMax, this.zValues[k].doubleValue());
234             }
235         }
236         return zMax;
237     }
238
239     /**
240      * Returns the minimum z-value.
241      *
242      * @return The minimum z-value.
243      */

244     public double getMinZValue() {
245         double zMin = 1.e20;
246         for (int k = 0; k < this.zValues.length; k++) {
247             if (this.zValues[k] != null) {
248                 zMin = Math.min(zMin, this.zValues[k].doubleValue());
249             }
250         }
251         return zMin;
252     }
253
254     /**
255      * Returns the maximum z-value within visible region of plot.
256      *
257      * @param x the x range.
258      * @param y the y range.
259      *
260      * @return The z range.
261      */

262     public Range getZValueRange(Range x, Range y) {
263
264         double minX = x.getLowerBound();
265         double minY = y.getLowerBound();
266         double maxX = x.getUpperBound();
267         double maxY = y.getUpperBound();
268
269         double zMin = 1.e20;
270         double zMax = -1.e20;
271         for (int k = 0; k < this.zValues.length; k++) {
272             if (this.xValues[k].doubleValue() >= minX
273                 && this.xValues[k].doubleValue() <= maxX
274                 && this.yValues[k].doubleValue() >= minY
275                 && this.yValues[k].doubleValue() <= maxY) {
276                 if (this.zValues[k] != null) {
277                     zMin = Math.min(zMin, this.zValues[k].doubleValue());
278                     zMax = Math.max(zMax, this.zValues[k].doubleValue());
279                 }
280             }
281         }
282
283         return new Range(zMin, zMax);
284     }
285
286     /**
287      * Returns the minimum z-value.
288      *
289      * @param minX the minimum x value.
290      * @param minY the minimum y value.
291      * @param maxX the maximum x value.
292      * @param maxY the maximum y value.
293      *
294      * @return The minimum z-value.
295      */

296     public double getMinZValue(double minX,
297                                double minY,
298                                double maxX,
299                                double maxY) {
300
301         double zMin = 1.e20;
302         for (int k = 0; k < this.zValues.length; k++) {
303             if (this.zValues[k] != null) {
304                 zMin = Math.min(zMin, this.zValues[k].doubleValue());
305             }
306         }
307         return zMin;
308
309     }
310
311     /**
312      * Returns the number of series.
313      * <P>
314      * Required by XYDataset interface (this will always return 1)
315      *
316      * @return 1.
317      */

318     public int getSeriesCount() {
319         return 1;
320     }
321
322     /**
323      * Returns the name of the specified series.
324      *
325      * Method provided to satisfy the XYDataset interface implementation
326      *
327      * @param series must be zero.
328      *
329      * @return The series name.
330      */

331     public Comparable JavaDoc getSeriesKey(int series) {
332         if (series > 0) {
333             throw new IllegalArgumentException JavaDoc("Only one series for contour");
334         }
335         return this.seriesKey;
336     }
337
338     /**
339      * Returns the index of the xvalues.
340      *
341      * @return The x values.
342      */

343     public int[] getXIndices() {
344         return this.xIndex;
345     }
346
347     /**
348      * Returns the x values.
349      *
350      * @return The x values.
351      */

352     public Number JavaDoc[] getXValues() {
353         return this.xValues;
354     }
355
356     /**
357      * Returns the x value for the specified series and index (zero-based
358      * indices). Required by the {@link XYDataset}.
359      *
360      * @param series must be zero;
361      * @param item the item index (zero-based).
362      *
363      * @return The x value.
364      */

365     public Number JavaDoc getX(int series, int item) {
366         if (series > 0) {
367             throw new IllegalArgumentException JavaDoc("Only one series for contour");
368         }
369         return this.xValues[item];
370     }
371
372     /**
373      * Returns an x value.
374      *
375      * @param item the item index (zero-based).
376      *
377      * @return The X value.
378      */

379     public Number JavaDoc getXValue(int item) {
380         return this.xValues[item];
381     }
382
383     /**
384      * Returns a Number array containing all y values.
385      *
386      * @return The Y values.
387      */

388     public Number JavaDoc[] getYValues() {
389         return this.yValues;
390     }
391
392     /**
393      * Returns the y value for the specified series and index (zero-based
394      * indices). Required by the {@link XYDataset}.
395      *
396      * @param series the series index (must be zero for this dataset).
397      * @param item the item index (zero-based).
398      *
399      * @return The Y value.
400      */

401     public Number JavaDoc getY(int series, int item) {
402         if (series > 0) {
403             throw new IllegalArgumentException JavaDoc("Only one series for contour");
404         }
405         return this.yValues[item];
406     }
407
408     /**
409      * Returns a Number array containing all z values.
410      *
411      * @return The Z values.
412      */

413     public Number JavaDoc[] getZValues() {
414         return this.zValues;
415     }
416
417     /**
418      * Returns the z value for the specified series and index (zero-based
419      * indices). Required by the {@link XYDataset}
420      *
421      * @param series the series index (must be zero for this dataset).
422      * @param item the item index (zero-based).
423      *
424      * @return The Z value.
425      */

426     public Number JavaDoc getZ(int series, int item) {
427         if (series > 0) {
428             throw new IllegalArgumentException JavaDoc("Only one series for contour");
429         }
430         return this.zValues[item];
431     }
432
433     /**
434      * Returns an int array contain the index into the x values.
435      *
436      * @return The X values.
437      */

438     public int[] indexX() {
439         int[] index = new int[this.xValues.length];
440         for (int k = 0; k < index.length; k++) {
441             index[k] = indexX(k);
442         }
443         return index;
444     }
445
446     /**
447      * Given index k, returns the column index containing k.
448      *
449      * @param k index of interest.
450      *
451      * @return The column index.
452      */

453     public int indexX(int k) {
454         int i = Arrays.binarySearch(this.xIndex, k);
455         if (i >= 0) {
456             return i;
457         }
458         else {
459             return -1 * i - 2;
460         }
461     }
462
463
464     /**
465      * Given index k, return the row index containing k.
466      *
467      * @param k index of interest.
468      *
469      * @return The row index.
470      */

471     public int indexY(int k) { // this may be obsolete (not used anywhere)
472
return (k / this.xValues.length);
473     }
474
475     /**
476      * Given column and row indices, returns the k index.
477      *
478      * @param i index of along x-axis.
479      * @param j index of along y-axis.
480      *
481      * @return The Z index.
482      */

483     public int indexZ(int i, int j) {
484         return this.xValues.length * j + i;
485     }
486
487     /**
488      * Returns true if axis are dates.
489      *
490      * @param axisNumber The axis where 0-x, 1-y, and 2-z.
491      *
492      * @return A boolean.
493      */

494     public boolean isDateAxis(int axisNumber) {
495         if (axisNumber < 0 || axisNumber > 2) {
496             return false; // bad axisNumber
497
}
498         return this.dateAxis[axisNumber];
499     }
500
501     /**
502      * Sets the names of the series in the data source.
503      *
504      * @param seriesKeys the keys of the series in the data source.
505      */

506     public void setSeriesKeys(Comparable JavaDoc[] seriesKeys) {
507         if (seriesKeys.length > 1) {
508             throw new IllegalArgumentException JavaDoc(
509                 "Contours only support one series"
510             );
511         }
512         this.seriesKey = seriesKeys[0];
513         fireDatasetChanged();
514     }
515
516 }
517
Popular Tags