1. /* ===========================================================
  2. * JFreeChart : a free chart library for the Java(tm) platform
  3. * ===========================================================
  4. *
  5. * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
  6. *
  7. * Project Info: http://www.jfree.org/jfreechart/index.html
  8. *
  9. * This library is free software; you can redistribute it and/or modify it under the terms
  10. * of the GNU Lesser General Public License as published by the Free Software Foundation;
  11. * either version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  14. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. * See the GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License along with this
  18. * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. *
  21. * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  22. * in the United States and other countries.]
  23. *
  24. * ---------------------
  25. * SubseriesDataset.java
  26. * ---------------------
  27. * (C) Copyright 2001-2005, by Bill Kelemen and Contributors.
  28. *
  29. * Original Author: Bill Kelemen;
  30. * Contributor(s): Sylvain Vieujot;
  31. * David Gilbert (for Object Refinery Limited);
  32. *
  33. * $Id: SubSeriesDataset.java,v 1.3 2005/01/14 17:31:43 mungady Exp $
  34. *
  35. * Changes
  36. * -------
  37. * 06-Dec-2001 : Version 1 (BK);
  38. * 05-Feb-2002 : Added SignalsDataset (and small change to HighLowDataset interface) as requested
  39. * by Sylvain Vieujot (DG);
  40. * 28-Feb-2002 : Fixed bug: missing map[series] in IntervalXYDataset and SignalsDataset
  41. * methods (BK);
  42. * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  43. * 06-May-2004 : Now extends AbstractIntervalXYDataset (DG);
  44. * 15-Jul-2004 : Switched getX() with getXValue() and getY() with getYValue() (DG);
  45. *
  46. */
  47. package org.jfree.data.general;
  48. import org.jfree.data.xy.AbstractIntervalXYDataset;
  49. import org.jfree.data.xy.OHLCDataset;
  50. import org.jfree.data.xy.IntervalXYDataset;
  51. import org.jfree.data.xy.SignalsDataset;
  52. import org.jfree.data.xy.XYDataset;
  53. /**
  54. * This class will create a dataset with one or more series from another
  55. * {@link SeriesDataset}.
  56. *
  57. * @author Bill Kelemen (bill@kelemen-usa.com)
  58. */
  59. public class SubSeriesDataset extends AbstractIntervalXYDataset
  60. implements OHLCDataset, SignalsDataset, IntervalXYDataset,
  61. CombinationDataset {
  62. /** The parent dataset. */
  63. private SeriesDataset parent = null;
  64. /** Storage for map. */
  65. private int[] map; // maps our series into our parent's
  66. /**
  67. * Creates a SubSeriesDataset using one or more series from <code>parent</code>.
  68. * The series to use are passed as an array of int.
  69. *
  70. * @param parent underlying dataset
  71. * @param map int[] of series from parent to include in this Dataset
  72. */
  73. public SubSeriesDataset(SeriesDataset parent, int[] map) {
  74. this.parent = parent;
  75. this.map = map;
  76. }
  77. /**
  78. * Creates a SubSeriesDataset using one series from <code>parent</code>.
  79. * The series to is passed as an int.
  80. *
  81. * @param parent underlying dataset
  82. * @param series series from parent to include in this Dataset
  83. */
  84. public SubSeriesDataset(SeriesDataset parent, int series) {
  85. this(parent, new int[] {series});
  86. }
  87. ///////////////////////////////////////////////////////////////////////////
  88. // From HighLowDataset
  89. ///////////////////////////////////////////////////////////////////////////
  90. /**
  91. * Returns the high-value for the specified series and item.
  92. * <p>
  93. * Note: throws <code>ClassCastException</code> if the series if not from a
  94. * {@link OHLCDataset}.
  95. *
  96. * @param series the index of the series of interest (zero-based).
  97. * @param item the index of the item of interest (zero-based).
  98. *
  99. * @return the high-value for the specified series and item.
  100. */
  101. public Number getHigh(int series, int item) {
  102. return ((OHLCDataset) this.parent).getHigh(this.map[series], item);
  103. }
  104. /**
  105. * Returns the high-value (as a double primitive) for an item within a series.
  106. *
  107. * @param series the series (zero-based index).
  108. * @param item the item (zero-based index).
  109. *
  110. * @return The high-value.
  111. */
  112. public double getHighValue(int series, int item) {
  113. double result = Double.NaN;
  114. Number high = getHigh(series, item);
  115. if (high != null) {
  116. result = high.doubleValue();
  117. }
  118. return result;
  119. }
  120. /**
  121. * Returns the low-value for the specified series and item.
  122. * <p>
  123. * Note: throws <code>ClassCastException</code> if the series if not from a
  124. * {@link OHLCDataset}.
  125. *
  126. * @param series the index of the series of interest (zero-based).
  127. * @param item the index of the item of interest (zero-based).
  128. *
  129. * @return the low-value for the specified series and item.
  130. */
  131. public Number getLow(int series, int item) {
  132. return ((OHLCDataset) this.parent).getLow(this.map[series], item);
  133. }
  134. /**
  135. * Returns the low-value (as a double primitive) for an item within a series.
  136. *
  137. * @param series the series (zero-based index).
  138. * @param item the item (zero-based index).
  139. *
  140. * @return The low-value.
  141. */
  142. public double getLowValue(int series, int item) {
  143. double result = Double.NaN;
  144. Number low = getLow(series, item);
  145. if (low != null) {
  146. result = low.doubleValue();
  147. }
  148. return result;
  149. }
  150. /**
  151. * Returns the open-value for the specified series and item.
  152. * <p>
  153. * Note: throws <code>ClassCastException</code> if the series if not from a
  154. * {@link OHLCDataset}.
  155. *
  156. * @param series the index of the series of interest (zero-based).
  157. * @param item the index of the item of interest (zero-based).
  158. *
  159. * @return the open-value for the specified series and item.
  160. */
  161. public Number getOpen(int series, int item) {
  162. return ((OHLCDataset) this.parent).getOpen(this.map[series], item);
  163. }
  164. /**
  165. * Returns the open-value (as a double primitive) for an item within a series.
  166. *
  167. * @param series the series (zero-based index).
  168. * @param item the item (zero-based index).
  169. *
  170. * @return The open-value.
  171. */
  172. public double getOpenValue(int series, int item) {
  173. double result = Double.NaN;
  174. Number open = getOpen(series, item);
  175. if (open != null) {
  176. result = open.doubleValue();
  177. }
  178. return result;
  179. }
  180. /**
  181. * Returns the close-value for the specified series and item.
  182. * <p>
  183. * Note: throws <code>ClassCastException</code> if the series if not from a
  184. * {@link OHLCDataset}.
  185. *
  186. * @param series the index of the series of interest (zero-based).
  187. * @param item the index of the item of interest (zero-based).
  188. *
  189. * @return the close-value for the specified series and item.
  190. */
  191. public Number getClose(int series, int item) {
  192. return ((OHLCDataset) this.parent).getClose(this.map[series], item);
  193. }
  194. /**
  195. * Returns the close-value (as a double primitive) for an item within a series.
  196. *
  197. * @param series the series (zero-based index).
  198. * @param item the item (zero-based index).
  199. *
  200. * @return The close-value.
  201. */
  202. public double getCloseValue(int series, int item) {
  203. double result = Double.NaN;
  204. Number close = getClose(series, item);
  205. if (close != null) {
  206. result = close.doubleValue();
  207. }
  208. return result;
  209. }
  210. /**
  211. * Returns the volume.
  212. * <p>
  213. * Note: throws <code>ClassCastException</code> if the series if not from a
  214. * {@link OHLCDataset}.
  215. *
  216. * @param series the series (zero based index).
  217. * @param item the item (zero based index).
  218. *
  219. * @return the volume.
  220. */
  221. public Number getVolume(int series, int item) {
  222. return ((OHLCDataset) this.parent).getVolume(this.map[series], item);
  223. }
  224. /**
  225. * Returns the volume-value (as a double primitive) for an item within a series.
  226. *
  227. * @param series the series (zero-based index).
  228. * @param item the item (zero-based index).
  229. *
  230. * @return The volume-value.
  231. */
  232. public double getVolumeValue(int series, int item) {
  233. double result = Double.NaN;
  234. Number volume = getVolume(series, item);
  235. if (volume != null) {
  236. result = volume.doubleValue();
  237. }
  238. return result;
  239. }
  240. ///////////////////////////////////////////////////////////////////////////
  241. // From XYDataset
  242. ///////////////////////////////////////////////////////////////////////////
  243. /**
  244. * Returns the X-value for the specified series and item.
  245. * <p>
  246. * Note: throws <code>ClassCastException</code> if the series if not from a
  247. * {@link XYDataset}.
  248. *
  249. * @param series the index of the series of interest (zero-based);
  250. * @param item the index of the item of interest (zero-based).
  251. *
  252. * @return the X-value for the specified series and item.
  253. */
  254. public Number getX(int series, int item) {
  255. return ((XYDataset) this.parent).getX(this.map[series], item);
  256. }
  257. /**
  258. * Returns the Y-value for the specified series and item.
  259. * <p>
  260. * Note: throws <code>ClassCastException</code> if the series if not from a
  261. * {@link XYDataset}.
  262. *
  263. * @param series the index of the series of interest (zero-based).
  264. * @param item the index of the item of interest (zero-based).
  265. *
  266. * @return the Y-value for the specified series and item.
  267. */
  268. public Number getY(int series, int item) {
  269. return ((XYDataset) this.parent).getY(this.map[series], item);
  270. }
  271. /**
  272. * Returns the number of items in a series.
  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. *
  279. * @return the number of items in a series.
  280. */
  281. public int getItemCount(int series) {
  282. return ((XYDataset) this.parent).getItemCount(this.map[series]);
  283. }
  284. ///////////////////////////////////////////////////////////////////////////
  285. // From SeriesDataset
  286. ///////////////////////////////////////////////////////////////////////////
  287. /**
  288. * Returns the number of series in the dataset.
  289. *
  290. * @return The number of series in the dataset.
  291. */
  292. public int getSeriesCount() {
  293. return this.map.length;
  294. }
  295. /**
  296. * Returns the name of a series.
  297. *
  298. * @param series the series (zero-based index).
  299. *
  300. * @return The name of a series.
  301. */
  302. public String getSeriesName(int series) {
  303. return this.parent.getSeriesName(this.map[series]);
  304. }
  305. ///////////////////////////////////////////////////////////////////////////
  306. // From IntervalXYDataset
  307. ///////////////////////////////////////////////////////////////////////////
  308. /**
  309. * Returns the starting X value for the specified series and item.
  310. *
  311. * @param series the index of the series of interest (zero-based).
  312. * @param item the index of the item of interest (zero-based).
  313. *
  314. * @return The starting X value for the specified series and item.
  315. */
  316. public Number getStartX(int series, int item) {
  317. if (this.parent instanceof IntervalXYDataset) {
  318. return ((IntervalXYDataset) this.parent).getStartX(this.map[series], item);
  319. }
  320. else {
  321. return getX(series, item);
  322. }
  323. }
  324. /**
  325. * Returns the ending X value for the specified series and item.
  326. *
  327. * @param series the index of the series of interest (zero-based).
  328. * @param item the index of the item of interest (zero-based).
  329. *
  330. * @return the ending X value for the specified series and item.
  331. */
  332. public Number getEndX(int series, int item) {
  333. if (this.parent instanceof IntervalXYDataset) {
  334. return ((IntervalXYDataset) this.parent).getEndX(this.map[series], item);
  335. }
  336. else {
  337. return getX(series, item);
  338. }
  339. }
  340. /**
  341. * Returns the starting Y value for the specified series and item.
  342. *
  343. * @param series the index of the series of interest (zero-based).
  344. * @param item the index of the item of interest (zero-based).
  345. *
  346. * @return The starting Y value for the specified series and item.
  347. */
  348. public Number getStartY(int series, int item) {
  349. if (this.parent instanceof IntervalXYDataset) {
  350. return ((IntervalXYDataset) this.parent).getStartY(this.map[series], item);
  351. }
  352. else {
  353. return getY(series, item);
  354. }
  355. }
  356. /**
  357. * Returns the ending Y value for the specified series and item.
  358. *
  359. * @param series the index of the series of interest (zero-based).
  360. * @param item the index of the item of interest (zero-based).
  361. *
  362. * @return The ending Y value for the specified series and item.
  363. */
  364. public Number getEndY(int series, int item) {
  365. if (this.parent instanceof IntervalXYDataset) {
  366. return ((IntervalXYDataset) this.parent).getEndY(this.map[series], item);
  367. }
  368. else {
  369. return getY(series, item);
  370. }
  371. }
  372. ///////////////////////////////////////////////////////////////////////////
  373. // From SignalsDataset
  374. ///////////////////////////////////////////////////////////////////////////
  375. /**
  376. * Returns the type.
  377. *
  378. * @param series the series (zero based index).
  379. * @param item the item (zero based index).
  380. *
  381. * @return the type.
  382. */
  383. public int getType(int series, int item) {
  384. if (this.parent instanceof SignalsDataset) {
  385. return ((SignalsDataset) this.parent).getType(this.map[series], item);
  386. }
  387. else {
  388. return getY(series, item).intValue();
  389. }
  390. }
  391. /**
  392. * Returns the level.
  393. *
  394. * @param series the series (zero based index).
  395. * @param item the item (zero based index).
  396. *
  397. * @return The level.
  398. */
  399. public double getLevel(int series, int item) {
  400. if (this.parent instanceof SignalsDataset) {
  401. return ((SignalsDataset) this.parent).getLevel(this.map[series], item);
  402. }
  403. else {
  404. return getYValue(series, item);
  405. }
  406. }
  407. ///////////////////////////////////////////////////////////////////////////
  408. // New methods from CombinationDataset
  409. ///////////////////////////////////////////////////////////////////////////
  410. /**
  411. * Returns the parent Dataset of this combination.
  412. *
  413. * @return The parent Dataset of this combination.
  414. */
  415. public SeriesDataset getParent() {
  416. return this.parent;
  417. }
  418. /**
  419. * Returns a map or indirect indexing form our series into parent's series.
  420. *
  421. * @return A map or indirect indexing form our series into parent's series.
  422. */
  423. public int[] getMap() {
  424. return (int[]) this.map.clone();
  425. }
  426. }