001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2008, 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     * DefaultOHLCDataset.java
029     * -----------------------
030     * (C) Copyright 2003-2008, by Object Refinery Limited.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * Changes
036     * -------
037     * 03-Dec-2003 : Version 1 (DG);
038     * 05-May-2004 : Now extends AbstractXYDataset (DG);
039     * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
040     *               getYValue() (DG);
041     * 29-Apr-2005 : Added equals() method (DG);
042     * 22-Apr-2008 : Implemented PublicCloneable, and fixed cloning bug (DG);
043     *
044     */
045    
046    package org.jfree.data.xy;
047    
048    import java.util.Arrays;
049    import java.util.Date;
050    
051    import org.jfree.util.PublicCloneable;
052    
053    /**
054     * A simple implementation of the {@link OHLCDataset} interface.  This
055     * implementation supports only one series.
056     */
057    public class DefaultOHLCDataset extends AbstractXYDataset
058            implements OHLCDataset, PublicCloneable {
059    
060        /** The series key. */
061        private Comparable key;
062    
063        /** Storage for the data items. */
064        private OHLCDataItem[] data;
065    
066        /**
067         * Creates a new dataset.
068         *
069         * @param key  the series key.
070         * @param data  the data items.
071         */
072        public DefaultOHLCDataset(Comparable key, OHLCDataItem[] data) {
073            this.key = key;
074            this.data = data;
075        }
076    
077        /**
078         * Returns the series key.
079         *
080         * @param series  the series index (ignored).
081         *
082         * @return The series key.
083         */
084        public Comparable getSeriesKey(int series) {
085            return this.key;
086        }
087    
088        /**
089         * Returns the x-value for a data item.
090         *
091         * @param series  the series index (ignored).
092         * @param item  the item index (zero-based).
093         *
094         * @return The x-value.
095         */
096        public Number getX(int series, int item) {
097            return new Long(this.data[item].getDate().getTime());
098        }
099    
100        /**
101         * Returns the x-value for a data item as a date.
102         *
103         * @param series  the series index (ignored).
104         * @param item  the item index (zero-based).
105         *
106         * @return The x-value as a date.
107         */
108        public Date getXDate(int series, int item) {
109            return this.data[item].getDate();
110        }
111    
112        /**
113         * Returns the y-value.
114         *
115         * @param series  the series index (ignored).
116         * @param item  the item index (zero-based).
117         *
118         * @return The y value.
119         */
120        public Number getY(int series, int item) {
121            return getClose(series, item);
122        }
123    
124        /**
125         * Returns the high value.
126         *
127         * @param series  the series index (ignored).
128         * @param item  the item index (zero-based).
129         *
130         * @return The high value.
131         */
132        public Number getHigh(int series, int item) {
133            return this.data[item].getHigh();
134        }
135    
136        /**
137         * Returns the high-value (as a double primitive) for an item within a
138         * series.
139         *
140         * @param series  the series (zero-based index).
141         * @param item  the item (zero-based index).
142         *
143         * @return The high-value.
144         */
145        public double getHighValue(int series, int item) {
146            double result = Double.NaN;
147            Number high = getHigh(series, item);
148            if (high != null) {
149                result = high.doubleValue();
150            }
151            return result;
152        }
153    
154        /**
155         * Returns the low value.
156         *
157         * @param series  the series index (ignored).
158         * @param item  the item index (zero-based).
159         *
160         * @return The low value.
161         */
162        public Number getLow(int series, int item) {
163            return this.data[item].getLow();
164        }
165    
166        /**
167         * Returns the low-value (as a double primitive) for an item within a
168         * series.
169         *
170         * @param series  the series (zero-based index).
171         * @param item  the item (zero-based index).
172         *
173         * @return The low-value.
174         */
175        public double getLowValue(int series, int item) {
176            double result = Double.NaN;
177            Number low = getLow(series, item);
178            if (low != null) {
179                result = low.doubleValue();
180            }
181            return result;
182        }
183    
184        /**
185         * Returns the open value.
186         *
187         * @param series  the series index (ignored).
188         * @param item  the item index (zero-based).
189         *
190         * @return The open value.
191         */
192        public Number getOpen(int series, int item) {
193            return this.data[item].getOpen();
194        }
195    
196        /**
197         * Returns the open-value (as a double primitive) for an item within a
198         * series.
199         *
200         * @param series  the series (zero-based index).
201         * @param item  the item (zero-based index).
202         *
203         * @return The open-value.
204         */
205        public double getOpenValue(int series, int item) {
206            double result = Double.NaN;
207            Number open = getOpen(series, item);
208            if (open != null) {
209                result = open.doubleValue();
210            }
211            return result;
212        }
213    
214        /**
215         * Returns the close value.
216         *
217         * @param series  the series index (ignored).
218         * @param item  the item index (zero-based).
219         *
220         * @return The close value.
221         */
222        public Number getClose(int series, int item) {
223            return this.data[item].getClose();
224        }
225    
226        /**
227         * Returns the close-value (as a double primitive) for an item within a
228         * series.
229         *
230         * @param series  the series (zero-based index).
231         * @param item  the item (zero-based index).
232         *
233         * @return The close-value.
234         */
235        public double getCloseValue(int series, int item) {
236            double result = Double.NaN;
237            Number close = getClose(series, item);
238            if (close != null) {
239                result = close.doubleValue();
240            }
241            return result;
242        }
243    
244        /**
245         * Returns the trading volume.
246         *
247         * @param series  the series index (ignored).
248         * @param item  the item index (zero-based).
249         *
250         * @return The trading volume.
251         */
252        public Number getVolume(int series, int item) {
253            return this.data[item].getVolume();
254        }
255    
256        /**
257         * Returns the volume-value (as a double primitive) for an item within a
258         * series.
259         *
260         * @param series  the series (zero-based index).
261         * @param item  the item (zero-based index).
262         *
263         * @return The volume-value.
264         */
265        public double getVolumeValue(int series, int item) {
266            double result = Double.NaN;
267            Number volume = getVolume(series, item);
268            if (volume != null) {
269                result = volume.doubleValue();
270            }
271            return result;
272        }
273    
274        /**
275         * Returns the series count.
276         *
277         * @return 1.
278         */
279        public int getSeriesCount() {
280            return 1;
281        }
282    
283        /**
284         * Returns the item count for the specified series.
285         *
286         * @param series  the series index (ignored).
287         *
288         * @return The item count.
289         */
290        public int getItemCount(int series) {
291            return this.data.length;
292        }
293    
294        /**
295         * Sorts the data into ascending order by date.
296         */
297        public void sortDataByDate() {
298            Arrays.sort(this.data);
299        }
300    
301        /**
302         * Tests this instance for equality with an arbitrary object.
303         *
304         * @param obj  the object (<code>null</code> permitted).
305         *
306         * @return A boolean.
307         */
308        public boolean equals(Object obj) {
309            if (this == obj) {
310                return true;
311            }
312            if (!(obj instanceof DefaultOHLCDataset)) {
313                return false;
314            }
315            DefaultOHLCDataset that = (DefaultOHLCDataset) obj;
316            if (!this.key.equals(that.key)) {
317                return false;
318            }
319            if (!Arrays.equals(this.data, that.data)) {
320                return false;
321            }
322            return true;
323        }
324    
325        /**
326         * Returns an independent copy of this dataset.
327         *
328         * @return A clone.
329         *
330         * @throws CloneNotSupportedException
331         */
332        public Object clone() throws CloneNotSupportedException {
333            DefaultOHLCDataset clone = (DefaultOHLCDataset) super.clone();
334            clone.data = new OHLCDataItem[this.data.length];
335            System.arraycopy(this.data, 0, clone.data, 0, this.data.length);
336            return clone;
337        }
338    
339    }