KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > category > DefaultIntervalCategoryDataset


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  * DefaultIntervalCategoryDataset.java
29  * -----------------------------------
30  * (C) Copyright 2002-2005, by Jeremy Bowman and Contributors.
31  *
32  * Original Author: Jeremy Bowman;
33  * Contributor(s): David Gilbert (for Object Refinery Limited);
34  *
35  * $Id: DefaultIntervalCategoryDataset.java,v 1.9.2.2 2005/10/25 21:29:58 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 29-Apr-2002 : Version 1, contributed by Jeremy Bowman (DG);
40  * 24-Oct-2002 : Amendments for changes made to the dataset interface (DG);
41  *
42  */

43
44 package org.jfree.data.category;
45
46 import java.util.ArrayList JavaDoc;
47 import java.util.Arrays JavaDoc;
48 import java.util.Collections JavaDoc;
49 import java.util.List JavaDoc;
50 import java.util.ResourceBundle JavaDoc;
51
52 import org.jfree.data.DataUtilities;
53 import org.jfree.data.general.AbstractSeriesDataset;
54
55 /**
56  * A convenience class that provides a default implementation of the
57  * {@link IntervalCategoryDataset} interface.
58  * <p>
59  * The standard constructor accepts data in a two dimensional array where the
60  * first dimension is the series, and the second dimension is the category.
61  *
62  * @author Jeremy Bowman
63  */

