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