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 }