001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2013, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
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
055package org.jfree.data.general;
056
057import org.jfree.data.xy.AbstractIntervalXYDataset;
058import org.jfree.data.xy.IntervalXYDataset;
059import org.jfree.data.xy.OHLCDataset;
060import 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 */
070public 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    @Override
118    public Number getHigh(int series, int item) {
119        return ((OHLCDataset) this.parent).getHigh(this.map[series], item);
120    }
121
122    /**
123     * Returns the high-value (as a double primitive) for an item within a
124     * series.
125     *
126     * @param series  the series (zero-based index).
127     * @param item  the item (zero-based index).
128     *
129     * @return The high-value.
130     */
131    @Override
132    public double getHighValue(int series, int item) {
133        double result = Double.NaN;
134        Number high = getHigh(series, item);
135        if (high != null) {
136            result = high.doubleValue();
137        }
138        return result;
139    }
140
141    /**
142     * Returns the low-value for the specified series and item.
143     * <p>
144     * Note: throws <code>ClassCastException</code> if the series if not from a
145     * {@link OHLCDataset}.
146     *
147     * @param series  the index of the series of interest (zero-based).
148     * @param item  the index of the item of interest (zero-based).
149     *
150     * @return The low-value for the specified series and item.
151     */
152    @Override
153    public Number getLow(int series, int item) {
154        return ((OHLCDataset) this.parent).getLow(this.map[series], item);
155    }
156
157    /**
158     * Returns the low-value (as a double primitive) for an item within a
159     * series.
160     *
161     * @param series  the series (zero-based index).
162     * @param item  the item (zero-based index).
163     *
164     * @return The low-value.
165     */
166    @Override
167    public double getLowValue(int series, int item) {
168        double result = Double.NaN;
169        Number low = getLow(series, item);
170        if (low != null) {
171            result = low.doubleValue();
172        }
173        return result;
174    }
175
176    /**
177     * Returns the open-value for the specified series and item.
178     * <p>
179     * Note: throws <code>ClassCastException</code> if the series if not from a
180     * {@link OHLCDataset}.
181     *
182     * @param series  the index of the series of interest (zero-based).
183     * @param item  the index of the item of interest (zero-based).
184     *
185     * @return The open-value for the specified series and item.
186     */
187    @Override
188    public Number getOpen(int series, int item) {
189        return ((OHLCDataset) this.parent).getOpen(this.map[series], item);
190    }
191
192    /**
193     * Returns the open-value (as a double primitive) for an item within a
194     * series.
195     *
196     * @param series  the series (zero-based index).
197     * @param item  the item (zero-based index).
198     *
199     * @return The open-value.
200     */
201    @Override
202    public double getOpenValue(int series, int item) {
203        double result = Double.NaN;
204        Number open = getOpen(series, item);
205        if (open != null) {
206            result = open.doubleValue();
207        }
208        return result;
209    }
210
211    /**
212     * Returns the close-value for the specified series and item.
213     * <p>
214     * Note: throws <code>ClassCastException</code> if the series if not from a
215     * {@link OHLCDataset}.
216     *
217     * @param series  the index of the series of interest (zero-based).
218     * @param item  the index of the item of interest (zero-based).
219     *
220     * @return The close-value for the specified series and item.
221     */
222    @Override
223    public Number getClose(int series, int item) {
224        return ((OHLCDataset) this.parent).getClose(this.map[series], item);
225    }
226
227    /**
228     * Returns the close-value (as a double primitive) for an item within a
229     * series.
230     *
231     * @param series  the series (zero-based index).
232     * @param item  the item (zero-based index).
233     *
234     * @return The close-value.
235     */
236    @Override
237    public double getCloseValue(int series, int item) {
238        double result = Double.NaN;
239        Number close = getClose(series, item);
240        if (close != null) {
241            result = close.doubleValue();
242        }
243        return result;
244    }
245
246    /**
247     * Returns the volume.
248     * <p>
249     * Note: throws <code>ClassCastException</code> if the series if not from a
250     * {@link OHLCDataset}.
251     *
252     * @param series  the series (zero based index).
253     * @param item  the item (zero based index).
254     *
255     * @return The volume.
256     */
257    @Override
258    public Number getVolume(int series, int item) {
259        return ((OHLCDataset) this.parent).getVolume(this.map[series], item);
260    }
261
262    /**
263     * Returns the volume-value (as a double primitive) for an item within a
264     * series.
265     *
266     * @param series  the series (zero-based index).
267     * @param item  the item (zero-based index).
268     *
269     * @return The volume-value.
270     */
271    @Override
272    public double getVolumeValue(int series, int item) {
273        double result = Double.NaN;
274        Number volume = getVolume(series, item);
275        if (volume != null) {
276            result = volume.doubleValue();
277        }
278        return result;
279    }
280
281    ///////////////////////////////////////////////////////////////////////////
282    // From XYDataset
283    ///////////////////////////////////////////////////////////////////////////
284
285    /**
286     * Returns the X-value for the specified series and item.
287     * <p>
288     * Note: throws <code>ClassCastException</code> if the series if not from a
289     * {@link XYDataset}.
290     *
291     * @param series  the index of the series of interest (zero-based);
292     * @param item  the index of the item of interest (zero-based).
293     *
294     * @return The X-value for the specified series and item.
295     */
296    @Override
297    public Number getX(int series, int item) {
298        return ((XYDataset) this.parent).getX(this.map[series], item);
299    }
300
301    /**
302     * Returns the Y-value for the specified series and item.
303     * <p>
304     * Note: throws <code>ClassCastException</code> if the series if not from a
305     * {@link XYDataset}.
306     *
307     * @param series  the index of the series of interest (zero-based).
308     * @param item  the index of the item of interest (zero-based).
309     *
310     * @return The Y-value for the specified series and item.
311     */
312    @Override
313    public Number getY(int series, int item) {
314        return ((XYDataset) this.parent).getY(this.map[series], item);
315    }
316
317    /**
318     * Returns the number of items in a series.
319     * <p>
320     * Note: throws <code>ClassCastException</code> if the series if not from a
321     * {@link XYDataset}.
322     *
323     * @param series  the index of the series of interest (zero-based).
324     *
325     * @return The number of items in a series.
326     */
327    @Override
328    public int getItemCount(int series) {
329        return ((XYDataset) this.parent).getItemCount(this.map[series]);
330    }
331
332    ///////////////////////////////////////////////////////////////////////////
333    // From SeriesDataset
334    ///////////////////////////////////////////////////////////////////////////
335
336    /**
337     * Returns the number of series in the dataset.
338     *
339     * @return The number of series in the dataset.
340     */
341    @Override
342    public int getSeriesCount() {
343        return this.map.length;
344    }
345
346    /**
347     * Returns the key for a series.
348     *
349     * @param series  the series (zero-based index).
350     *
351     * @return The name of a series.
352     */
353    @Override
354    public Comparable getSeriesKey(int series) {
355        return this.parent.getSeriesKey(this.map[series]);
356    }
357
358    ///////////////////////////////////////////////////////////////////////////
359    // From IntervalXYDataset
360    ///////////////////////////////////////////////////////////////////////////
361
362    /**
363     * Returns the starting X value for the specified series and item.
364     *
365     * @param series  the index of the series of interest (zero-based).
366     * @param item  the index of the item of interest (zero-based).
367     *
368     * @return The starting X value for the specified series and item.
369     */
370    @Override
371    public Number getStartX(int series, int item) {
372        if (this.parent instanceof IntervalXYDataset) {
373            return ((IntervalXYDataset) this.parent).getStartX(
374                this.map[series], item
375            );
376        }
377        else {
378            return getX(series, item);
379        }
380    }
381
382    /**
383     * Returns the ending X value for the specified series and item.
384     *
385     * @param series  the index of the series of interest (zero-based).
386     * @param item  the index of the item of interest (zero-based).
387     *
388     * @return The ending X value for the specified series and item.
389     */
390    @Override
391    public Number getEndX(int series, int item) {
392        if (this.parent instanceof IntervalXYDataset) {
393            return ((IntervalXYDataset) this.parent).getEndX(
394                this.map[series], item
395            );
396        }
397        else {
398            return getX(series, item);
399        }
400    }
401
402    /**
403     * Returns the starting Y value for the specified series and item.
404     *
405     * @param series  the index of the series of interest (zero-based).
406     * @param item  the index of the item of interest (zero-based).
407     *
408     * @return The starting Y value for the specified series and item.
409     */
410    @Override
411    public Number getStartY(int series, int item) {
412        if (this.parent instanceof IntervalXYDataset) {
413            return ((IntervalXYDataset) this.parent).getStartY(
414                this.map[series], item
415            );
416        }
417        else {
418            return getY(series, item);
419        }
420    }
421
422    /**
423     * Returns the ending Y value for the specified series and item.
424     *
425     * @param series  the index of the series of interest (zero-based).
426     * @param item  the index of the item of interest (zero-based).
427     *
428     * @return The ending Y value for the specified series and item.
429     */
430    @Override
431    public Number getEndY(int series,  int item) {
432        if (this.parent instanceof IntervalXYDataset) {
433            return ((IntervalXYDataset) this.parent).getEndY(
434                this.map[series], item
435            );
436        }
437        else {
438            return getY(series, item);
439        }
440    }
441
442    ///////////////////////////////////////////////////////////////////////////
443    // New methods from CombinationDataset
444    ///////////////////////////////////////////////////////////////////////////
445
446    /**
447     * Returns the parent Dataset of this combination.
448     *
449     * @return The parent Dataset of this combination.
450     */
451    @Override
452    public SeriesDataset getParent() {
453        return this.parent;
454    }
455
456    /**
457     * Returns a map or indirect indexing form our series into parent's series.
458     *
459     * @return A map or indirect indexing form our series into parent's series.
460     */
461    @Override
462    public int[] getMap() {
463        return (int[]) this.map.clone();
464    }
465
466}