    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2005, 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-2005, 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     * $Id: SubSeriesDataset.java,v 1.5.2.2 2005/11/30 11:58:58 mungady Exp $
    037     *
    038     * Changes
    039     * -------
    040     * 06-Dec-2001 : Version 1 (BK);
    041     * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset
    042     *               interface) as requested by Sylvain Vieujot (DG);
    043     * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and
    044     *               SignalsDataset methods (BK);
    045     * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
    046     * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG);
    047     * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
    048     *               getYValue() (DG);
    049     * 29-Nov-2005 : Removed SignalsDataset (DG);
    050     *
    051     */
    052
    053    package org.jfree.data.general;
    054
    055    import org.jfree.data.xy.AbstractIntervalXYDataset;
    056    import org.jfree.data.xy.OHLCDataset;
    057    import org.jfree.data.xy.IntervalXYDataset;
    058    import org.jfree.data.xy.XYDataset;
    059
    060    /**
    061     * This class will create a dataset with one or more series from another
    062     * {@link SeriesDataset}.
    063     *
    064     * @author Bill Kelemen (bill@kelemen-usa.com)
    065     */
    066    public class SubSeriesDataset extends AbstractIntervalXYDataset
    067                                  implements OHLCDataset,
    068                                             IntervalXYDataset,
    069                                             CombinationDataset {
    070
    071        /** The parent dataset. */
    072        private SeriesDataset parent = null;
    073
    074        /** Storage for map. */
    075        private int[] map;  // maps our series into our parent's
    076
    077        /**
    078         * Creates a SubSeriesDataset using one or more series from
    079         * <code>parent</code>.  The series to use are passed as an array of int.
    080         *
    081         * @param parent  underlying dataset
    082         * @param map  int[] of series from parent to include in this Dataset
    083         */
    084        public SubSeriesDataset(SeriesDataset parent, int[] map) {
    085            this.parent = parent;
    086            this.map = map;
    087        }
    088
    089        /**
    090         * Creates a SubSeriesDataset using one series from <code>parent</code>.
    091         * The series to is passed as an int.
    092         *
    093         * @param parent  underlying dataset
    094         * @param series  series from parent to include in this Dataset
    095         */
    096        public SubSeriesDataset(SeriesDataset parent, int series) {
    097            this(parent, new int[] {series});
    098        }
    099
    100        ///////////////////////////////////////////////////////////////////////////
    101        // From HighLowDataset
    102        ///////////////////////////////////////////////////////////////////////////
    103
    104        /**
    105         * Returns the high-value for the specified series and item.
    106         * <p>
    107         * Note: throws <code>ClassCastException</code> if the series if not from a
    108         * {@link OHLCDataset}.
    109         *
    110         * @param series  the index of the series of interest (zero-based).
    111         * @param item  the index of the item of interest (zero-based).
    112         *
    113         * @return The high-value for the specified series and item.
    114         */
    115        public Number getHigh(int series, int item) {
    116            return ((OHLCDataset) this.parent).getHigh(this.map[series], item);
    117        }
    118
    119        /**
    120         * Returns the high-value (as a double primitive) for an item within a
    121         * series.
    122         *
    123         * @param series  the series (zero-based index).
    124         * @param item  the item (zero-based index).
    125         *
    126         * @return The high-value.
    127         */
    128        public double getHighValue(int series, int item) {
    129            double result = Double.NaN;
    130            Number high = getHigh(series, item);
    131            if (high != null) {
    132                result = high.doubleValue();
    133            }
    134            return result;
    135        }
    136
    137        /**
    138         * Returns the low-value for the specified series and item.
    139         * <p>
    140         * Note: throws <code>ClassCastException</code> if the series if not from a
    141         * {@link OHLCDataset}.
    142         *
    143         * @param series  the index of the series of interest (zero-based).
    144         * @param item  the index of the item of interest (zero-based).
    145         *
    146         * @return The low-value for the specified series and item.
    147         */
    148        public Number getLow(int series, int item) {
    149            return ((OHLCDataset) this.parent).getLow(this.map[series], item);
    150        }
    151
    152        /**
    153         * Returns the low-value (as a double primitive) for an item within a
    154         * series.
    155         *
    156         * @param series  the series (zero-based index).
    157         * @param item  the item (zero-based index).
    158         *
    159         * @return The low-value.
    160         */
    161        public double getLowValue(int series, int item) {
    162            double result = Double.NaN;
    163            Number low = getLow(series, item);
    164            if (low != null) {
    165                result = low.doubleValue();
    166            }
    167            return result;
    168        }
    169
    170        /**
    171         * Returns the open-value for the specified series and item.
    172         * <p>
    173         * Note: throws <code>ClassCastException</code> if the series if not from a
    174         * {@link OHLCDataset}.
    175         *
    176         * @param series  the index of the series of interest (zero-based).
    177         * @param item  the index of the item of interest (zero-based).
    178         *
    179         * @return The open-value for the specified series and item.
    180         */
    181        public Number getOpen(int series, int item) {
    182            return ((OHLCDataset) this.parent).getOpen(this.map[series], item);
    183        }
    184
    185        /**
    186         * Returns the open-value (as a double primitive) for an item within a
    187         * series.
    188         *
    189         * @param series  the series (zero-based index).
    190         * @param item  the item (zero-based index).
    191         *
    192         * @return The open-value.
    193         */
    194        public double getOpenValue(int series, int item) {
    195            double result = Double.NaN;
    196            Number open = getOpen(series, item);
    197            if (open != null) {
    198                result = open.doubleValue();
    199            }
    200            return result;
    201        }
    202
    203        /**
    204         * Returns the close-value for the specified series and item.
    205         * <p>
    206         * Note: throws <code>ClassCastException</code> if the series if not from a
    207         * {@link OHLCDataset}.
    208         *
    209         * @param series  the index of the series of interest (zero-based).
    210         * @param item  the index of the item of interest (zero-based).
    211         *
    212         * @return The close-value for the specified series and item.
    213         */
    214        public Number getClose(int series, int item) {
    215            return ((OHLCDataset) this.parent).getClose(this.map[series], item);
    216        }
    217
    218        /**
    219         * Returns the close-value (as a double primitive) for an item within a
    220         * series.
    221         *
    222         * @param series  the series (zero-based index).
    223         * @param item  the item (zero-based index).
    224         *
    225         * @return The close-value.
    226         */
    227        public double getCloseValue(int series, int item) {
    228            double result = Double.NaN;
    229            Number close = getClose(series, item);
    230            if (close != null) {
    231                result = close.doubleValue();
    232            }
    233            return result;
    234        }
    235
    236        /**
    237         * Returns the volume.
    238         * <p>
    239         * Note: throws <code>ClassCastException</code> if the series if not from a
    240         * {@link OHLCDataset}.
    241         *
    242         * @param series  the series (zero based index).
    243         * @param item  the item (zero based index).
    244         *
    245         * @return The volume.
    246         */
    247        public Number getVolume(int series, int item) {
    248            return ((OHLCDataset) this.parent).getVolume(this.map[series], item);
    249        }
    250
    251        /**
    252         * Returns the volume-value (as a double primitive) for an item within a
    253         * series.
    254         *
    255         * @param series  the series (zero-based index).
    256         * @param item  the item (zero-based index).
    257         *
    258         * @return The volume-value.
    259         */
    260        public double getVolumeValue(int series, int item) {
    261            double result = Double.NaN;
    262            Number volume = getVolume(series, item);
    263            if (volume != null) {
    264                result = volume.doubleValue();
    265            }
    266            return result;
    267        }
    268
    269        ///////////////////////////////////////////////////////////////////////////
    270        // From XYDataset
    271        ///////////////////////////////////////////////////////////////////////////
    272
    273        /**
    274         * Returns the X-value for the specified series and item.
    275         * <p>
    276         * Note: throws <code>ClassCastException</code> if the series if not from a
    277         * {@link XYDataset}.
    278         *
    279         * @param series  the index of the series of interest (zero-based);
    280         * @param item  the index of the item of interest (zero-based).
    281         *
    282         * @return The X-value for the specified series and item.
    283         */
    284        public Number getX(int series, int item) {
    285            return ((XYDataset) this.parent).getX(this.map[series], item);
    286        }
    287
    288        /**
    289         * Returns the Y-value for the specified series and item.
    290         * <p>
    291         * Note: throws <code>ClassCastException</code> if the series if not from a
    292         * {@link XYDataset}.
    293         *
    294         * @param series  the index of the series of interest (zero-based).
    295         * @param item  the index of the item of interest (zero-based).
    296         *
    297         * @return The Y-value for the specified series and item.
    298         */
    299        public Number getY(int series, int item) {
    300            return ((XYDataset) this.parent).getY(this.map[series], item);
    301        }
    302
    303        /**
    304         * Returns the number of items in a series.
    305         * <p>
    306         * Note: throws <code>ClassCastException</code> if the series if not from a
    307         * {@link XYDataset}.
    308         *
    309         * @param series  the index of the series of interest (zero-based).
    310         *
    311         * @return The number of items in a series.
    312         */
    313        public int getItemCount(int series) {
    314            return ((XYDataset) this.parent).getItemCount(this.map[series]);
    315        }
    316
    317        ///////////////////////////////////////////////////////////////////////////
    318        // From SeriesDataset
    319        ///////////////////////////////////////////////////////////////////////////
    320
    321        /**
    322         * Returns the number of series in the dataset.
    323         *
    324         * @return The number of series in the dataset.
    325         */
    326        public int getSeriesCount() {
    327            return this.map.length;
    328        }
    329
    330        /**
    331         * Returns the key for a series.
    332         *
    333         * @param series  the series (zero-based index).
    334         *
    335         * @return The name of a series.
    336         */
    337        public Comparable getSeriesKey(int series) {
    338            return this.parent.getSeriesKey(this.map[series]);
    339        }
    340
    341        ///////////////////////////////////////////////////////////////////////////
    342        // From IntervalXYDataset
    343        ///////////////////////////////////////////////////////////////////////////
    344
    345        /**
    346         * Returns the starting X value for the specified series and item.
    347         *
    348         * @param series  the index of the series of interest (zero-based).
    349         * @param item  the index of the item of interest (zero-based).
    350         *
    351         * @return The starting X value for the specified series and item.
    352         */
    353        public Number getStartX(int series, int item) {
    354            if (this.parent instanceof IntervalXYDataset) {
    355                return ((IntervalXYDataset) this.parent).getStartX(
    356                    this.map[series], item
    357                );
    358            }
    359            else {
    360                return getX(series, item);
    361            }
    362        }
    363
    364        /**
    365         * Returns the ending X value for the specified series and item.
    366         *
    367         * @param series  the index of the series of interest (zero-based).
    368         * @param item  the index of the item of interest (zero-based).
    369         *
    370         * @return The ending X value for the specified series and item.
    371         */
    372        public Number getEndX(int series, int item) {
    373            if (this.parent instanceof IntervalXYDataset) {
    374                return ((IntervalXYDataset) this.parent).getEndX(
    375                    this.map[series], item
    376                );
    377            }
    378            else {
    379                return getX(series, item);
    380            }
    381        }
    382
    383        /**
    384         * Returns the starting Y value for the specified series and item.
    385         *
    386         * @param series  the index of the series of interest (zero-based).
    387         * @param item  the index of the item of interest (zero-based).
    388         *
    389         * @return The starting Y value for the specified series and item.
    390         */
    391        public Number getStartY(int series, int item) {
    392            if (this.parent instanceof IntervalXYDataset) {
    393                return ((IntervalXYDataset) this.parent).getStartY(
    394                    this.map[series], item
    395                );
    396            }
    397            else {
    398                return getY(series, item);
    399            }
    400        }
    401
    402        /**
    403         * Returns the ending 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 ending Y value for the specified series and item.
    409         */
    410        public Number getEndY(int series,  int item) {
    411            if (this.parent instanceof IntervalXYDataset) {
    412                return ((IntervalXYDataset) this.parent).getEndY(
    413                    this.map[series], item
    414                );
    415            }
    416            else {
    417                return getY(series, item);
    418            }
    419        }
    420
    421        ///////////////////////////////////////////////////////////////////////////
    422        // New methods from CombinationDataset
    423        ///////////////////////////////////////////////////////////////////////////
    424
    425        /**
    426         * Returns the parent Dataset of this combination.
    427         *
    428         * @return The parent Dataset of this combination.
    429         */
    430        public SeriesDataset getParent() {
    431            return this.parent;
    432        }
    433
    434        /**
    435         * Returns a map or indirect indexing form our series into parent's series.
    436         *
    437         * @return A map or indirect indexing form our series into parent's series.
    438         */
    439        public int[] getMap() {
    440            return (int[]) this.map.clone();
    441        }
    442
    443    }