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