Source for org.jfree.data.general.SubSeriesDataset

   1: /* ===========================================================
   2:  * JFreeChart : a free chart library for the Java(tm) platform
   3:  * ===========================================================
   4:  *
   5:  * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
   6:  *
   7:  * Project Info:  http://www.jfree.org/jfreechart/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  *
  27:  * ---------------------
  28:  * SubseriesDataset.java
  29:  * ---------------------
  30:  * (C) Copyright 2001-2007, by Bill Kelemen and Contributors.
  31:  *
  32:  * Original Author:  Bill Kelemen;
  33:  * Contributor(s):   Sylvain Vieujot;
  34:  *                   David Gilbert (for Object Refinery Limited);
  35:  *
  36:  * $Id: SubSeriesDataset.java,v 1.5.2.3 2007/02/02 15:50:44 mungady Exp $
  37:  *
  38:  * Changes
  39:  * -------
  40:  * 06-Dec-2001 : Version 1 (BK);
  41:  * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset 
  42:  *               interface) as requested by Sylvain Vieujot (DG);
  43:  * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and 
  44:  *               SignalsDataset methods (BK);
  45:  * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  46:  * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG);
  47:  * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 
  48:  *               getYValue() (DG);
  49:  * 29-Nov-2005 : Removed SignalsDataset (DG);
  50:  * ------------- JFREECHART 1.0.x ---------------------------------------------
  51:  * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
  52:  *
  53:  */
  54: 
  55: package org.jfree.data.general;
  56: 
  57: import org.jfree.data.xy.AbstractIntervalXYDataset;
  58: import org.jfree.data.xy.OHLCDataset;
  59: import org.jfree.data.xy.IntervalXYDataset;
  60: import org.jfree.data.xy.XYDataset;
  61: 
  62: /**
  63:  * This class will create a dataset with one or more series from another
  64:  * {@link SeriesDataset}. 
  65:  */
  66: public class SubSeriesDataset extends AbstractIntervalXYDataset
  67:                               implements OHLCDataset,
  68:                                          IntervalXYDataset,
  69:                                          CombinationDataset {
  70: 
  71:     /** The parent dataset. */
  72:     private SeriesDataset parent = null;
  73: 
  74:     /** Storage for map. */
  75:     private int[] map;  // maps our series into our parent's
  76: 
  77:     /**
  78:      * Creates a SubSeriesDataset using one or more series from 
  79:      * <code>parent</code>.  The series to use are passed as an array of int.
  80:      *
  81:      * @param parent  underlying dataset
  82:      * @param map  int[] of series from parent to include in this Dataset
  83:      */
  84:     public SubSeriesDataset(SeriesDataset parent, int[] map) {
  85:         this.parent = parent;
  86:         this.map = map;
  87:     }
  88: 
  89:     /**
  90:      * Creates a SubSeriesDataset using one series from <code>parent</code>.
  91:      * The series to is passed as an int.
  92:      *
  93:      * @param parent  underlying dataset
  94:      * @param series  series from parent to include in this Dataset
  95:      */
  96:     public SubSeriesDataset(SeriesDataset parent, int series) {
  97:         this(parent, new int[] {series});
  98:     }
  99: 
 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: }