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 }