001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2006, 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 * OHLCSeriesCollection.java 029 * ------------------------- 030 * (C) Copyright 2006, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * $Id: OHLCSeriesCollection.java,v 1.1.2.1 2006/12/04 17:08:36 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 04-Dec-2006 : Version 1 (DG); 040 * 041 */ 042 043 package org.jfree.data.time.ohlc; 044 045 import java.io.Serializable; 046 import java.util.List; 047 048 import org.jfree.data.general.DatasetChangeEvent; 049 import org.jfree.data.time.RegularTimePeriod; 050 import org.jfree.data.time.TimePeriodAnchor; 051 import org.jfree.data.xy.AbstractXYDataset; 052 import org.jfree.data.xy.OHLCDataset; 053 import org.jfree.util.ObjectUtilities; 054 055 /** 056 * A collection of {@link OHLCSeries} objects. 057 * 058 * @since 1.0.4 059 * 060 * @see OHLCSeries 061 */ 062 public class OHLCSeriesCollection extends AbstractXYDataset 063 implements OHLCDataset, Serializable { 064 065 /** Storage for the data series. */ 066 private List data; 067 068 private TimePeriodAnchor xPosition = TimePeriodAnchor.MIDDLE; 069 070 /** 071 * Creates a new instance of <code>OHLCSeriesCollection</code>. 072 */ 073 public OHLCSeriesCollection() { 074 this.data = new java.util.ArrayList(); 075 } 076 077 /** 078 * Adds a series to the collection and sends a {@link DatasetChangeEvent} 079 * to all registered listeners. 080 * 081 * @param series the series (<code>null</code> not permitted). 082 */ 083 public void addSeries(OHLCSeries series) { 084 if (series == null) { 085 throw new IllegalArgumentException("Null 'series' argument."); 086 } 087 this.data.add(series); 088 series.addChangeListener(this); 089 fireDatasetChanged(); 090 } 091 092 /** 093 * Returns the number of series in the collection. 094 * 095 * @return The series count. 096 */ 097 public int getSeriesCount() { 098 return this.data.size(); 099 } 100 101 /** 102 * Returns a series from the collection. 103 * 104 * @param series the series index (zero-based). 105 * 106 * @return The series. 107 * 108 * @throws IllegalArgumentException if <code>series</code> is not in the 109 * range <code>0</code> to <code>getSeriesCount() - 1</code>. 110 */ 111 public OHLCSeries getSeries(int series) { 112 if ((series < 0) || (series >= getSeriesCount())) { 113 throw new IllegalArgumentException("Series index out of bounds"); 114 } 115 return (OHLCSeries) this.data.get(series); 116 } 117 118 /** 119 * Returns the key for a series. 120 * 121 * @param series the series index (in the range <code>0</code> to 122 * <code>getSeriesCount() - 1</code>). 123 * 124 * @return The key for a series. 125 * 126 * @throws IllegalArgumentException if <code>series</code> is not in the 127 * specified range. 128 */ 129 public Comparable getSeriesKey(int series) { 130 // defer argument checking 131 return getSeries(series).getKey(); 132 } 133 134 /** 135 * Returns the number of items in the specified series. 136 * 137 * @param series the series (zero-based index). 138 * 139 * @return The item count. 140 * 141 * @throws IllegalArgumentException if <code>series</code> is not in the 142 * range <code>0</code> to <code>getSeriesCount() - 1</code>. 143 */ 144 public int getItemCount(int series) { 145 // defer argument checking 146 return getSeries(series).getItemCount(); 147 } 148 149 /** 150 * Returns the x-value for a time period. 151 * 152 * @param period the time period (<code>null</code> not permitted). 153 * 154 * @return The x-value. 155 */ 156 protected synchronized long getX(RegularTimePeriod period) { 157 long result = 0L; 158 if (this.xPosition == TimePeriodAnchor.START) { 159 result = period.getFirstMillisecond(); 160 } 161 else if (this.xPosition == TimePeriodAnchor.MIDDLE) { 162 result = period.getMiddleMillisecond(); 163 } 164 else if (this.xPosition == TimePeriodAnchor.END) { 165 result = period.getLastMillisecond(); 166 } 167 return result; 168 } 169 170 /** 171 * Returns the x-value for an item within a series. 172 * 173 * @param series the series index. 174 * @param item the item index. 175 * 176 * @return The x-value. 177 */ 178 public double getXValue(int series, int item) { 179 OHLCSeries s = (OHLCSeries) this.data.get(series); 180 OHLCItem di = (OHLCItem) s.getDataItem(item); 181 RegularTimePeriod period = di.getPeriod(); 182 return getX(period); 183 } 184 185 /** 186 * Returns the x-value for an item within a series. 187 * 188 * @param series the series index. 189 * @param item the item index. 190 * 191 * @return The x-value. 192 */ 193 public Number getX(int series, int item) { 194 return new Double(getXValue(series, item)); 195 } 196 197 /** 198 * Returns the y-value for an item within a series. 199 * 200 * @param series the series index. 201 * @param item the item index. 202 * 203 * @return The y-value. 204 */ 205 public Number getY(int series, int item) { 206 OHLCSeries s = (OHLCSeries) this.data.get(series); 207 OHLCItem di = (OHLCItem) s.getDataItem(item); 208 return new Double(di.getYValue()); 209 } 210 211 /** 212 * Returns the open-value for an item within a series. 213 * 214 * @param series the series index. 215 * @param item the item index. 216 * 217 * @return The open-value. 218 */ 219 public double getOpenValue(int series, int item) { 220 OHLCSeries s = (OHLCSeries) this.data.get(series); 221 OHLCItem di = (OHLCItem) s.getDataItem(item); 222 return di.getOpenValue(); 223 } 224 225 /** 226 * Returns the open-value for an item within a series. 227 * 228 * @param series the series index. 229 * @param item the item index. 230 * 231 * @return The open-value. 232 */ 233 public Number getOpen(int series, int item) { 234 return new Double(getOpenValue(series, item)); 235 } 236 237 /** 238 * Returns the close-value for an item within a series. 239 * 240 * @param series the series index. 241 * @param item the item index. 242 * 243 * @return The close-value. 244 */ 245 public double getCloseValue(int series, int item) { 246 OHLCSeries s = (OHLCSeries) this.data.get(series); 247 OHLCItem di = (OHLCItem) s.getDataItem(item); 248 return di.getCloseValue(); 249 } 250 251 /** 252 * Returns the close-value for an item within a series. 253 * 254 * @param series the series index. 255 * @param item the item index. 256 * 257 * @return The close-value. 258 */ 259 public Number getClose(int series, int item) { 260 return new Double(getCloseValue(series, item)); 261 } 262 263 /** 264 * Returns the high-value for an item within a series. 265 * 266 * @param series the series index. 267 * @param item the item index. 268 * 269 * @return The high-value. 270 */ 271 public double getHighValue(int series, int item) { 272 OHLCSeries s = (OHLCSeries) this.data.get(series); 273 OHLCItem di = (OHLCItem) s.getDataItem(item); 274 return di.getHighValue(); 275 } 276 277 /** 278 * Returns the high-value for an item within a series. 279 * 280 * @param series the series index. 281 * @param item the item index. 282 * 283 * @return The high-value. 284 */ 285 public Number getHigh(int series, int item) { 286 return new Double(getHighValue(series, item)); 287 } 288 289 /** 290 * Returns the low-value for an item within a series. 291 * 292 * @param series the series index. 293 * @param item the item index. 294 * 295 * @return The low-value. 296 */ 297 public double getLowValue(int series, int item) { 298 OHLCSeries s = (OHLCSeries) this.data.get(series); 299 OHLCItem di = (OHLCItem) s.getDataItem(item); 300 return di.getLowValue(); 301 } 302 303 /** 304 * Returns the low-value for an item within a series. 305 * 306 * @param series the series index. 307 * @param item the item index. 308 * 309 * @return The low-value. 310 */ 311 public Number getLow(int series, int item) { 312 return new Double(getLowValue(series, item)); 313 } 314 315 public Number getVolume(int series, int item) { 316 return null; 317 } 318 319 public double getVolumeValue(int series, int item) { 320 return Double.NaN; 321 } 322 323 /** 324 * Tests this instance for equality with an arbitrary object. 325 * 326 * @param obj the object (<code>null</code> permitted). 327 * 328 * @return A boolean. 329 */ 330 public boolean equals(Object obj) { 331 if (obj == this) { 332 return true; 333 } 334 if (!(obj instanceof OHLCSeriesCollection)) { 335 return false; 336 } 337 OHLCSeriesCollection that = (OHLCSeriesCollection) obj; 338 return ObjectUtilities.equal(this.data, that.data); 339 } 340 341 /** 342 * Returns a clone of this instance. 343 * 344 * @return A clone. 345 * 346 * @throws CloneNotSupportedException if there is a problem. 347 */ 348 public Object clone() throws CloneNotSupportedException { 349 OHLCSeriesCollection clone 350 = (OHLCSeriesCollection) super.clone(); 351 clone.data = (List) ObjectUtilities.deepClone(this.data); 352 return clone; 353 } 354 355 }