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