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