Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2006, 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: * DefaultHighLowDataset.java 29: * -------------------------- 30: * (C) Copyright 2002-2006, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * $Id: DefaultHighLowDataset.java,v 1.6.2.2 2006/11/28 10:41:51 mungady Exp $ 36: * 37: * Changes 38: * ------- 39: * 21-Mar-2002 : Version 1 (DG); 40: * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG); 41: * 06-May-2004 : Now extends AbstractXYDataset and added new methods from 42: * HighLowDataset (DG); 43: * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 44: * getYValue() (DG); 45: * ------------- JFREECHART 1.0.x --------------------------------------------- 46: * 28-Nov-2006 : Added equals() method override (DG); 47: * 48: */ 49: 50: package org.jfree.data.xy; 51: 52: import java.util.Arrays; 53: import java.util.Date; 54: 55: /** 56: * A simple implementation of the {@link OHLCDataset} interface. See also 57: * the {@link DefaultOHLCDataset} class, which provides another implementation 58: * that is very similar. 59: */ 60: public class DefaultHighLowDataset extends AbstractXYDataset 61: implements OHLCDataset { 62: 63: /** The series key. */ 64: private Comparable seriesKey; 65: 66: /** Storage for the dates. */ 67: private Date[] date; 68: 69: /** Storage for the high values. */ 70: private Number[] high; 71: 72: /** Storage for the low values. */ 73: private Number[] low; 74: 75: /** Storage for the open values. */ 76: private Number[] open; 77: 78: /** Storage for the close values. */ 79: private Number[] close; 80: 81: /** Storage for the volume values. */ 82: private Number[] volume; 83: 84: /** 85: * Constructs a new high/low/open/close dataset. 86: * <p> 87: * The current implementation allows only one series in the dataset. 88: * This may be extended in a future version. 89: * 90: * @param seriesKey the key for the series (<code>null</code> not 91: * permitted). 92: * @param date the dates (<code>null</code> not permitted). 93: * @param high the high values (<code>null</code> not permitted). 94: * @param low the low values (<code>null</code> not permitted). 95: * @param open the open values (<code>null</code> not permitted). 96: * @param close the close values (<code>null</code> not permitted). 97: * @param volume the volume values (<code>null</code> not permitted). 98: */ 99: public DefaultHighLowDataset(Comparable seriesKey, Date[] date, 100: double[] high, double[] low, double[] open, double[] close, 101: double[] volume) { 102: 103: if (seriesKey == null) { 104: throw new IllegalArgumentException("Null 'series' argument."); 105: } 106: if (date == null) { 107: throw new IllegalArgumentException("Null 'date' argument."); 108: } 109: this.seriesKey = seriesKey; 110: this.date = date; 111: this.high = createNumberArray(high); 112: this.low = createNumberArray(low); 113: this.open = createNumberArray(open); 114: this.close = createNumberArray(close); 115: this.volume = createNumberArray(volume); 116: 117: } 118: 119: /** 120: * Returns the key for the series stored in this dataset. 121: * 122: * @param series the index of the series (ignored, this dataset supports 123: * only one series and this method always returns the key for series 0). 124: * 125: * @return The series key (never <code>null</code>). 126: */ 127: public Comparable getSeriesKey(int series) { 128: return this.seriesKey; 129: } 130: 131: /** 132: * Returns the x-value for one item in a series. The value returned is a 133: * <code>Long</code> instance generated from the underlying 134: * <code>Date</code> object. To avoid generating a new object instance, 135: * you might prefer to call {@link #getXValue(int, int)}. 136: * 137: * @param series the series (zero-based index). 138: * @param item the item (zero-based index). 139: * 140: * @return The x-value. 141: * 142: * @see #getXValue(int, int) 143: * @see #getXDate(int, int) 144: */ 145: public Number getX(int series, int item) { 146: return new Long(this.date[item].getTime()); 147: } 148: 149: /** 150: * Returns the x-value for one item in a series, as a Date. 151: * <p> 152: * This method is provided for convenience only. 153: * 154: * @param series the series (zero-based index). 155: * @param item the item (zero-based index). 156: * 157: * @return The x-value as a Date. 158: * 159: * @see #getX(int, int) 160: */ 161: public Date getXDate(int series, int item) { 162: return this.date[item]; 163: } 164: 165: /** 166: * Returns the y-value for one item in a series. 167: * <p> 168: * This method (from the {@link XYDataset} interface) is mapped to the 169: * {@link #getCloseValue(int, int)} method. 170: * 171: * @param series the series (zero-based index). 172: * @param item the item (zero-based index). 173: * 174: * @return The y-value. 175: * 176: * @see #getYValue(int, int) 177: */ 178: public Number getY(int series, int item) { 179: return getClose(series, item); 180: } 181: 182: /** 183: * Returns the high-value for one item in a series. 184: * 185: * @param series the series (zero-based index). 186: * @param item the item (zero-based index). 187: * 188: * @return The high-value. 189: * 190: * @see #getHighValue(int, int) 191: */ 192: public Number getHigh(int series, int item) { 193: return this.high[item]; 194: } 195: 196: /** 197: * Returns the high-value (as a double primitive) for an item within a 198: * series. 199: * 200: * @param series the series (zero-based index). 201: * @param item the item (zero-based index). 202: * 203: * @return The high-value. 204: * 205: * @see #getHigh(int, int) 206: */ 207: public double getHighValue(int series, int item) { 208: double result = Double.NaN; 209: Number high = getHigh(series, item); 210: if (high != null) { 211: result = high.doubleValue(); 212: } 213: return result; 214: } 215: 216: /** 217: * Returns the low-value for one item in a series. 218: * 219: * @param series the series (zero-based index). 220: * @param item the item (zero-based index). 221: * 222: * @return The low-value. 223: * 224: * @see #getLowValue(int, int) 225: */ 226: public Number getLow(int series, int item) { 227: return this.low[item]; 228: } 229: 230: /** 231: * Returns the low-value (as a double primitive) for an item within a 232: * series. 233: * 234: * @param series the series (zero-based index). 235: * @param item the item (zero-based index). 236: * 237: * @return The low-value. 238: * 239: * @see #getLow(int, int) 240: */ 241: public double getLowValue(int series, int item) { 242: double result = Double.NaN; 243: Number low = getLow(series, item); 244: if (low != null) { 245: result = low.doubleValue(); 246: } 247: return result; 248: } 249: 250: /** 251: * Returns the open-value for one item in a series. 252: * 253: * @param series the series (zero-based index). 254: * @param item the item (zero-based index). 255: * 256: * @return The open-value. 257: * 258: * @see #getOpenValue(int, int) 259: */ 260: public Number getOpen(int series, int item) { 261: return this.open[item]; 262: } 263: 264: /** 265: * Returns the open-value (as a double primitive) for an item within a 266: * series. 267: * 268: * @param series the series (zero-based index). 269: * @param item the item (zero-based index). 270: * 271: * @return The open-value. 272: * 273: * @see #getOpen(int, int) 274: */ 275: public double getOpenValue(int series, int item) { 276: double result = Double.NaN; 277: Number open = getOpen(series, item); 278: if (open != null) { 279: result = open.doubleValue(); 280: } 281: return result; 282: } 283: 284: /** 285: * Returns the close-value for one item in a series. 286: * 287: * @param series the series (zero-based index). 288: * @param item the item (zero-based index). 289: * 290: * @return The close-value. 291: * 292: * @see #getCloseValue(int, int) 293: */ 294: public Number getClose(int series, int item) { 295: return this.close[item]; 296: } 297: 298: /** 299: * Returns the close-value (as a double primitive) for an item within a 300: * series. 301: * 302: * @param series the series (zero-based index). 303: * @param item the item (zero-based index). 304: * 305: * @return The close-value. 306: * 307: * @see #getClose(int, int) 308: */ 309: public double getCloseValue(int series, int item) { 310: double result = Double.NaN; 311: Number close = getClose(series, item); 312: if (close != null) { 313: result = close.doubleValue(); 314: } 315: return result; 316: } 317: 318: /** 319: * Returns the volume-value for one item in a series. 320: * 321: * @param series the series (zero-based index). 322: * @param item the item (zero-based index). 323: * 324: * @return The volume-value. 325: * 326: * @see #getVolumeValue(int, int) 327: */ 328: public Number getVolume(int series, int item) { 329: return this.volume[item]; 330: } 331: 332: /** 333: * Returns the volume-value (as a double primitive) for an item within a 334: * series. 335: * 336: * @param series the series (zero-based index). 337: * @param item the item (zero-based index). 338: * 339: * @return The volume-value. 340: * 341: * @see #getVolume(int, int) 342: */ 343: public double getVolumeValue(int series, int item) { 344: double result = Double.NaN; 345: Number volume = getVolume(series, item); 346: if (volume != null) { 347: result = volume.doubleValue(); 348: } 349: return result; 350: } 351: 352: /** 353: * Returns the number of series in the dataset. 354: * <p> 355: * This implementation only allows one series. 356: * 357: * @return The number of series. 358: */ 359: public int getSeriesCount() { 360: return 1; 361: } 362: 363: /** 364: * Returns the number of items in the specified series. 365: * 366: * @param series the index (zero-based) of the series. 367: * 368: * @return The number of items in the specified series. 369: */ 370: public int getItemCount(int series) { 371: return this.date.length; 372: } 373: 374: /** 375: * Tests this dataset for equality with an arbitrary instance. 376: * 377: * @param obj the object (<code>null</code> permitted). 378: * 379: * @return A boolean. 380: */ 381: public boolean equals(Object obj) { 382: if (obj == this) { 383: return true; 384: } 385: if (!(obj instanceof DefaultHighLowDataset)) { 386: return false; 387: } 388: DefaultHighLowDataset that = (DefaultHighLowDataset) obj; 389: if (!this.seriesKey.equals(that.seriesKey)) { 390: return false; 391: } 392: if (!Arrays.equals(this.date, that.date)) { 393: return false; 394: } 395: if (!Arrays.equals(this.open, that.open)) { 396: return false; 397: } 398: if (!Arrays.equals(this.high, that.high)) { 399: return false; 400: } 401: if (!Arrays.equals(this.low, that.low)) { 402: return false; 403: } 404: if (!Arrays.equals(this.close, that.close)) { 405: return false; 406: } 407: if (!Arrays.equals(this.volume, that.volume)) { 408: return false; 409: } 410: return true; 411: } 412: 413: /** 414: * Constructs an array of Number objects from an array of doubles. 415: * 416: * @param data the double values to convert (<code>null</code> not 417: * permitted). 418: * 419: * @return The data as an array of Number objects. 420: */ 421: public static Number[] createNumberArray(double[] data) { 422: Number[] result = new Number[data.length]; 423: for (int i = 0; i < data.length; i++) { 424: result[i] = new Double(data[i]); 425: } 426: return result; 427: } 428: 429: }