001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2009, by Object Refinery Limited and Contributors.
006     *
007     * Project Info:  http://www.jfree.org/jfreechart/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it
010     * under the terms of the GNU Lesser General Public License as published by
011     * the Free Software Foundation; either version 2.1 of the License, or
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
022     * USA.
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025     * in the United States and other countries.]
026     *
027     * ---------------------
028     * SubseriesDataset.java
029     * ---------------------
030     * (C) Copyright 2001-2009, by Bill Kelemen and Contributors.
031     *
032     * Original Author:  Bill Kelemen;
033     * Contributor(s):   Sylvain Vieujot;
034     *                   David Gilbert (for Object Refinery Limited);
035     *
036     * Changes
037     * -------
038     * 06-Dec-2001 : Version 1 (BK);
039     * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset
040     *               interface) as requested by Sylvain Vieujot (DG);
041     * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and
042     *               SignalsDataset methods (BK);
043     * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
044     * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG);
045     * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
046     *               getYValue() (DG);
047     * 29-Nov-2005 : Removed SignalsDataset (DG);
048     * ------------- JFREECHART 1.0.x ---------------------------------------------
049     * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
050     * 04-Feb-2009 : Deprecated, this class won't be supported in version
051     *               1.2.0 (DG);
052     *
053     */
054    
055    package org.jfree.data.general;
056    
057    import org.jfree.data.xy.AbstractIntervalXYDataset;
058    import org.jfree.data.xy.IntervalXYDataset;
059    import org.jfree.data.xy.OHLCDataset;
060    import org.jfree.data.xy.XYDataset;
061    
062    /**
063     * This class will create a dataset with one or more series from another
064     * {@link SeriesDataset}.
065     *
066     * @deprecated As of version 1.0.13.  This class will be removed from
067     *     JFreeChart 1.2.0 onwards.  Anyone needing this facility will need to
068     *     maintain it outside of JFreeChart.
069     */
070    public class SubSeriesDataset extends AbstractIntervalXYDataset
071            implements OHLCDataset, IntervalXYDataset, CombinationDataset {
072    
073        /** The parent dataset. */
074        private SeriesDataset parent = null;
075    
076        /** Storage for map. */
077        private int[] map;  // maps our series into our parent's
078    
079        /**
080         * Creates a SubSeriesDataset using one or more series from
081         * <code>parent</code>.  The series to use are passed as an array of int.
082         *
083         * @param parent  underlying dataset
084         * @param map  int[] of series from parent to include in this Dataset
085         */
086        public SubSeriesDataset(SeriesDataset parent, int[] map) {
087            this.parent = parent;
088            this.map = map;
089        }
090    
091        /**
092         * Creates a SubSeriesDataset using one series from <code>parent</code>.
093         * The series to is passed as an int.
094         *
095         * @param parent  underlying dataset
096         * @param series  series from parent to include in this Dataset
097         */
098        public SubSeriesDataset(SeriesDataset parent, int series) {
099            this(parent, new int[] {series});
100        }
101    
102        ///////////////////////////////////////////////////////////////////////////
103        // From HighLowDataset
104        ///////////////////////////////////////////////////////////////////////////
105    
106        /**
107         * Returns the high-value for the specified series and item.
108         * <p>
109         * Note: throws <code>ClassCastException</code> if the series if not from a
110         * {@link OHLCDataset}.
111         *
112         * @param series  the index of the series of interest (zero-based).
113         * @param item  the index of the item of interest (zero-based).
114         *
115         * @return The high-value for the specified series and item.
116         */
117        public Number getHigh(int series, int item) {
118            return ((OHLCDataset) this.parent).getHigh(this.map[series], item);
119        }
120    
121        /**
122         * Returns the high-value (as a double primitive) for an item within a
123         * series.
124         *
125         * @param series  the series (zero-based index).
126         * @param item  the item (zero-based index).
127         *
128         * @return The high-value.
129         */
130        public double getHighValue(int series, int item) {
131            double result = Double.NaN;
132            Number high = getHigh(series, item);
133            if (high != null) {
134                result = high.doubleValue();
135            }
136            return result;
137        }
138    
139        /**
140         * Returns the low-value for the specified series and item.
141         * <p>
142         * Note: throws <code>ClassCastException</code> if the series if not from a
143         * {@link OHLCDataset}.
144         *
145         * @param series  the index of the series of interest (zero-based).
146         * @param item  the index of the item of interest (zero-based).
147         *
148         * @return The low-value for the specified series and item.
149         */
150        public Number getLow(int series, int item) {
151            return ((OHLCDataset) this.parent).getLow(this.map[series], item);
152        }
153    
154        /**
155         * Returns the low-value (as a double primitive) for an item within a
156         * series.
157         *
158         * @param series  the series (zero-based index).
159         * @param item  the item (zero-based index).
160         *
161         * @return The low-value.
162         */
163        public double getLowValue(int series, int item) {
164            double result = Double.NaN;
165            Number low = getLow(series, item);
166            if (low != null) {
167                result = low.doubleValue();
168            }
169            return result;
170        }
171    
172        /**
173         * Returns the open-value for the specified series and item.
174         * <p>
175         * Note: throws <code>ClassCastException</code> if the series if not from a
176         * {@link OHLCDataset}.
177         *
178         * @param series  the index of the series of interest (zero-based).
179         * @param item  the index of the item of interest (zero-based).
180         *
181         * @return The open-value for the specified series and item.
182         */
183        public Number getOpen(int series, int item) {
184            return ((OHLCDataset) this.parent).getOpen(this.map[series], item);
185        }
186    
187        /**
188         * Returns the open-value (as a double primitive) for an item within a
189         * series.
190         *
191         * @param series  the series (zero-based index).
192         * @param item  the item (zero-based index).
193         *
194         * @return The open-value.
195         */
196        public double getOpenValue(int series, int item) {
197            double result = Double.NaN;
198            Number open = getOpen(series, item);
199            if (open != null) {
200                result = open.doubleValue();
201            }
202            return result;
203        }
204    
205        /**
206         * Returns the close-value for the specified series and item.
207         * <p>
208         * Note: throws <code>ClassCastException</code> if the series if not from a
209         * {@link OHLCDataset}.
210         *
211         * @param series  the index of the series of interest (zero-based).
212         * @param item  the index of the item of interest (zero-based).
213         *
214         * @return The close-value for the specified series and item.
215         */
216        public Number getClose(int series, int item) {
217            return ((OHLCDataset) this.parent).getClose(this.map[series], item);
218        }
219    
220        /**
221         * Returns the close-value (as a double primitive) for an item within a
222         * series.
223         *
224         * @param series  the series (zero-based index).
225         * @param item  the item (zero-based index).
226         *
227         * @return The close-value.
228         */
229        public double getCloseValue(int series, int item) {
230            double result = Double.NaN;
231            Number close = getClose(series, item);
232            if (close != null) {
233                result = close.doubleValue();
234            }
235            return result;
236        }
237    
238        /**
239         * Returns the volume.
240         * <p>
241         * Note: throws <code>ClassCastException</code> if the series if not from a
242         * {@link OHLCDataset}.
243         *
244         * @param series  the series (zero based index).
245         * @param item  the item (zero based index).
246         *
247         * @return The volume.
248         */
249        public Number getVolume(int series, int item) {
250            return ((OHLCDataset) this.parent).getVolume(this.map[series], item);
251        }
252    
253        /**
254         * Returns the volume-value (as a double primitive) for an item within a
255         * series.
256         *
257         * @param series  the series (zero-based index).
258         * @param item  the item (zero-based index).
259         *
260         * @return The volume-value.
261         */
262        public double getVolumeValue(int series, int item) {
263            double result = Double.NaN;
264            Number volume = getVolume(series, item);
265            if (volume != null) {
266                result = volume.doubleValue();
267            }
268            return result;
269        }
270    
271        ///////////////////////////////////////////////////////////////////////////
272        // From XYDataset
273        ///////////////////////////////////////////////////////////////////////////
274    
275        /**
276         * Returns the X-value for the specified series and item.
277         * <p>
278         * Note: throws <code>ClassCastException</code> if the series if not from a
279         * {@link XYDataset}.
280         *
281         * @param series  the index of the series of interest (zero-based);
282         * @param item  the index of the item of interest (zero-based).
283         *
284         * @return The X-value for the specified series and item.
285         */
286        public Number getX(int series, int item) {
287            return ((XYDataset) this.parent).getX(this.map[series], item);
288        }
289    
290        /**
291         * Returns the Y-value for the specified series and item.
292         * <p>
293         * Note: throws <code>ClassCastException</code> if the series if not from a
294         * {@link XYDataset}.
295         *
296         * @param series  the index of the series of interest (zero-based).
297         * @param item  the index of the item of interest (zero-based).
298         *
299         * @return The Y-value for the specified series and item.
300         */
301        public Number getY(int series, int item) {
302            return ((XYDataset) this.parent).getY(this.map[series], item);
303        }
304    
305        /**
306         * Returns the number of items in a series.
307         * <p>
308         * Note: throws <code>ClassCastException</code> if the series if not from a
309         * {@link XYDataset}.
310         *
311         * @param series  the index of the series of interest (zero-based).
312         *
313         * @return The number of items in a series.
314         */
315        public int getItemCount(int series) {
316            return ((XYDataset) this.parent).getItemCount(this.map[series]);
317        }
318    
319        ///////////////////////////////////////////////////////////////////////////
320        // From SeriesDataset
321        ///////////////////////////////////////////////////////////////////////////
322    
323        /**
324         * Returns the number of series in the dataset.
325         *
326         * @return The number of series in the dataset.
327         */
328        public int getSeriesCount() {
329            return this.map.length;
330        }
331    
332        /**
333         * Returns the key for a series.
334         *
335         * @param series  the series (zero-based index).
336         *
337         * @return The name of a series.
338         */
339        public Comparable getSeriesKey(int series) {
340            return this.parent.getSeriesKey(this.map[series]);
341        }
342    
343        ///////////////////////////////////////////////////////////////////////////
344        // From IntervalXYDataset
345        ///////////////////////////////////////////////////////////////////////////
346    
347        /**
348         * Returns the starting X value for the specified series and item.
349         *
350         * @param series  the index of the series of interest (zero-based).
351         * @param item  the index of the item of interest (zero-based).
352         *
353         * @return The starting X value for the specified series and item.
354         */
355        public Number getStartX(int series, int item) {
356            if (this.parent instanceof IntervalXYDataset) {
357                return ((IntervalXYDataset) this.parent).getStartX(
358                    this.map[series], item
359                );
360            }
361            else {
362                return getX(series, item);
363            }
364        }
365    
366        /**
367         * Returns the ending X value for the specified series and item.
368         *
369         * @param series  the index of the series of interest (zero-based).
370         * @param item  the index of the item of interest (zero-based).
371         *
372         * @return The ending X value for the specified series and item.
373         */
374        public Number getEndX(int series, int item) {
375            if (this.parent instanceof IntervalXYDataset) {
376                return ((IntervalXYDataset) this.parent).getEndX(
377                    this.map[series], item
378                );
379            }
380            else {
381                return getX(series, item);
382            }
383        }
384    
385        /**
386         * Returns the starting Y value for the specified series and item.
387         *
388         * @param series  the index of the series of interest (zero-based).
389         * @param item  the index of the item of interest (zero-based).
390         *
391         * @return The starting Y value for the specified series and item.
392         */
393        public Number getStartY(int series, int item) {
394            if (this.parent instanceof IntervalXYDataset) {
395                return ((IntervalXYDataset) this.parent).getStartY(
396                    this.map[series], item
397                );
398            }
399            else {
400                return getY(series, item);
401            }
402        }
403    
404        /**
405         * Returns the ending Y value for the specified series and item.
406         *
407         * @param series  the index of the series of interest (zero-based).
408         * @param item  the index of the item of interest (zero-based).
409         *
410         * @return The ending Y value for the specified series and item.
411         */
412        public Number getEndY(int series,  int item) {
413            if (this.parent instanceof IntervalXYDataset) {
414                return ((IntervalXYDataset) this.parent).getEndY(
415                    this.map[series], item
416                );
417            }
418            else {
419                return getY(series, item);
420            }
421        }
422    
423        ///////////////////////////////////////////////////////////////////////////
424        // New methods from CombinationDataset
425        ///////////////////////////////////////////////////////////////////////////
426    
427        /**
428         * Returns the parent Dataset of this combination.
429         *
430         * @return The parent Dataset of this combination.
431         */
432        public SeriesDataset getParent() {
433            return this.parent;
434        }
435    
436        /**
437         * Returns a map or indirect indexing form our series into parent's series.
438         *
439         * @return A map or indirect indexing form our series into parent's series.
440         */
441        public int[] getMap() {
442            return (int[]) this.map.clone();
443        }
444    
445    }