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