64 public class DefaultIntervalCategoryDataset extends AbstractSeriesDataset
65                                             implements IntervalCategoryDataset {
66
67     /** The series keys. */
68     private Comparable JavaDoc[] seriesKeys;
69
70     /** The category keys. */
71     private Comparable JavaDoc[] categoryKeys;
72
73     /** Storage for the start value data. */
74     private Number JavaDoc[][] startData;
75
76     /** Storage for the end value data. */
77     private Number JavaDoc[][] endData;
78
79     /**
80      * Creates a new dataset.
81      *
82      * @param starts the starting values for the intervals.
83      * @param ends the ending values for the intervals.
84      */

85     public DefaultIntervalCategoryDataset(double[][] starts, double[][] ends) {
86         this(
87             DataUtilities.createNumberArray2D(starts),
88             DataUtilities.createNumberArray2D(ends)
89         );
90     }
91
92     /**
93      * Constructs a dataset and populates it with data from the array.
94      * <p>
95      * The arrays are indexed as data[series][category]. Series and category
96      * names are automatically generated - you can change them using the
97      * {@link #setSeriesKeys(Comparable[])} and
98      * {@link #setCategoryKeys(Comparable[])} methods.
99      *
100      * @param starts the start values data.
101      * @param ends the end values data.
102      */

103     public DefaultIntervalCategoryDataset(Number JavaDoc[][] starts, Number JavaDoc[][] ends) {
104         this(null, null, starts, ends);
105     }
106
107     /**
108      * Constructs a DefaultIntervalCategoryDataset, populates it with data
109      * from the arrays, and uses the supplied names for the series.
110      * <p>
111      * Category names are generated automatically ("Category 1", "Category 2",
112      * etc).
113      *
114      * @param seriesNames the series names.
115      * @param starts the start values data, indexed as data[series][category].
116      * @param ends the end values data, indexed as data[series][category].
117      */

118     public DefaultIntervalCategoryDataset(String JavaDoc[] seriesNames,
119                                           Number JavaDoc[][] starts,
120                                           Number JavaDoc[][] ends) {
121
122         this(seriesNames, null, starts, ends);
123
124     }
125
126     /**
127      * Constructs a DefaultIntervalCategoryDataset, populates it with data
128      * from the arrays, and uses the supplied names for the series and the
129      * supplied objects for the categories.
130      *
131      * @param seriesKeys the series keys.
132      * @param categoryKeys the categories.
133      * @param starts the start values data, indexed as data[series][category].
134      * @param ends the end values data, indexed as data[series][category].
135      */

136     public DefaultIntervalCategoryDataset(Comparable JavaDoc[] seriesKeys,
137                                           Comparable JavaDoc[] categoryKeys,
138                                           Number JavaDoc[][] starts,
139                                           Number JavaDoc[][] ends) {
140
141         this.startData = starts;
142         this.endData = ends;
143
144         if (starts != null && ends != null) {
145
146             String JavaDoc baseName = "org.jfree.data.resources.DataPackageResources";
147             ResourceBundle JavaDoc resources = ResourceBundle.getBundle(baseName);
148
149             int seriesCount = starts.length;
150             if (seriesCount != ends.length) {
151                 String JavaDoc errMsg = "DefaultIntervalCategoryDataset: the number "
152                     + "of series in the start value dataset does "
153                     + "not match the number of series in the end "
154                     + "value dataset.";
155                 throw new IllegalArgumentException JavaDoc(errMsg);
156             }
157             if (seriesCount > 0) {
158
159                 // set up the series names...
160
if (seriesKeys != null) {
161
162                     if (seriesKeys.length != seriesCount) {
163                         throw new IllegalArgumentException JavaDoc(
164                             "The number of series keys does "
165                             + "not match the number of series in the data."
166                         );
167                     }
168
169                     this.seriesKeys = seriesKeys;
170                 }
171                 else {
172                     String JavaDoc prefix
173                         = resources.getString("series.default-prefix") + " ";
174                     this.seriesKeys = generateKeys(seriesCount, prefix);
175                 }
176
177                 // set up the category names...
178
int categoryCount = starts[0].length;
179                 if (categoryCount != ends[0].length) {
180                     String JavaDoc errMsg = "DefaultIntervalCategoryDataset: the "
181                                 + "number of categories in the start value "
182                                 + "dataset does not match the number of "
183                                 + "categories in the end value dataset.";
184                     throw new IllegalArgumentException JavaDoc(errMsg);
185                 }
186                 if (categoryKeys != null) {
187                     if (categoryKeys.length != categoryCount) {
188                         throw new IllegalArgumentException JavaDoc(
189                             "The number of category keys does "
190                             + "not match the number of categories in the data."
191                         );
192                     }
193                     this.categoryKeys = categoryKeys;
194                 }
195                 else {
196                     String JavaDoc prefix = resources.getString(
197                         "categories.default-prefix"
198                     ) + " ";
199                     this.categoryKeys = generateKeys(categoryCount, prefix);
200                 }
201
202             }
203             else {
204                 this.seriesKeys = null;
205                 this.categoryKeys = null;
206             }
207         }
208
209     }
210
211     /**
212      * Returns the number of series in the dataset (possibly zero).
213      *
214      * @return The number of series in the dataset.
215      */

216     public int getSeriesCount() {
217         int result = 0;
218         if (this.startData != null) {
219             result = this.startData.length;
220         }
221         return result;
222     }
223
224     /**
225      * Returns the item count.
226      *
227      * @return The item count.
228      */

229     public int getItemCount() {
230         return this.categoryKeys.length;
231     }
232
233     /**
234      * Returns a series index.
235      *
236      * @param series the series key.
237      *
238      * @return The series index.
239      */

240     public int getSeriesIndex(Comparable JavaDoc series) {
241         List JavaDoc seriesKeys = getSeries();
242         return seriesKeys.indexOf(series);
243     }
244
245     /**
246      * Returns the name of the specified series.
247      *
248      * @param series the index of the required series (zero-based).
249      *
250      * @return The name of the specified series.
251      */

252     public Comparable JavaDoc getSeriesKey(int series) {
253         if ((series >= getSeriesCount()) || (series < 0)) {
254             throw new IllegalArgumentException JavaDoc("No such series : " + series);
255         }
256         return this.seriesKeys[series];
257     }
258
259     /**
260      * Sets the names of the series in the dataset.
261      *
262      * @param seriesKeys the keys of the series in the dataset.
263      */

264     public void setSeriesKeys(Comparable JavaDoc[] seriesKeys) {
265
266         // check argument...
267
if (seriesKeys == null) {
268             throw new IllegalArgumentException JavaDoc("Null 'seriesKeys' argument.");
269         }
270
271         if (seriesKeys.length != getSeriesCount()) {
272             throw new IllegalArgumentException JavaDoc(
273                 "DefaultIntervalCategoryDataset.setSeriesKeys(): "
274                 + "the number of series keys does not match the data."
275             );
276         }
277
278         // make the change...
279
this.seriesKeys = seriesKeys;
280         fireDatasetChanged();
281
282     }
283
284     /**
285      * Returns the number of categories in the dataset.
286      * <P>
287      * This method is part of the CategoryDataset interface.
288      *
289      * @return The number of categories in the dataset.
290      */

291     public int getCategoryCount() {
292         int result = 0;
293         if (this.startData != null) {
294             if (getSeriesCount() > 0) {
295                 result = this.startData[0].length;
296             }
297         }
298         return result;
299     }
300
301     /**
302      * Returns a list of the series in the dataset.
303      * <P>
304      * Supports the CategoryDataset interface.
305      *
306      * @return A list of the series in the dataset.
307      */

308     public List JavaDoc getSeries() {
309
310         // the CategoryDataset interface expects a list of series, but
311
// we've stored them in an array...
312
if (this.seriesKeys == null) {
313             return new java.util.ArrayList JavaDoc();
314         }
315         else {
316             return Collections.unmodifiableList(Arrays.asList(this.seriesKeys));
317         }
318
319     }
320
321     /**
322      * Returns a list of the categories in the dataset.
323      * <P>
324      * Supports the CategoryDataset interface.
325      *
326      * @return A list of the categories in the dataset.
327      */

328     public List JavaDoc getCategories() {
329         return getColumnKeys();
330     }
331
332     /**
333      * Returns a list of the categories in the dataset.
334      * <P>
335      * Supports the CategoryDataset interface.
336      *
337      * @return A list of the categories in the dataset.
338      */

339     public List JavaDoc getColumnKeys() {
340
341         // the CategoryDataset interface expects a list of categories, but
342
// we've stored them in an array...
343
if (this.categoryKeys == null) {
344             return new ArrayList JavaDoc();
345         }
346         else {
347             return Collections.unmodifiableList(
348                 Arrays.asList(this.categoryKeys)
349             );
350         }
351
352     }
353
354     /**
355      * Sets the categories for the dataset.
356      *
357      * @param categoryKeys an array of objects representing the categories in
358      * the dataset.
359      */

360     public void setCategoryKeys(Comparable JavaDoc[] categoryKeys) {
361
362         // check arguments...
363
if (categoryKeys == null) {
364             throw new IllegalArgumentException JavaDoc("Null 'categoryKeys' argument.");
365         }
366
367         if (categoryKeys.length != this.startData[0].length) {
368             throw new IllegalArgumentException JavaDoc(
369                 "The number of categories does not match the data."
370             );
371         }
372
373         for (int i = 0; i < categoryKeys.length; i++) {
374             if (categoryKeys[i] == null) {
375                 throw new IllegalArgumentException JavaDoc(
376                     "DefaultIntervalCategoryDataset.setCategoryKeys(): "
377                     + "null category not permitted.");
378             }
379         }
380
381         // make the change...
382
this.categoryKeys = categoryKeys;
383         fireDatasetChanged();
384
385     }
386
387     /**
388      * Returns the data value for one category in a series.
389      * <P>
390      * This method is part of the CategoryDataset interface. Not particularly
391      * meaningful for this class...returns the end value.
392      * @param series The required series (zero based index).
393      * @param category The required category.
394      * @return The data value for one category in a series (null possible).
395      */

396     public Number JavaDoc getValue(Comparable JavaDoc series, Comparable JavaDoc category) {
397         int seriesIndex = getSeriesIndex(series);
398         int itemIndex = getColumnIndex(category);
399         return getValue(seriesIndex, itemIndex);
400     }
401
402     /**
403      * Returns the data value for one category in a series.
404      * <P>
405      * This method is part of the CategoryDataset interface. Not particularly
406      * meaningful for this class...returns the end value.
407      *
408      * @param series the required series (zero based index).
409      * @param category the required category.
410      *
411      * @return The data value for one category in a series (null possible).
412      */

413     public Number JavaDoc getValue(int series, int category) {
414         return getEndValue(series, category);
415     }
416
417     /**
418      * Returns the start data value for one category in a series.
419      *
420      * @param series the required series.
421      * @param category the required category.
422      *
423      * @return The start data value for one category in a series
424      * (possibly <code>null</code>).
425      */

426     public Number JavaDoc getStartValue(Comparable JavaDoc series, Comparable JavaDoc category) {
427         int seriesIndex = getSeriesIndex(series);
428         int itemIndex = getColumnIndex(category);
429         return getStartValue(seriesIndex, itemIndex);
430     }
431
432     /**
433      * Returns the start data value for one category in a series.
434      *
435      * @param series the required series (zero based index).
436      * @param category the required category.
437      *
438      * @return The start data value for one category in a series
439      * (possibly <code>null</code>).
440      */

441     public Number JavaDoc getStartValue(int series, int category) {
442
443         // check arguments...
444
if ((series < 0) || (series >= getSeriesCount())) {
445             throw new IllegalArgumentException JavaDoc(
446                 "DefaultIntervalCategoryDataset.getValue(): "
447                 + "series index out of range.");
448         }
449
450         if ((category < 0) || (category >= getCategoryCount())) {
451             throw new IllegalArgumentException JavaDoc(
452                 "DefaultIntervalCategoryDataset.getValue(): "
453                 + "category index out of range.");
454         }
455
456         // fetch the value...
457
return this.startData[series][category];
458
459     }
460
461     /**
462      * Returns the end data value for one category in a series.
463      *
464      * @param series the required series.
465      * @param category the required category.
466      *
467      * @return The end data value for one category in a series (null possible).
468      */

469     public Number JavaDoc getEndValue(Comparable JavaDoc series, Comparable JavaDoc category) {
470         int seriesIndex = getSeriesIndex(series);
471         int itemIndex = getColumnIndex(category);
472         return getEndValue(seriesIndex, itemIndex);
473     }
474
475     /**
476      * Returns the end data value for one category in a series.
477      *
478      * @param series the required series (zero based index).
479      * @param category the required category.
480      *
481      * @return The end data value for one category in a series (null possible).
482      */

483     public Number JavaDoc getEndValue(int series, int category) {
484
485         // check arguments...
486
if ((series < 0) || (series >= getSeriesCount())) {
487             throw new IllegalArgumentException JavaDoc(
488                 "DefaultIntervalCategoryDataset.getValue(): "
489                 + "series index out of range.");
490         }
491
492         if ((category < 0) || (category >= getCategoryCount())) {
493             throw new IllegalArgumentException JavaDoc(
494                 "DefaultIntervalCategoryDataset.getValue(): "
495                 + "category index out of range.");
496         }
497
498         // fetch the value...
499
return this.endData[series][category];
500
501     }
502
503     /**
504      * Sets the start data value for one category in a series.
505      *
506      * @param series the series (zero-based index).
507      * @param category the category.
508      *
509      * @param value The value.
510      */

511     public void setStartValue(int series, Comparable JavaDoc category, Number JavaDoc value) {
512
513         // does the series exist?
514
if ((series < 0) || (series > getSeriesCount())) {
515             throw new IllegalArgumentException JavaDoc(
516                 "DefaultIntervalCategoryDataset.setValue: "
517                 + "series outside valid range.");
518         }
519
520         // is the category valid?
521
int categoryIndex = getCategoryIndex(category);
522         if (categoryIndex < 0) {
523             throw new IllegalArgumentException JavaDoc(
524                 "DefaultIntervalCategoryDataset.setValue: "
525                 + "unrecognised category.");
526         }
527
528         // update the data...
529
this.startData[series][categoryIndex] = value;
530         fireDatasetChanged();
531
532     }
533
534     /**
535      * Sets the end data value for one category in a series.
536      *
537      * @param series the series (zero-based index).
538      * @param category the category.
539      *
540      * @param value the value.
541      */

542     public void setEndValue(int series, Comparable JavaDoc category, Number JavaDoc value) {
543
544         // does the series exist?
545
if ((series < 0) || (series > getSeriesCount())) {
546             throw new IllegalArgumentException JavaDoc(
547                 "DefaultIntervalCategoryDataset.setValue: "
548                 + "series outside valid range.");
549         }
550
551         // is the category valid?
552
int categoryIndex = getCategoryIndex(category);
553         if (categoryIndex < 0) {
554             throw new IllegalArgumentException JavaDoc(
555                 "DefaultIntervalCategoryDataset.setValue: "
556                 + "unrecognised category.");
557         }
558
559         // update the data...
560
this.endData[series][categoryIndex] = value;
561         fireDatasetChanged();
562
563     }
564
565     /**
566      * Returns the index for the given category.
567      *
568      * @param category the category.
569      *
570      * @return The index.
571      */

572     private int getCategoryIndex(Comparable JavaDoc category) {
573         int result = -1;
574         for (int i = 0; i < this.categoryKeys.length; i++) {
575             if (category.equals(this.categoryKeys[i])) {
576                 result = i;
577                 break;
578             }
579         }
580         return result;
581     }
582
583     /**
584      * Generates an array of keys, by appending a space plus an integer
585      * (starting with 1) to the supplied prefix string.
586      *
587      * @param count the number of keys required.
588      * @param prefix the name prefix.
589      *
590      * @return An array of <i>prefixN</i> with N = { 1 .. count}.
591      */

592     private Comparable JavaDoc[] generateKeys(int count, String JavaDoc prefix) {
593         Comparable JavaDoc[] result = new Comparable JavaDoc[count];
594         String JavaDoc name;
595         for (int i = 0; i < count; i++) {
596             name = prefix + (i + 1);
597             result[i] = name;
598         }
599         return result;
600     }
601
602     /**
603      * Returns a column key.
604      *
605      * @param column the column index.
606      *
607      * @return The column key.
608      */

609     public Comparable JavaDoc getColumnKey(int column) {
610         return this.categoryKeys[column];
611     }
612
613     /**
614      * Returns a column index.
615      *
616      * @param columnKey the column key.
617      *
618      * @return The column index.
619      */

620     public int getColumnIndex(Comparable JavaDoc columnKey) {
621         List JavaDoc categories = getCategories();
622         return categories.indexOf(columnKey);
623     }
624
625     /**
626      * Returns a row index.
627      *
628      * @param rowKey the row key.
629      *
630      * @return The row index.
631      */

632     public int getRowIndex(Comparable JavaDoc rowKey) {
633         List JavaDoc seriesKeys = getSeries();
634         return seriesKeys.indexOf(rowKey);
635     }
636
637     /**
638      * Returns a list of the series in the dataset.
639      * <P>
640      * Supports the CategoryDataset interface.
641      *
642      * @return A list of the series in the dataset.
643      */

644     public List JavaDoc getRowKeys() {
645         // the CategoryDataset interface expects a list of series, but
646
// we've stored them in an array...
647
if (this.seriesKeys == null) {
648             return new java.util.ArrayList JavaDoc();
649         }
650         else {
651             return Collections.unmodifiableList(Arrays.asList(this.seriesKeys));
652         }
653     }
654
655     /**
656      * Returns the name of the specified series.
657      *
658      * @param row the index of the required row/series (zero-based).
659      *
660      * @return The name of the specified series.
661      */

662     public Comparable JavaDoc getRowKey(int row) {
663         if ((row >= getRowCount()) || (row < 0)) {
664             throw new IllegalArgumentException JavaDoc(
665                     "The 'row' argument is out of bounds.");
666         }
667         return this.seriesKeys[row];
668     }
669
670     /**
671      * Returns the number of categories in the dataset. This method is part of
672      * the {@link CategoryDataset} interface.
673      *
674      * @return The number of categories in the dataset.
675      */

676     public int getColumnCount() {
677         int result = 0;
678         if (this.startData != null) {
679             if (getSeriesCount() > 0) {
680                 result = this.startData[0].length;
681             }
682         }
683         return result;
684     }
685
686     /**
687      * Returns the number of series in the dataset (possibly zero).
688      *
689      * @return The number of series in the dataset.
690      */

691     public int getRowCount() {
692         int result = 0;
693         if (this.startData != null) {
694             result = this.startData.length;
695         }
696         return result;
697     }
698
699 }
700
Popular Tags