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