001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2014, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * -----------------------
028 * DefaultOHLCDataset.java
029 * -----------------------
030 * (C) Copyright 2003-2014, 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
046package org.jfree.data.xy;
047
048import java.util.Arrays;
049import java.util.Date;
050
051import org.jfree.util.PublicCloneable;
052
053/**
054 * A simple implementation of the {@link OHLCDataset} interface.  This
055 * implementation supports only one series.
056 */
057public 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    @Override
085    public Comparable getSeriesKey(int series) {
086        return this.key;
087    }
088
089    /**
090     * Returns the x-value for a data item.
091     *
092     * @param series  the series index (ignored).
093     * @param item  the item index (zero-based).
094     *
095     * @return The x-value.
096     */
097    @Override
098    public Number getX(int series, int item) {
099        return new Long(this.data[item].getDate().getTime());
100    }
101
102    /**
103     * Returns the x-value for a data item as a date.
104     *
105     * @param series  the series index (ignored).
106     * @param item  the item index (zero-based).
107     *
108     * @return The x-value as a date.
109     */
110    public Date getXDate(int series, int item) {
111        return this.data[item].getDate();
112    }
113
114    /**
115     * Returns the y-value.
116     *
117     * @param series  the series index (ignored).
118     * @param item  the item index (zero-based).
119     *
120     * @return The y value.
121     */
122    @Override
123    public Number getY(int series, int item) {
124        return getClose(series, item);
125    }
126
127    /**
128     * Returns the high value.
129     *
130     * @param series  the series index (ignored).
131     * @param item  the item index (zero-based).
132     *
133     * @return The high value.
134     */
135    @Override
136    public Number getHigh(int series, int item) {
137        return this.data[item].getHigh();
138    }
139
140    /**
141     * Returns the high-value (as a double primitive) for an item within a
142     * series.
143     *
144     * @param series  the series (zero-based index).
145     * @param item  the item (zero-based index).
146     *
147     * @return The high-value.
148     */
149    @Override
150    public double getHighValue(int series, int item) {
151        double result = Double.NaN;
152        Number high = getHigh(series, item);
153        if (high != null) {
154            result = high.doubleValue();
155        }
156        return result;
157    }
158
159    /**
160     * Returns the low value.
161     *
162     * @param series  the series index (ignored).
163     * @param item  the item index (zero-based).
164     *
165     * @return The low value.
166     */
167    @Override
168    public Number getLow(int series, int item) {
169        return this.data[item].getLow();
170    }
171
172    /**
173     * Returns the low-value (as a double primitive) for an item within a
174     * series.
175     *
176     * @param series  the series (zero-based index).
177     * @param item  the item (zero-based index).
178     *
179     * @return The low-value.
180     */
181    @Override
182    public double getLowValue(int series, int item) {
183        double result = Double.NaN;
184        Number low = getLow(series, item);
185        if (low != null) {
186            result = low.doubleValue();
187        }
188        return result;
189    }
190
191    /**
192     * Returns the open value.
193     *
194     * @param series  the series index (ignored).
195     * @param item  the item index (zero-based).
196     *
197     * @return The open value.
198     */
199    @Override
200    public Number getOpen(int series, int item) {
201        return this.data[item].getOpen();
202    }
203
204    /**
205     * Returns the open-value (as a double primitive) for an item within a
206     * series.
207     *
208     * @param series  the series (zero-based index).
209     * @param item  the item (zero-based index).
210     *
211     * @return The open-value.
212     */
213    @Override
214    public double getOpenValue(int series, int item) {
215        double result = Double.NaN;
216        Number open = getOpen(series, item);
217        if (open != null) {
218            result = open.doubleValue();
219        }
220        return result;
221    }
222
223    /**
224     * Returns the close value.
225     *
226     * @param series  the series index (ignored).
227     * @param item  the item index (zero-based).
228     *
229     * @return The close value.
230     */
231    @Override
232    public Number getClose(int series, int item) {
233        return this.data[item].getClose();
234    }
235
236    /**
237     * Returns the close-value (as a double primitive) for an item within a
238     * series.
239     *
240     * @param series  the series (zero-based index).
241     * @param item  the item (zero-based index).
242     *
243     * @return The close-value.
244     */
245    @Override
246    public double getCloseValue(int series, int item) {
247        double result = Double.NaN;
248        Number close = getClose(series, item);
249        if (close != null) {
250            result = close.doubleValue();
251        }
252        return result;
253    }
254
255    /**
256     * Returns the trading volume.
257     *
258     * @param series  the series index (ignored).
259     * @param item  the item index (zero-based).
260     *
261     * @return The trading volume.
262     */
263    @Override
264    public Number getVolume(int series, int item) {
265        return this.data[item].getVolume();
266    }
267
268    /**
269     * Returns the volume-value (as a double primitive) for an item within a
270     * series.
271     *
272     * @param series  the series (zero-based index).
273     * @param item  the item (zero-based index).
274     *
275     * @return The volume-value.
276     */
277    @Override
278    public double getVolumeValue(int series, int item) {
279        double result = Double.NaN;
280        Number volume = getVolume(series, item);
281        if (volume != null) {
282            result = volume.doubleValue();
283        }
284        return result;
285    }
286
287    /**
288     * Returns the series count.
289     *
290     * @return 1.
291     */
292    @Override
293    public int getSeriesCount() {
294        return 1;
295    }
296
297    /**
298     * Returns the item count for the specified series.
299     *
300     * @param series  the series index (ignored).
301     *
302     * @return The item count.
303     */
304    @Override
305    public int getItemCount(int series) {
306        return this.data.length;
307    }
308
309    /**
310     * Sorts the data into ascending order by date.
311     */
312    public void sortDataByDate() {
313        Arrays.sort(this.data);
314    }
315
316    /**
317     * Tests this instance for equality with an arbitrary object.
318     *
319     * @param obj  the object (<code>null</code> permitted).
320     *
321     * @return A boolean.
322     */
323    @Override
324    public boolean equals(Object obj) {
325        if (this == obj) {
326            return true;
327        }
328        if (!(obj instanceof DefaultOHLCDataset)) {
329            return false;
330        }
331        DefaultOHLCDataset that = (DefaultOHLCDataset) obj;
332        if (!this.key.equals(that.key)) {
333            return false;
334        }
335        if (!Arrays.equals(this.data, that.data)) {
336            return false;
337        }
338        return true;
339    }
340
341    /**
342     * Returns an independent copy of this dataset.
343     *
344     * @return A clone.
345     *
346     * @throws CloneNotSupportedException if there is a cloning problem.
347     */
348    @Override
349    public Object clone() throws CloneNotSupportedException {
350        DefaultOHLCDataset clone = (DefaultOHLCDataset) super.clone();
351        clone.data = new OHLCDataItem[this.data.length];
352        System.arraycopy(this.data, 0, clone.data, 0, this.data.length);
353        return clone;
354    }
355
356}