001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2005, 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     * DefaultHighLowDataset.java
029     * --------------------------
030     * (C) Copyright 2002-2005, by Object Refinery Limited.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * $Id: DefaultHighLowDataset.java,v 1.6.2.1 2005/10/25 21:36:51 mungady Exp $
036     *
037     * Changes
038     * -------
039     * 21-Mar-2002 : Version 1 (DG);
040     * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
041     * 06-May-2004 : Now extends AbstractXYDataset and added new methods from 
042     *               HighLowDataset (DG);
043     * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 
044     *               getYValue() (DG);
045     *
046     */
047    
048    package org.jfree.data.xy;
049    
050    import java.util.Date;
051    
052    /**
053     * A simple implementation of the {@link OHLCDataset}.
054     */
055    public class DefaultHighLowDataset extends AbstractXYDataset 
056                                       implements OHLCDataset {
057    
058        /** The series key. */
059        private Comparable seriesKey;
060    
061        /** Storage for the dates. */
062        private Date[] date;
063    
064        /** Storage for the high values. */
065        private Number[] high;
066    
067        /** Storage for the low values. */
068        private Number[] low;
069    
070        /** Storage for the open values. */
071        private Number[] open;
072    
073        /** Storage for the close values. */
074        private Number[] close;
075    
076        /** Storage for the volume values. */
077        private Number[] volume;
078    
079        /**
080         * Constructs a new high/low/open/close dataset.
081         * <p>
082         * The current implementation allows only one series in the dataset.
083         * This may be extended in a future version.
084         *
085         * @param seriesKey  the key for the series.
086         * @param date  the dates.
087         * @param high  the high values.
088         * @param low  the low values.
089         * @param open  the open values.
090         * @param close  the close values.
091         * @param volume  the volume values.
092         */
093        public DefaultHighLowDataset(Comparable seriesKey,
094                                     Date[] date,
095                                     double[] high, final double[] low,
096                                     double[] open, final double[] close,
097                                     double[] volume) {
098    
099            this.seriesKey = seriesKey;
100            this.date = date;
101            this.high = createNumberArray(high);
102            this.low = createNumberArray(low);
103            this.open = createNumberArray(open);
104            this.close = createNumberArray(close);
105            this.volume = createNumberArray(volume);
106    
107        }
108    
109        /**
110         * Returns the for the series stored in this dataset.
111         *
112         * @param i  the index of the series. Currently ignored.
113         * 
114         * @return The key for this series.
115         */
116        public Comparable getSeriesKey(int i) {
117            return this.seriesKey;
118        }
119    
120        /**
121         * Returns the x-value for one item in a series.  The value returned is a 
122         * <code>Long</code> instance generated from the underlying 
123         * <code>Date</code> object.
124         *
125         * @param series  the series (zero-based index).
126         * @param item  the item (zero-based index).
127         *
128         * @return The x-value.
129         */
130        public Number getX(int series, int item) {
131            return new Long(this.date[item].getTime());
132        }
133    
134        /**
135         * Returns the x-value for one item in a series, as a Date.
136         * <p>
137         * This method is provided for convenience only.
138         *
139         * @param series  the series (zero-based index).
140         * @param item  the item (zero-based index).
141         *
142         * @return The x-value as a Date.
143         */
144        public Date getXDate(int series, int item) {
145            return this.date[item];
146        }
147    
148        /**
149         * Returns the y-value for one item in a series.
150         * <p>
151         * This method (from the {@link XYDataset} interface) is mapped to the 
152         * {@link #getCloseValue(int, int)} method.
153         *
154         * @param series  the series (zero-based index).
155         * @param item  the item (zero-based index).
156         *
157         * @return The y-value.
158         */
159        public Number getY(int series, int item) {
160            return getClose(series, item);
161        }
162    
163        /**
164         * Returns the high-value for one item in a series.
165         *
166         * @param series  the series (zero-based index).
167         * @param item  the item (zero-based index).
168         *
169         * @return The high-value.
170         */
171        public Number getHigh(int series, int item) {
172            return this.high[item];
173        }
174    
175        /**
176         * Returns the high-value (as a double primitive) for an item within a 
177         * series.
178         * 
179         * @param series  the series (zero-based index).
180         * @param item  the item (zero-based index).
181         * 
182         * @return The high-value.
183         */
184        public double getHighValue(int series, int item) {
185            double result = Double.NaN;
186            Number high = getHigh(series, item);
187            if (high != null) {
188                result = high.doubleValue();   
189            }
190            return result;   
191        }
192    
193        /**
194         * Returns the low-value for one item in a series.
195         *
196         * @param series  the series (zero-based index).
197         * @param item  the item (zero-based index).
198         *
199         * @return The low-value.
200         */
201        public Number getLow(int series, int item) {
202            return this.low[item];
203        }
204    
205        /**
206         * Returns the low-value (as a double primitive) for an item within a 
207         * series.
208         * 
209         * @param series  the series (zero-based index).
210         * @param item  the item (zero-based index).
211         * 
212         * @return The low-value.
213         */
214        public double getLowValue(int series, int item) {
215            double result = Double.NaN;
216            Number low = getLow(series, item);
217            if (low != null) {
218                result = low.doubleValue();   
219            }
220            return result;   
221        }
222    
223        /**
224         * Returns the open-value for one item in a series.
225         *
226         * @param series  the series (zero-based index).
227         * @param item  the item (zero-based index).
228         *
229         * @return The open-value.
230         */
231        public Number getOpen(int series, int item) {
232            return this.open[item];
233        }
234    
235        /**
236         * Returns the open-value (as a double primitive) for an item within a 
237         * series.
238         * 
239         * @param series  the series (zero-based index).
240         * @param item  the item (zero-based index).
241         * 
242         * @return The open-value.
243         */
244        public double getOpenValue(int series, int item) {
245            double result = Double.NaN;
246            Number open = getOpen(series, item);
247            if (open != null) {
248                result = open.doubleValue();   
249            }
250            return result;   
251        }
252    
253        /**
254         * Returns the close-value for one item in a series.
255         *
256         * @param series  the series (zero-based index).
257         * @param item  the item (zero-based index).
258         *
259         * @return The close-value.
260         */
261        public Number getClose(int series, int item) {
262            return this.close[item];
263        }
264    
265        /**
266         * Returns the close-value (as a double primitive) for an item within a 
267         * series.
268         * 
269         * @param series  the series (zero-based index).
270         * @param item  the item (zero-based index).
271         * 
272         * @return The close-value.
273         */
274        public double getCloseValue(int series, int item) {
275            double result = Double.NaN;
276            Number close = getClose(series, item);
277            if (close != null) {
278                result = close.doubleValue();   
279            }
280            return result;   
281        }
282    
283        /**
284         * Returns the volume-value for one item in a series.
285         *
286         * @param series  the series (zero-based index).
287         * @param item  the item (zero-based index).
288         *
289         * @return The volume-value.
290         */
291        public Number getVolume(int series, int item) {
292            return this.volume[item];
293        }
294    
295        /**
296         * Returns the volume-value (as a double primitive) for an item within a 
297         * series.
298         * 
299         * @param series  the series (zero-based index).
300         * @param item  the item (zero-based index).
301         * 
302         * @return The volume-value.
303         */
304        public double getVolumeValue(int series, int item) {
305            double result = Double.NaN;
306            Number volume = getVolume(series, item);
307            if (volume != null) {
308                result = volume.doubleValue();   
309            }
310            return result;   
311        }
312    
313        /**
314         * Returns the number of series in the dataset.
315         * <p>
316         * This implementation only allows one series.
317         *
318         * @return The number of series.
319         */
320        public int getSeriesCount() {
321            return 1;
322        }
323    
324        /**
325         * Returns the number of items in the specified series.
326         *
327         * @param series  the index (zero-based) of the series.
328         *
329         * @return The number of items in the specified series.
330         */
331        public int getItemCount(int series) {
332            return this.date.length;
333        }
334    
335        /**
336         * Constructs an array of Number objects from an array of doubles.
337         *
338         * @param data  the double values to convert.
339         *
340         * @return The data as an array of Number objects.
341         */
342        public static Number[] createNumberArray(double[] data) {
343            Number[] result = new Number[data.length];
344            for (int i = 0; i < data.length; i++) {
345                result[i] = new Double(data[i]);
346            }
347            return result;
348        }
349    
350    }