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:  * Changes
  37:  * -------
  38:  * 06-Dec-2001 : Version 1 (BK);
  39:  * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset 
  40:  *               interface) as requested by Sylvain Vieujot (DG);
  41:  * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and 
  42:  *               SignalsDataset methods (BK);
  43:  * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  44:  * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG);
  45:  * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 
  46:  *               getYValue() (DG);
  47:  * 29-Nov-2005 : Removed SignalsDataset (DG);
  48:  * ------------- JFREECHART 1.0.x ---------------------------------------------
  49:  * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
  50:  *
  51:  */
  52: 
  53: package org.jfree.data.general;
  54: 
  55: import org.jfree.data.xy.AbstractIntervalXYDataset;
  56: import org.jfree.data.xy.IntervalXYDataset;
  57: import org.jfree.data.xy.OHLCDataset;
  58: import org.jfree.data.xy.XYDataset;
  59: 
  60: /**
  61:  * This class will create a dataset with one or more series from another
  62:  * {@link SeriesDataset}. 
  63:  */
  64: public class SubSeriesDataset extends AbstractIntervalXYDataset
  65:                               implements OHLCDataset,
  66:                                          IntervalXYDataset,
  67:                                          CombinationDataset {
  68: 
  69:     /** The parent dataset. */
  70:     private SeriesDataset parent = null;
  71: 
  72:     /** Storage for map. */
  73:     private int[] map;  // maps our series into our parent's
  74: 
  75:     /**
  76:      * Creates a SubSeriesDataset using one or more series from 
  77:      * <code>parent</code>.  The series to use are passed as an array of int.
  78:      *
  79:      * @param parent  underlying dataset
  80:      * @param map  int[] of series from parent to include in this Dataset
  81:      */
  82:     public SubSeriesDataset(SeriesDataset parent, int[] map) {
  83:         this.parent = parent;
  84:         this.map = map;
  85:     }
  86: 
  87:     /**
  88:      * Creates a SubSeriesDataset using one series from <code>parent</code>.
  89:      * The series to is passed as an int.
  90:      *
  91:      * @param parent  underlying dataset
  92:      * @param series  series from parent to include in this Dataset
  93:      */
  94:     public SubSeriesDataset(SeriesDataset parent, int series) {
  95:         this(parent, new int[] {series});
  96:     }
  97: 
  98:     ///////////////////////////////////////////////////////////////////////////
  99:     // 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: }