    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2011, 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
    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    }