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
  10. * under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2.1 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  17. * License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this library; if not, write to the Free Software Foundation,
  21. * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  22. *
  23. * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  24. * in the United States and other countries.]
  25. *
  26. * ---------------------------
  27. * CategoryTableXYDataset.java
  28. * ---------------------------
  29. * (C) Copyright 2004, 2005, by Andreas Schroeder and Contributors.
  30. *
  31. * Original Author: Andreas Schroeder;
  32. * Contributor(s): David Gilbert (for Object Refinery Limited);
  33. *
  34. * $Id: CategoryTableXYDataset.java,v 1.6 2005/02/22 08:26:14 mungady Exp $
  35. *
  36. * Changes
  37. * -------
  38. * 31-Mar-2004 : Version 1 (AS);
  39. * 05-May-2004 : Now extends AbstractIntervalXYDataset (DG);
  40. * 15-Jul-2004 : Switched interval access method names (DG);
  41. * 18-Aug-2004 : Moved from org.jfree.data --> org.jfree.data.xy (DG);
  42. * 17-Nov-2004 : Updates required by changes to DomainInfo interface (DG);
  43. * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG);
  44. *
  45. */
  46. package org.jfree.data.xy;
  47. import org.jfree.data.DefaultKeyedValues2D;
  48. import org.jfree.data.DomainInfo;
  49. import org.jfree.data.Range;
  50. import org.jfree.data.general.DatasetChangeEvent;
  51. /**
  52. * An implementation variant of the {@link TableXYDataset} where every series
  53. * shares the same x-values (required for generating stacked area charts).
  54. * This implementation uses a {@link DefaultKeyedValues2D} Object as backend
  55. * implementation and is hence more "category oriented" than the {@link
  56. * DefaultTableXYDataset} implementation.
  57. * <p>
  58. * This implementation provides no means to remove data items yet.
  59. * This is due to the lack of such facility in the DefaultKeyedValues2D class.
  60. * <p>
  61. * This class also implements the {@link IntervalXYDataset} interface, but this
  62. * implementation is provisional.
  63. *
  64. * @author Andreas Schroeder
  65. */
  66. public class CategoryTableXYDataset extends AbstractIntervalXYDataset
  67. implements TableXYDataset,
  68. IntervalXYDataset,
  69. DomainInfo {
  70. /**
  71. * The backing data structure.
  72. */
  73. private DefaultKeyedValues2D values;
  74. /** A delegate for controlling the interval width. */
  75. private IntervalXYDelegate intervalDelegate;
  76. /**
  77. * Creates a new empty CategoryTableXYDataset.
  78. */
  79. public CategoryTableXYDataset() {
  80. this.values = new DefaultKeyedValues2D(true);
  81. this.intervalDelegate = new IntervalXYDelegate(this);
  82. }
  83. /**
  84. * Adds a data item to this dataset and sends a {@link DatasetChangeEvent}
  85. * to all registered listeners.
  86. *
  87. * @param x the x value.
  88. * @param y the y value.
  89. * @param seriesName the name of the series to add the data item.
  90. */
  91. public void add(double x, double y, String seriesName) {
  92. add(new Double(x), new Double(y), seriesName, true);
  93. }
  94. /**
  95. * Adds a data item to this dataset and, if requested, sends a
  96. * {@link DatasetChangeEvent} to all registered listeners.
  97. *
  98. * @param x the x value.
  99. * @param y the y value.
  100. * @param seriesName the name of the series to add the data item.
  101. * @param notify notify listeners?
  102. */
  103. public void add(Number x, Number y, String seriesName, boolean notify) {
  104. this.values.addValue(y, (Comparable) x, seriesName);
  105. int series = this.values.getColumnIndex(seriesName);
  106. int item = this.values.getRowIndex((Comparable) x);
  107. this.intervalDelegate.itemAdded(series, item);
  108. if (notify) {
  109. fireDatasetChanged();
  110. }
  111. }
  112. /**
  113. * Removes a value from the dataset.
  114. *
  115. * @param x the x-value.
  116. * @param seriesName the series name.
  117. */
  118. public void remove(double x, String seriesName) {
  119. remove(new Double(x), seriesName, true);
  120. }
  121. /**
  122. * Removes an item from the dataset.
  123. *
  124. * @param x the x-value.
  125. * @param seriesName the series name.
  126. * @param notify notify listeners?
  127. */
  128. public void remove(Number x, String seriesName, boolean notify) {
  129. this.values.removeValue((Comparable) x, seriesName);
  130. this.intervalDelegate.itemRemoved(x.doubleValue());
  131. if (notify) {
  132. fireDatasetChanged();
  133. }
  134. }
  135. /**
  136. * Returns the number of series in the collection.
  137. *
  138. * @return The series count.
  139. */
  140. public int getSeriesCount() {
  141. return this.values.getColumnCount();
  142. }
  143. /**
  144. * Returns the name of a series.
  145. *
  146. * @param series the series index (zero-based).
  147. *
  148. * @return The name of a series.
  149. */
  150. public String getSeriesName(int series) {
  151. return this.values.getColumnKey(series).toString();
  152. }
  153. /**
  154. * Returns the number of x values in the dataset.
  155. *
  156. * @return The item count.
  157. */
  158. public int getItemCount() {
  159. return this.values.getRowCount();
  160. }
  161. /**
  162. * Returns the number of items in the specified series.
  163. * Returns the same as {@link CategoryTableXYDataset#getItemCount()}.
  164. *
  165. * @param series the series index (zero-based).
  166. *
  167. * @return The item count.
  168. */
  169. public int getItemCount(int series) {
  170. return getItemCount(); // all series have the same number of items in
  171. // this dataset
  172. }
  173. /**
  174. * Returns the x-value for the specified series and item.
  175. *
  176. * @param series the series index (zero-based).
  177. * @param item the item index (zero-based).
  178. *
  179. * @return The value.
  180. */
  181. public Number getX(int series, int item) {
  182. return (Number) this.values.getRowKey(item);
  183. }
  184. /**
  185. * Returns the starting X value for the specified series and item.
  186. *
  187. * @param series the series index (zero-based).
  188. * @param item the item index (zero-based).
  189. *
  190. * @return The starting X value.
  191. */
  192. public Number getStartX(int series, int item) {
  193. return this.intervalDelegate.getStartX(series, item);
  194. }
  195. /**
  196. * Returns the ending X value for the specified series and item.
  197. *
  198. * @param series the series index (zero-based).
  199. * @param item the item index (zero-based).
  200. *
  201. * @return The ending X value.
  202. */
  203. public Number getEndX(int series, int item) {
  204. return this.intervalDelegate.getEndX(series, item);
  205. }
  206. /**
  207. * Returns the y-value for the specified series and item.
  208. *
  209. * @param series the series index (zero-based).
  210. * @param item the item index (zero-based).
  211. *
  212. * @return The y value (possibly <code>null</code>).
  213. */
  214. public Number getY(int series, int item) {
  215. return this.values.getValue(item, series);
  216. }
  217. /**
  218. * Returns the starting Y value for the specified series and item.
  219. *
  220. * @param series the series index (zero-based).
  221. * @param item the item index (zero-based).
  222. *
  223. * @return The starting Y value.
  224. */
  225. public Number getStartY(int series, int item) {
  226. return getY(series, item);
  227. }
  228. /**
  229. * Returns the ending Y value for the specified series and item.
  230. *
  231. * @param series the series index (zero-based).
  232. * @param item the item index (zero-based).
  233. *
  234. * @return The ending Y value.
  235. */
  236. public Number getEndY(int series, int item) {
  237. return getY(series, item);
  238. }
  239. /**
  240. * Returns the minimum x-value in the dataset.
  241. *
  242. * @param includeInterval a flag that determines whether or not the
  243. * x-interval is taken into account.
  244. *
  245. * @return The minimum value.
  246. */
  247. public double getDomainLowerBound(boolean includeInterval) {
  248. return this.intervalDelegate.getDomainLowerBound(includeInterval);
  249. }
  250. /**
  251. * Returns the maximum x-value in the dataset.
  252. *
  253. * @param includeInterval a flag that determines whether or not the
  254. * x-interval is taken into account.
  255. *
  256. * @return The maximum value.
  257. */
  258. public double getDomainUpperBound(boolean includeInterval) {
  259. return this.intervalDelegate.getDomainUpperBound(includeInterval);
  260. }
  261. /**
  262. * Returns the range of the values in this dataset's domain.
  263. *
  264. * @param includeInterval a flag that determines whether or not the
  265. * x-interval is taken into account.
  266. *
  267. * @return The range.
  268. */
  269. public Range getDomainBounds(boolean includeInterval) {
  270. return this.intervalDelegate.getDomainBounds(includeInterval);
  271. }
  272. /**
  273. * Returns the interval position factor.
  274. *
  275. * @return The interval position factor.
  276. */
  277. public double getIntervalPositionFactor() {
  278. return this.intervalDelegate.getIntervalPositionFactor();
  279. }
  280. /**
  281. * Sets the interval position factor. Must be between 0.0 and 1.0 inclusive.
  282. * If the factor is 0.5, the gap is in the middle of the x values. If it
  283. * is lesser than 0.5, the gap is farther to the left and if greater than
  284. * 0.5 it gets farther to the right.
  285. *
  286. * @param d the new interval position factor.
  287. */
  288. public void setIntervalPositionFactor(double d) {
  289. this.intervalDelegate.setIntervalPositionFactor(d);
  290. fireDatasetChanged();
  291. }
  292. /**
  293. * Returns the full interval width.
  294. *
  295. * @return The interval width to use.
  296. */
  297. public double getIntervalWidth() {
  298. return this.intervalDelegate.getIntervalWidth();
  299. }
  300. /**
  301. * Sets the interval width manually.
  302. *
  303. * @param d the new interval width.
  304. */
  305. public void setIntervalWidth(double d) {
  306. this.intervalDelegate.setIntervalWidth(d);
  307. fireDatasetChanged();
  308. }
  309. /**
  310. * Returns whether the interval width is automatically calculated or not.
  311. *
  312. * @return whether the width is automatically calculated or not.
  313. */
  314. public boolean isAutoWidth() {
  315. return this.intervalDelegate.isAutoWidth();
  316. }
  317. /**
  318. * Sets the flag that indicates whether the interval width is automatically
  319. * calculated or not.
  320. *
  321. * @param b the flag.
  322. */
  323. public void setAutoWidth(boolean b) {
  324. this.intervalDelegate.setAutoWidth(b);
  325. fireDatasetChanged();
  326. }
  327. }