001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2005, 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-2005, 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 * $Id: SubSeriesDataset.java,v 1.5.2.2 2005/11/30 11:58:58 mungady Exp $ 037 * 038 * Changes 039 * ------- 040 * 06-Dec-2001 : Version 1 (BK); 041 * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset 042 * interface) as requested by Sylvain Vieujot (DG); 043 * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and 044 * SignalsDataset methods (BK); 045 * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG); 046 * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG); 047 * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 048 * getYValue() (DG); 049 * 29-Nov-2005 : Removed SignalsDataset (DG); 050 * 051 */ 052 053 package org.jfree.data.general; 054 055 import org.jfree.data.xy.AbstractIntervalXYDataset; 056 import org.jfree.data.xy.OHLCDataset; 057 import org.jfree.data.xy.IntervalXYDataset; 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 * @author Bill Kelemen (bill@kelemen-usa.com) 065 */ 066 public class SubSeriesDataset extends AbstractIntervalXYDataset 067 implements OHLCDataset, 068 IntervalXYDataset, 069 CombinationDataset { 070 071 /** The parent dataset. */ 072 private SeriesDataset parent = null; 073 074 /** Storage for map. */ 075 private int[] map; // maps our series into our parent's 076 077 /** 078 * Creates a SubSeriesDataset using one or more series from 079 * <code>parent</code>. The series to use are passed as an array of int. 080 * 081 * @param parent underlying dataset 082 * @param map int[] of series from parent to include in this Dataset 083 */ 084 public SubSeriesDataset(SeriesDataset parent, int[] map) { 085 this.parent = parent; 086 this.map = map; 087 } 088 089 /** 090 * Creates a SubSeriesDataset using one series from <code>parent</code>. 091 * The series to is passed as an int. 092 * 093 * @param parent underlying dataset 094 * @param series series from parent to include in this Dataset 095 */ 096 public SubSeriesDataset(SeriesDataset parent, int series) { 097 this(parent, new int[] {series}); 098 } 099 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 }