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