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: * OHLCSeriesCollection.java 29: * ------------------------- 30: * (C) Copyright 2006, 2007, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * Changes 36: * ------- 37: * 04-Dec-2006 : Version 1 (DG); 38: * 39: */ 40: 41: package org.jfree.data.time.ohlc; 42: 43: import java.io.Serializable; 44: import java.util.List; 45: 46: import org.jfree.data.general.DatasetChangeEvent; 47: import org.jfree.data.time.RegularTimePeriod; 48: import org.jfree.data.time.TimePeriodAnchor; 49: import org.jfree.data.xy.AbstractXYDataset; 50: import org.jfree.data.xy.OHLCDataset; 51: import org.jfree.util.ObjectUtilities; 52: 53: /** 54: * A collection of {@link OHLCSeries} objects. 55: * 56: * @since 1.0.4 57: * 58: * @see OHLCSeries 59: */ 60: public class OHLCSeriesCollection extends AbstractXYDataset 61: implements OHLCDataset, Serializable { 62: 63: /** Storage for the data series. */ 64: private List data; 65: 66: private TimePeriodAnchor xPosition = TimePeriodAnchor.MIDDLE; 67: 68: /** 69: * Creates a new instance of <code>OHLCSeriesCollection</code>. 70: */ 71: public OHLCSeriesCollection() { 72: this.data = new java.util.ArrayList(); 73: } 74: 75: /** 76: * Adds a series to the collection and sends a {@link DatasetChangeEvent} 77: * to all registered listeners. 78: * 79: * @param series the series (<code>null</code> not permitted). 80: */ 81: public void addSeries(OHLCSeries series) { 82: if (series == null) { 83: throw new IllegalArgumentException("Null 'series' argument."); 84: } 85: this.data.add(series); 86: series.addChangeListener(this); 87: fireDatasetChanged(); 88: } 89: 90: /** 91: * Returns the number of series in the collection. 92: * 93: * @return The series count. 94: */ 95: public int getSeriesCount() { 96: return this.data.size(); 97: } 98: 99: /** 100: * Returns a series from the collection. 101: * 102: * @param series the series index (zero-based). 103: * 104: * @return The series. 105: * 106: * @throws IllegalArgumentException if <code>series</code> is not in the 107: * range <code>0</code> to <code>getSeriesCount() - 1</code>. 108: */ 109: public OHLCSeries getSeries(int series) { 110: if ((series < 0) || (series >= getSeriesCount())) { 111: throw new IllegalArgumentException("Series index out of bounds"); 112: } 113: return (OHLCSeries) this.data.get(series); 114: } 115: 116: /** 117: * Returns the key for a series. 118: * 119: * @param series the series index (in the range <code>0</code> to 120: * <code>getSeriesCount() - 1</code>). 121: * 122: * @return The key for a series. 123: * 124: * @throws IllegalArgumentException if <code>series</code> is not in the 125: * specified range. 126: */ 127: public Comparable getSeriesKey(int series) { 128: // defer argument checking 129: return getSeries(series).getKey(); 130: } 131: 132: /** 133: * Returns the number of items in the specified series. 134: * 135: * @param series the series (zero-based index). 136: * 137: * @return The item count. 138: * 139: * @throws IllegalArgumentException if <code>series</code> is not in the 140: * range <code>0</code> to <code>getSeriesCount() - 1</code>. 141: */ 142: public int getItemCount(int series) { 143: // defer argument checking 144: return getSeries(series).getItemCount(); 145: } 146: 147: /** 148: * Returns the x-value for a time period. 149: * 150: * @param period the time period (<code>null</code> not permitted). 151: * 152: * @return The x-value. 153: */ 154: protected synchronized long getX(RegularTimePeriod period) { 155: long result = 0L; 156: if (this.xPosition == TimePeriodAnchor.START) { 157: result = period.getFirstMillisecond(); 158: } 159: else if (this.xPosition == TimePeriodAnchor.MIDDLE) { 160: result = period.getMiddleMillisecond(); 161: } 162: else if (this.xPosition == TimePeriodAnchor.END) { 163: result = period.getLastMillisecond(); 164: } 165: return result; 166: } 167: 168: /** 169: * Returns the x-value for an item within a series. 170: * 171: * @param series the series index. 172: * @param item the item index. 173: * 174: * @return The x-value. 175: */ 176: public double getXValue(int series, int item) { 177: OHLCSeries s = (OHLCSeries) this.data.get(series); 178: OHLCItem di = (OHLCItem) s.getDataItem(item); 179: RegularTimePeriod period = di.getPeriod(); 180: return getX(period); 181: } 182: 183: /** 184: * Returns the x-value for an item within a series. 185: * 186: * @param series the series index. 187: * @param item the item index. 188: * 189: * @return The x-value. 190: */ 191: public Number getX(int series, int item) { 192: return new Double(getXValue(series, item)); 193: } 194: 195: /** 196: * Returns the y-value for an item within a series. 197: * 198: * @param series the series index. 199: * @param item the item index. 200: * 201: * @return The y-value. 202: */ 203: public Number getY(int series, int item) { 204: OHLCSeries s = (OHLCSeries) this.data.get(series); 205: OHLCItem di = (OHLCItem) s.getDataItem(item); 206: return new Double(di.getYValue()); 207: } 208: 209: /** 210: * Returns the open-value for an item within a series. 211: * 212: * @param series the series index. 213: * @param item the item index. 214: * 215: * @return The open-value. 216: */ 217: public double getOpenValue(int series, int item) { 218: OHLCSeries s = (OHLCSeries) this.data.get(series); 219: OHLCItem di = (OHLCItem) s.getDataItem(item); 220: return di.getOpenValue(); 221: } 222: 223: /** 224: * Returns the open-value for an item within a series. 225: * 226: * @param series the series index. 227: * @param item the item index. 228: * 229: * @return The open-value. 230: */ 231: public Number getOpen(int series, int item) { 232: return new Double(getOpenValue(series, item)); 233: } 234: 235: /** 236: * Returns the close-value for an item within a series. 237: * 238: * @param series the series index. 239: * @param item the item index. 240: * 241: * @return The close-value. 242: */ 243: public double getCloseValue(int series, int item) { 244: OHLCSeries s = (OHLCSeries) this.data.get(series); 245: OHLCItem di = (OHLCItem) s.getDataItem(item); 246: return di.getCloseValue(); 247: } 248: 249: /** 250: * Returns the close-value for an item within a series. 251: * 252: * @param series the series index. 253: * @param item the item index. 254: * 255: * @return The close-value. 256: */ 257: public Number getClose(int series, int item) { 258: return new Double(getCloseValue(series, item)); 259: } 260: 261: /** 262: * Returns the high-value for an item within a series. 263: * 264: * @param series the series index. 265: * @param item the item index. 266: * 267: * @return The high-value. 268: */ 269: public double getHighValue(int series, int item) { 270: OHLCSeries s = (OHLCSeries) this.data.get(series); 271: OHLCItem di = (OHLCItem) s.getDataItem(item); 272: return di.getHighValue(); 273: } 274: 275: /** 276: * Returns the high-value for an item within a series. 277: * 278: * @param series the series index. 279: * @param item the item index. 280: * 281: * @return The high-value. 282: */ 283: public Number getHigh(int series, int item) { 284: return new Double(getHighValue(series, item)); 285: } 286: 287: /** 288: * Returns the low-value for an item within a series. 289: * 290: * @param series the series index. 291: * @param item the item index. 292: * 293: * @return The low-value. 294: */ 295: public double getLowValue(int series, int item) { 296: OHLCSeries s = (OHLCSeries) this.data.get(series); 297: OHLCItem di = (OHLCItem) s.getDataItem(item); 298: return di.getLowValue(); 299: } 300: 301: /** 302: * Returns the low-value for an item within a series. 303: * 304: * @param series the series index. 305: * @param item the item index. 306: * 307: * @return The low-value. 308: */ 309: public Number getLow(int series, int item) { 310: return new Double(getLowValue(series, item)); 311: } 312: 313: public Number getVolume(int series, int item) { 314: return null; 315: } 316: 317: public double getVolumeValue(int series, int item) { 318: return Double.NaN; 319: } 320: 321: /** 322: * Tests this instance for equality with an arbitrary object. 323: * 324: * @param obj the object (<code>null</code> permitted). 325: * 326: * @return A boolean. 327: */ 328: public boolean equals(Object obj) { 329: if (obj == this) { 330: return true; 331: } 332: if (!(obj instanceof OHLCSeriesCollection)) { 333: return false; 334: } 335: OHLCSeriesCollection that = (OHLCSeriesCollection) obj; 336: return ObjectUtilities.equal(this.data, that.data); 337: } 338: 339: /** 340: * Returns a clone of this instance. 341: * 342: * @return A clone. 343: * 344: * @throws CloneNotSupportedException if there is a problem. 345: */ 346: public Object clone() throws CloneNotSupportedException { 347: OHLCSeriesCollection clone 348: = (OHLCSeriesCollection) super.clone(); 349: clone.data = (List) ObjectUtilities.deepClone(this.data); 350: return clone; 351: } 352: 353: }