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 * SubseriesDataset.java
029 * ---------------------
030 * (C) Copyright 2001-2007, by Bill Kelemen and Contributors.
031 *
032 * Original Author: Bill Kelemen;
033 * Contributor(s): Sylvain Vieujot;
034 * David Gilbert (for Object Refinery Limited);
035 *
036 * $Id: SubSeriesDataset.java,v 1.5.2.3 2007/02/02 15:50:44 mungady Exp $
037 *
038 * Changes
039 * -------
040 * 06-Dec-2001 : Version 1 (BK);
041 * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset
042 * interface) as requested by Sylvain Vieujot (DG);
043 * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and
044 * SignalsDataset methods (BK);
045 * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
046 * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG);
047 * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
048 * getYValue() (DG);
049 * 29-Nov-2005 : Removed SignalsDataset (DG);
050 * ------------- JFREECHART 1.0.x ---------------------------------------------
051 * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
052 *
053 */
054
055 package org.jfree.data.general;
056
057 import org.jfree.data.xy.AbstractIntervalXYDataset;
058 import org.jfree.data.xy.OHLCDataset;
059 import org.jfree.data.xy.IntervalXYDataset;
060 import org.jfree.data.xy.XYDataset;
061
062 /**
063 * This class will create a dataset with one or more series from another
064 * {@link SeriesDataset}.
065 */
066 public class SubSeriesDataset extends AbstractIntervalXYDataset
067 implements OHLCDataset,
068 IntervalXYDataset,
069 CombinationDataset {
070
071 /** The parent dataset. */
072 private SeriesDataset parent = null;
073
074 /** Storage for map. */
075 private int[] map; // maps our series into our parent's
076
077 /**
078 * Creates a SubSeriesDataset using one or more series from
079 * <code>parent</code>. The series to use are passed as an array of int.
080 *
081 * @param parent underlying dataset
082 * @param map int[] of series from parent to include in this Dataset
083 */
084 public SubSeriesDataset(SeriesDataset parent, int[] map) {
085 this.parent = parent;
086 this.map = map;
087 }
088
089 /**
090 * Creates a SubSeriesDataset using one series from <code>parent</code>.
091 * The series to is passed as an int.
092 *
093 * @param parent underlying dataset
094 * @param series series from parent to include in this Dataset
095 */
096 public SubSeriesDataset(SeriesDataset parent, int series) {
097 this(parent, new int[] {series});
098 }
099
100 ///////////////////////////////////////////////////////////////////////////
101 // From HighLowDataset
102 ///////////////////////////////////////////////////////////////////////////
103
104 /**
105 * Returns the high-value for the specified series and item.
106 * <p>
107 * Note: throws <code>ClassCastException</code> if the series if not from a
108 * {@link OHLCDataset}.
109 *
110 * @param series the index of the series of interest (zero-based).
111 * @param item the index of the item of interest (zero-based).
112 *
113 * @return The high-value for the specified series and item.
114 */
115 public Number getHigh(int series, int item) {
116 return ((OHLCDataset) this.parent).getHigh(this.map[series], item);
117 }
118
119 /**
120 * Returns the high-value (as a double primitive) for an item within a
121 * series.
122 *
123 * @param series the series (zero-based index).
124 * @param item the item (zero-based index).
125 *
126 * @return The high-value.
127 */
128 public double getHighValue(int series, int item) {
129 double result = Double.NaN;
130 Number high = getHigh(series, item);
131 if (high != null) {
132 result = high.doubleValue();
133 }
134 return result;
135 }
136
137 /**
138 * Returns the low-value for the specified series and item.
139 * <p>
140 * Note: throws <code>ClassCastException</code> if the series if not from a
141 * {@link OHLCDataset}.
142 *
143 * @param series the index of the series of interest (zero-based).
144 * @param item the index of the item of interest (zero-based).
145 *
146 * @return The low-value for the specified series and item.
147 */
148 public Number getLow(int series, int item) {
149 return ((OHLCDataset) this.parent).getLow(this.map[series], item);
150 }
151
152 /**
153 * Returns the low-value (as a double primitive) for an item within a
154 * series.
155 *
156 * @param series the series (zero-based index).
157 * @param item the item (zero-based index).
158 *
159 * @return The low-value.
160 */
161 public double getLowValue(int series, int item) {
162 double result = Double.NaN;
163 Number low = getLow(series, item);
164 if (low != null) {
165 result = low.doubleValue();
166 }
167 return result;
168 }
169
170 /**
171 * Returns the open-value for the specified series and item.
172 * <p>
173 * Note: throws <code>ClassCastException</code> if the series if not from a
174 * {@link OHLCDataset}.
175 *
176 * @param series the index of the series of interest (zero-based).
177 * @param item the index of the item of interest (zero-based).
178 *
179 * @return The open-value for the specified series and item.
180 */
181 public Number getOpen(int series, int item) {
182 return ((OHLCDataset) this.parent).getOpen(this.map[series], item);
183 }
184
185 /**
186 * Returns the open-value (as a double primitive) for an item within a
187 * series.
188 *
189 * @param series the series (zero-based index).
190 * @param item the item (zero-based index).
191 *
192 * @return The open-value.
193 */
194 public double getOpenValue(int series, int item) {
195 double result = Double.NaN;
196 Number open = getOpen(series, item);
197 if (open != null) {
198 result = open.doubleValue();
199 }
200 return result;
201 }
202
203 /**
204 * Returns the close-value for the specified series and item.
205 * <p>
206 * Note: throws <code>ClassCastException</code> if the series if not from a
207 * {@link OHLCDataset}.
208 *
209 * @param series the index of the series of interest (zero-based).
210 * @param item the index of the item of interest (zero-based).
211 *
212 * @return The close-value for the specified series and item.
213 */
214 public Number getClose(int series, int item) {
215 return ((OHLCDataset) this.parent).getClose(this.map[series], item);
216 }
217
218 /**
219 * Returns the close-value (as a double primitive) for an item within a
220 * series.
221 *
222 * @param series the series (zero-based index).
223 * @param item the item (zero-based index).
224 *
225 * @return The close-value.
226 */
227 public double getCloseValue(int series, int item) {
228 double result = Double.NaN;
229 Number close = getClose(series, item);
230 if (close != null) {
231 result = close.doubleValue();
232 }
233 return result;
234 }
235
236 /**
237 * Returns the volume.
238 * <p>
239 * Note: throws <code>ClassCastException</code> if the series if not from a
240 * {@link OHLCDataset}.
241 *
242 * @param series the series (zero based index).
243 * @param item the item (zero based index).
244 *
245 * @return The volume.
246 */
247 public Number getVolume(int series, int item) {
248 return ((OHLCDataset) this.parent).getVolume(this.map[series], item);
249 }
250
251 /**
252 * Returns the volume-value (as a double primitive) for an item within a
253 * series.
254 *
255 * @param series the series (zero-based index).
256 * @param item the item (zero-based index).
257 *
258 * @return The volume-value.
259 */
260 public double getVolumeValue(int series, int item) {
261 double result = Double.NaN;
262 Number volume = getVolume(series, item);
263 if (volume != null) {
264 result = volume.doubleValue();
265 }
266 return result;
267 }
268
269 ///////////////////////////////////////////////////////////////////////////
270 // From XYDataset
271 ///////////////////////////////////////////////////////////////////////////
272
273 /**
274 * Returns the X-value for the specified series and item.
275 * <p>
276 * Note: throws <code>ClassCastException</code> if the series if not from a
277 * {@link XYDataset}.
278 *
279 * @param series the index of the series of interest (zero-based);
280 * @param item the index of the item of interest (zero-based).
281 *
282 * @return The X-value for the specified series and item.
283 */
284 public Number getX(int series, int item) {
285 return ((XYDataset) this.parent).getX(this.map[series], item);
286 }
287
288 /**
289 * Returns the Y-value for the specified series and item.
290 * <p>
291 * Note: throws <code>ClassCastException</code> if the series if not from a
292 * {@link XYDataset}.
293 *
294 * @param series the index of the series of interest (zero-based).
295 * @param item the index of the item of interest (zero-based).
296 *
297 * @return The Y-value for the specified series and item.
298 */
299 public Number getY(int series, int item) {
300 return ((XYDataset) this.parent).getY(this.map[series], item);
301 }
302
303 /**
304 * Returns the number of items in a series.
305 * <p>
306 * Note: throws <code>ClassCastException</code> if the series if not from a
307 * {@link XYDataset}.
308 *
309 * @param series the index of the series of interest (zero-based).
310 *
311 * @return The number of items in a series.
312 */
313 public int getItemCount(int series) {
314 return ((XYDataset) this.parent).getItemCount(this.map[series]);
315 }
316
317 ///////////////////////////////////////////////////////////////////////////
318 // From SeriesDataset
319 ///////////////////////////////////////////////////////////////////////////
320
321 /**
322 * Returns the number of series in the dataset.
323 *
324 * @return The number of series in the dataset.
325 */
326 public int getSeriesCount() {
327 return this.map.length;
328 }
329
330 /**
331 * Returns the key for a series.
332 *
333 * @param series the series (zero-based index).
334 *
335 * @return The name of a series.
336 */
337 public Comparable getSeriesKey(int series) {
338 return this.parent.getSeriesKey(this.map[series]);
339 }
340
341 ///////////////////////////////////////////////////////////////////////////
342 // From IntervalXYDataset
343 ///////////////////////////////////////////////////////////////////////////
344
345 /**
346 * Returns the starting X value for the specified series and item.
347 *
348 * @param series the index of the series of interest (zero-based).
349 * @param item the index of the item of interest (zero-based).
350 *
351 * @return The starting X value for the specified series and item.
352 */
353 public Number getStartX(int series, int item) {
354 if (this.parent instanceof IntervalXYDataset) {
355 return ((IntervalXYDataset) this.parent).getStartX(
356 this.map[series], item
357 );
358 }
359 else {
360 return getX(series, item);
361 }
362 }
363
364 /**
365 * Returns the ending X value for the specified series and item.
366 *
367 * @param series the index of the series of interest (zero-based).
368 * @param item the index of the item of interest (zero-based).
369 *
370 * @return The ending X value for the specified series and item.
371 */
372 public Number getEndX(int series, int item) {
373 if (this.parent instanceof IntervalXYDataset) {
374 return ((IntervalXYDataset) this.parent).getEndX(
375 this.map[series], item
376 );
377 }
378 else {
379 return getX(series, item);
380 }
381 }
382
383 /**
384 * Returns the starting Y value for the specified series and item.
385 *
386 * @param series the index of the series of interest (zero-based).
387 * @param item the index of the item of interest (zero-based).
388 *
389 * @return The starting Y value for the specified series and item.
390 */
391 public Number getStartY(int series, int item) {
392 if (this.parent instanceof IntervalXYDataset) {
393 return ((IntervalXYDataset) this.parent).getStartY(
394 this.map[series], item
395 );
396 }
397 else {
398 return getY(series, item);
399 }
400 }
401
402 /**
403 * Returns the ending Y value for the specified series and item.
404 *
405 * @param series the index of the series of interest (zero-based).
406 * @param item the index of the item of interest (zero-based).
407 *
408 * @return The ending Y value for the specified series and item.
409 */
410 public Number getEndY(int series, int item) {
411 if (this.parent instanceof IntervalXYDataset) {
412 return ((IntervalXYDataset) this.parent).getEndY(
413 this.map[series], item
414 );
415 }
416 else {
417 return getY(series, item);
418 }
419 }
420
421 ///////////////////////////////////////////////////////////////////////////
422 // New methods from CombinationDataset
423 ///////////////////////////////////////////////////////////////////////////
424
425 /**
426 * Returns the parent Dataset of this combination.
427 *
428 * @return The parent Dataset of this combination.
429 */
430 public SeriesDataset getParent() {
431 return this.parent;
432 }
433
434 /**
435 * Returns a map or indirect indexing form our series into parent's series.
436 *
437 * @return A map or indirect indexing form our series into parent's series.
438 */
439 public int[] getMap() {
440 return (int[]) this.map.clone();
441 }
442
443 }