KickJava   Java API By Example, From Geeks To Geeks.

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


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  * DefaultIntervalCategoryDataset.java
24  * -----------------------------------
25  * (C) Copyright 2002, 2003, by Jeremy Bowman and Contributors.
26  *
27  * Original Author: Jeremy Bowman;
28  * Contributor(s): David Gilbert (for Object Refinery Limited);
29  *
30  * $Id: DefaultIntervalCategoryDataset.java,v 1.5 2003/06/13 15:46:41 mungady Exp $
31  *
32  * Changes
33  * -------
34  * 29-Apr-2002 : Version 1, contributed by Jeremy Bowman (DG);
35  * 24-Oct-2002 : Amendments for changes made to the dataset interface (DG);
36  *
37  */

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

56 public class DefaultIntervalCategoryDataset extends AbstractSeriesDataset
57                                             implements IntervalCategoryDataset {
58
59     /** The series keys. */
60     private Comparable JavaDoc[] seriesKeys;
61
62     /** The category keys. */
63     private Comparable JavaDoc[] categoryKeys;
64
65     /** Storage for the start value data. */
66     private Number JavaDoc[][] startData;
67
68     /** Storage for the end value data. */
69     private Number JavaDoc[][] endData;
70
71     /**
72      * Creates a new dataset.
73      *
74      * @param starts the starting values for the intervals.
75      * @param ends the ending values for the intervals.
76      */

77     public DefaultIntervalCategoryDataset(double[][] starts, double[][] ends) {
78
79         this(DatasetUtilities.createNumberArray2D(starts),
80              DatasetUtilities.createNumberArray2D(ends));
81
82     }
83
84     /**
85      * Constructs a dataset and populates it with data from the array.
86      * <p>
87      * The arrays are indexed as data[series][category]. Series and category
88      * names are automatically generated - you can change them using the
89      * setSeriesName(...) and setCategory(...) methods.
90      *
91      * @param starts the start values data.
92      * @param ends the end values data.
93      */

94     public DefaultIntervalCategoryDataset(Number JavaDoc[][] starts, Number JavaDoc[][] ends) {
95
96         this(null, null, starts, ends);
97
98     }
99
100     /**
101      * Constructs a DefaultIntervalCategoryDataset, populates it with data
102      * from the arrays, and uses the supplied names for the series.
103      * <p>
104      * Category names are generated automatically ("Category 1", "Category 2",
105      * etc).
106      *
107      * @param seriesNames the series names.
108      * @param starts the start values data, indexed as data[series][category].
109      * @param ends the end values data, indexed as data[series][category].
110      */

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

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

204     public int getSeriesCount() {
205
206         int result = 0;
207         if (startData != null) {
208             result = startData.length;
209         }
210         return result;
211
212     }
213
214     /**
215      * Returns the item count.
216      *
217      * @return The item count.
218      */

219     public int getItemCount() {
220         return this.categoryKeys.length;
221     }
222
223     /**
224      * Returns a category key.
225      *
226      * @param item the category index.
227      *
228      * @return The category key.
229      */

230     public Comparable JavaDoc getCategory(int item) {
231         return this.categoryKeys[item];
232     }
233
234     /**
235      * Returns an item.
236      *
237      * @param category the category key.
238      *
239      * @return The item index.
240      */

241     public int getItem(Object JavaDoc category) {
242         List JavaDoc categories = getCategories();
243         return categories.indexOf(category);
244     }
245
246     /**
247      * Returns a series index.
248      *
249      * @param series the series.
250      *
251      * @return The series index.
252      */

253     public int getSeriesIndex(Object JavaDoc series) {
254         List JavaDoc seriesKeys = getSeries();
255         return seriesKeys.indexOf(series);
256     }
257
258     /**
259      * Returns the name of the specified series.
260      *
261      * @param series the index of the required series (zero-based).
262      *
263      * @return the name of the specified series.
264      */

265     public Comparable JavaDoc getSeries(int series) {
266
267         // check argument...
268
if ((series >= getSeriesCount()) || (series < 0)) {
269             throw new IllegalArgumentException JavaDoc(
270                 "DefaultCategoryDataset.getSeriesName(int): no such series.");
271         }
272
273         // return the value...
274
return seriesKeys[series];
275
276     }
277
278     /**
279      * Returns the name of the specified series.
280      *
281      * @param series The index of the required series (zero-based).
282      *
283      * @return the name of the specified series.
284      */

285     public String JavaDoc getSeriesName(int series) {
286
287         // check argument...
288
if ((series >= getSeriesCount()) || (series < 0)) {
289
290             throw new IllegalArgumentException JavaDoc(
291                 "DefaultIntervalCategoryDataset.getSeriesName(int): no such series.");
292         }
293
294         // return the value...
295
return seriesKeys[series].toString();
296
297     }
298
299     /**
300      * Sets the names of the series in the dataset.
301      *
302      * @param seriesKeys the keys of the series in the dataset.
303      */

304     public void setSeriesKeys(Comparable JavaDoc[] seriesKeys) {
305
306         // check argument...
307
if (seriesKeys == null) {
308             throw new IllegalArgumentException JavaDoc(
309                 "DefaultIntervalCategoryDataset.setSeriesKeys(): null not permitted.");
310         }
311
312         if (seriesKeys.length != getSeriesCount()) {
313             throw new IllegalArgumentException JavaDoc(
314                 "DefaultIntervalCategoryDataset.setSeriesKeys(): "
315                 + "the number of series keys does not match the data.");
316         }
317
318         // make the change...
319
this.seriesKeys = seriesKeys;
320         fireDatasetChanged();
321
322     }
323
324     /**
325      * Returns the number of categories in the dataset.
326      * <P>
327      * This method is part of the CategoryDataset interface.
328      *
329      * @return the number of categories in the dataset.
330      */

331     public int getCategoryCount() {
332
333         int result = 0;
334
335         if (startData != null) {
336             if (getSeriesCount() > 0) {
337                 result = startData[0].length;
338             }
339         }
340
341         return result;
342
343     }
344
345     /**
346      * Returns a list of the series in the dataset.
347      * <P>
348      * Supports the CategoryDataset interface.
349      *
350      * @return a list of the series in the dataset.
351      */

352     public List JavaDoc getSeries() {
353
354         // the CategoryDataset interface expects a list of series, but
355
// we've stored them in an array...
356
if (this.seriesKeys == null) {
357             return new java.util.ArrayList JavaDoc();
358         }
359         else {
360             return Collections.unmodifiableList(Arrays.asList(this.seriesKeys));
361         }
362
363     }
364
365     /**
366      * Returns a list of the categories in the dataset.
367      * <P>
368      * Supports the CategoryDataset interface.
369      *
370      * @return a list of the categories in the dataset.
371      */

372     public List JavaDoc getCategories() {
373         return getColumnKeys();
374     }
375
376     /**
377      * Returns a list of the categories in the dataset.
378      * <P>
379      * Supports the CategoryDataset interface.
380      *
381      * @return a list of the categories in the dataset.
382      */

383     public List JavaDoc getColumnKeys() {
384
385         // the CategoryDataset interface expects a list of categories, but
386
// we've stored them in an array...
387
if (this.categoryKeys == null) {
388             return new ArrayList JavaDoc();
389         }
390         else {
391             return Collections.unmodifiableList(Arrays.asList(this.categoryKeys));
392         }
393
394     }
395
396     /**
397      * Sets the categories for the dataset.
398      *
399      * @param categoryKeys An array of objects representing the categories in the dataset.
400      */

401     public void setCategoryKeys(Comparable JavaDoc[] categoryKeys) {
402
403         // check arguments...
404
if (categoryKeys == null) {
405             throw new IllegalArgumentException JavaDoc(
406                 "DefaultIntervalCategoryDataset.setCategories(...): null not permitted.");
407         }
408
409         if (categoryKeys.length != startData[0].length) {
410             throw new IllegalArgumentException JavaDoc(
411                 "DefaultIntervalCategoryDataset.setCategoryKeys(...): "
412                 + "the number of categories does not match the data.");
413         }
414
415         for (int i = 0; i < categoryKeys.length; i++) {
416             if (categoryKeys[i] == null) {
417                 throw new IllegalArgumentException JavaDoc(
418                     "DefaultIntervalCategoryDataset.setCategoryKeys(...): "
419                     + "null category not permitted.");
420             }
421         }
422
423         // make the change...
424
this.categoryKeys = categoryKeys;
425         fireDatasetChanged();
426
427     }
428
429     /**
430      * Returns the data value for one category in a series.
431      * <P>
432      * This method is part of the CategoryDataset interface. Not particularly
433      * meaningful for this class...returns the end value.
434      * @param series The required series (zero based index).
435      * @param category The required category.
436      * @return The data value for one category in a series (null possible).
437      */

438     public Number JavaDoc getValue(Comparable JavaDoc series, Comparable JavaDoc category) {
439         int seriesIndex = getSeriesIndex(series);
440         int itemIndex = getItem(category);
441         return getValue(seriesIndex, itemIndex);
442     }
443
444     /**
445      * Returns the data value for one category in a series.
446      * <P>
447      * This method is part of the CategoryDataset interface. Not particularly
448      * meaningful for this class...returns the end value.
449      *
450      * @param series The required series (zero based index).
451      * @param category The required category.
452      *
453      * @return The data value for one category in a series (null possible).
454      */

455     public Number JavaDoc getValue(int series, int category) {
456
457         return getEndValue(series, category);
458
459     }
460
461     /**
462      * Returns the start data value for one category in a series.
463      * <P>
464      * This method is part of the IntervalTableDataset interface.
465      *
466      * @param series The required series.
467      * @param category The required category.
468      *
469      * @return The start data value for one category in a series (null possible).
470      */

471     public Number JavaDoc getStartValue(Comparable JavaDoc series, Comparable JavaDoc category) {
472         int seriesIndex = getSeriesIndex(series);
473         int itemIndex = getItem(category);
474         return getStartValue(seriesIndex, itemIndex);
475     }
476
477     /**
478      * Returns the start data value for one category in a series.
479      * <P>
480      * This method is part of the IntervalTableDataset interface.
481      *
482      * @param series The required series (zero based index).
483      * @param category The required category.
484      *
485      * @return The start data value for one category in a series (null possible).
486      */

487     public Number JavaDoc getStartValue(int series, int category) {
488
489         // check arguments...
490
if ((series < 0) || (series >= getSeriesCount())) {
491             throw new IllegalArgumentException JavaDoc(
492                 "DefaultIntervalCategoryDataset.getValue(...): "
493                 + "series index out of range.");
494         }
495
496         if ((category < 0) || (category >= getCategoryCount())) {
497             throw new IllegalArgumentException JavaDoc(
498                 "DefaultIntervalCategoryDataset.getValue(...): "
499                 + "category index out of range.");
500         }
501
502         // fetch the value...
503
return startData[series][category];
504
505     }
506
507     /**
508      * Returns the end data value for one category in a series.
509      * <P>
510      * This method is part of the IntervalTableDataset interface.
511      *
512      * @param series the required series.
513      * @param category the required category.
514      *
515      * @return the end data value for one category in a series (null possible).
516      */

517     public Number JavaDoc getEndValue(Comparable JavaDoc series, Comparable JavaDoc category) {
518         int seriesIndex = getSeriesIndex(series);
519         int itemIndex = getItem(category);
520         return getEndValue(seriesIndex, itemIndex);
521     }
522
523     /**
524      * Returns the end data value for one category in a series.
525      * <P>
526      * This method is part of the IntervalTableDataset interface.
527      *
528      * @param series the required series (zero based index).
529      * @param category the required category.
530      *
531      * @return the end data value for one category in a series (null possible).
532      */

533     public Number JavaDoc getEndValue(int series, int category) {
534
535         // check arguments...
536
if ((series < 0) || (series >= getSeriesCount())) {
537             throw new IllegalArgumentException JavaDoc(
538                 "DefaultIntervalCategoryDataset.getValue(...): "
539                 + "series index out of range.");
540         }
541
542         if ((category < 0) || (category >= getCategoryCount())) {
543             throw new IllegalArgumentException JavaDoc(
544                 "DefaultIntervalCategoryDataset.getValue(...): "
545                 + "category index out of range.");
546         }
547
548         // fetch the value...
549
return endData[series][category];
550
551     }
552
553     /**
554      * Sets the start data value for one category in a series.
555      * @param series The series (zero-based index).
556      * @param category The category.
557      * @param value The value.
558      */

559     public void setStartValue(int series, Object JavaDoc category, Number JavaDoc value) {
560
561         // does the series exist?
562
if ((series < 0) || (series > getSeriesCount())) {
563             throw new IllegalArgumentException JavaDoc(
564                 "DefaultIntervalCategoryDataset.setValue: "
565                 + "series outside valid range.");
566         }
567
568         // is the category valid?
569
int categoryIndex = getCategoryIndex(category);
570         if (categoryIndex < 0) {
571             throw new IllegalArgumentException JavaDoc(
572                 "DefaultIntervalCategoryDataset.setValue: "
573                 + "unrecognised category.");
574         }
575
576         // update the data...
577
startData[series][categoryIndex] = value;
578         fireDatasetChanged();
579
580     }
581
582     /**
583      * Sets the end data value for one category in a series.
584      *
585      * @param series the series (zero-based index).
586      * @param category the category.
587      *
588      * @param value the value.
589      */

590     public void setEndValue(int series, Object JavaDoc category, Number JavaDoc value) {
591
592         // does the series exist?
593
if ((series < 0) || (series > getSeriesCount())) {
594             throw new IllegalArgumentException JavaDoc(
595                 "DefaultIntervalCategoryDataset.setValue: "
596                 + "series outside valid range.");
597         }
598
599         // is the category valid?
600
int categoryIndex = getCategoryIndex(category);
601         if (categoryIndex < 0) {
602             throw new IllegalArgumentException JavaDoc(
603                 "DefaultIntervalCategoryDataset.setValue: "
604                 + "unrecognised category.");
605         }
606
607         // update the data...
608
endData[series][categoryIndex] = value;
609         fireDatasetChanged();
610
611     }
612
613     /**
614      * Returns the index for the given category.
615      *
616      * @param category the category.
617      *
618      * @return the index.
619      */

620     private int getCategoryIndex(Object JavaDoc category) {
621
622         int result = -1;
623         for (int i = 0; i < this.categoryKeys.length; i++) {
624             if (category.equals(this.categoryKeys[i])) {
625                 result = i;
626                 break;
627             }
628         }
629         return result;
630
631     }
632
633     /**
634      * Generates an array of keys, by appending a space plus an integer
635      * (starting with 1) to the supplied prefix string.
636      *
637      * @param count the number of keys required.
638      * @param prefix the name prefix.
639      *
640      * @return an array of <i>prefixN</i> with N = { 1 .. count}.
641      */

642     private Comparable JavaDoc[] generateKeys(int count, String JavaDoc prefix) {
643
644         Comparable JavaDoc[] result = new Comparable JavaDoc[count];
645         String JavaDoc name;
646         for (int i = 0; i < count; i++) {
647             name = prefix + (i + 1);
648             result[i] = name;
649         }
650         return result;
651
652     }
653
654     /**
655      * Returns a column key.
656      *
657      * @param item the column index.
658      *
659      * @return The column key.
660      */

661     public Comparable JavaDoc getColumnKey(int item) {
662         return this.categoryKeys[item];
663     }
664
665     /**
666      * Returns a column index.
667      *
668      * @param columnKey the column key.
669      *
670      * @return The column index.
671      */

672     public int getColumnIndex(Comparable JavaDoc columnKey) {
673         List JavaDoc categories = getCategories();
674         return categories.indexOf(columnKey);
675     }
676
677     /**
678      * Returns a row index.
679      *
680      * @param rowKey the row key.
681      *
682      * @return The row index.
683      */

684     public int getRowIndex(Comparable JavaDoc rowKey) {
685         List JavaDoc seriesKeys = getSeries();
686         return seriesKeys.indexOf(rowKey);
687     }
688
689     /**
690      * Returns a list of the series in the dataset.
691      * <P>
692      * Supports the CategoryDataset interface.
693      *
694      * @return a list of the series in the dataset.
695      */

696     public List JavaDoc getRowKeys() {
697
698         // the CategoryDataset interface expects a list of series, but
699
// we've stored them in an array...
700
if (this.seriesKeys == null) {
701             return new java.util.ArrayList JavaDoc();
702         }
703         else {
704             return Collections.unmodifiableList(Arrays.asList(this.seriesKeys));
705         }
706
707     }
708
709     /**
710      * Returns the name of the specified series.
711      *
712      * @param series the index of the required series (zero-based).
713      *
714      * @return the name of the specified series.
715      */

716     public Comparable JavaDoc getRowKey(int series) {
717
718         // check argument...
719
if ((series >= getSeriesCount()) || (series < 0)) {
720             throw new IllegalArgumentException JavaDoc(
721                 "DefaultCategoryDataset.getSeriesName(int): no such series.");
722         }
723
724         // return the value...
725
return seriesKeys[series];
726
727     }
728
729     /**
730      * Returns the number of categories in the dataset.
731      * <P>
732      * This method is part of the CategoryDataset interface.
733      *
734      * @return the number of categories in the dataset.
735      */

736     public int getColumnCount() {
737
738         int result = 0;
739
740         if (startData != null) {
741             if (getSeriesCount() > 0) {
742                 result = startData[0].length;
743             }
744         }
745
746         return result;
747
748     }
749
750     /**
751      * Returns the number of series in the dataset (possibly zero).
752      *
753      * @return the number of series in the dataset.
754      */

755     public int getRowCount() {
756
757         int result = 0;
758         if (startData != null) {
759             result = startData.length;
760         }
761         return result;
762
763     }
764
765 }
766
Popular Tags