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. * DefaultWindDataset.java
  26. * -----------------------
  27. * (C) Copyright 2001-2005, by Achilleus Mantzios and Contributors.
  28. *
  29. * Original Author: Achilleus Mantzios;
  30. * Contributor(s): David Gilbert (for Object Refinery Limited);
  31. *
  32. * $Id: DefaultWindDataset.java,v 1.2 2005/01/11 17:35:03 mungady Exp $
  33. *
  34. * Changes
  35. * -------
  36. * 06-Feb-2002 : Version 1, based on code contributed by Achilleus Mantzios (DG);
  37. * 05-May-2004 : Now extends AbstractXYDataset (DG);
  38. * 15-Jul-2004 : Switched getX() with getXValue() and getY() with getYValue() (DG);
  39. *
  40. */
  41. package org.jfree.data.xy;
  42. import java.util.Arrays;
  43. import java.util.Collections;
  44. import java.util.Date;
  45. import java.util.List;
  46. /**
  47. * A default implementation of the {@link WindDataset} interface.
  48. *
  49. * @author Achilleus Mantzios
  50. */
  51. public class DefaultWindDataset extends AbstractXYDataset implements WindDataset {
  52. /** The names of the series. */
  53. private List seriesNames;
  54. /** Storage for the series data. */
  55. private List allSeriesData;
  56. /**
  57. * Constructs a new, empty, dataset.
  58. */
  59. public DefaultWindDataset() {
  60. this.seriesNames = new java.util.ArrayList();
  61. this.allSeriesData = new java.util.ArrayList();
  62. }
  63. /**
  64. * Constructs a dataset based on the specified data.
  65. *
  66. * @param data the data.
  67. */
  68. public DefaultWindDataset(Object[][][] data) {
  69. this(seriesNameListFromDataArray(data), data);
  70. }
  71. /**
  72. * Constructs a dataset based on the specified data.
  73. *
  74. * @param seriesNames the names of the series.
  75. * @param data the wind data.
  76. */
  77. public DefaultWindDataset(String[] seriesNames, Object[][][] data) {
  78. this(Arrays.asList(seriesNames), data);
  79. }
  80. /**
  81. * Constructs a dataset based on the specified data.
  82. *
  83. * @param seriesNames the names of the series.
  84. * @param data the wind dataset.
  85. */
  86. public DefaultWindDataset(List seriesNames, Object[][][] data) {
  87. this.seriesNames = seriesNames;
  88. int seriesCount = data.length;
  89. this.allSeriesData = new java.util.ArrayList(seriesCount);
  90. for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) {
  91. List oneSeriesData = new java.util.ArrayList();
  92. int maxItemCount = data[seriesIndex].length;
  93. for (int itemIndex = 0; itemIndex < maxItemCount; itemIndex++) {
  94. Object xObject = data[seriesIndex][itemIndex][0];
  95. if (xObject != null) {
  96. Number xNumber;
  97. if (xObject instanceof Number) {
  98. xNumber = (Number) xObject;
  99. }
  100. else {
  101. if (xObject instanceof Date) {
  102. Date xDate = (Date) xObject;
  103. xNumber = new Long(xDate.getTime());
  104. }
  105. else {
  106. xNumber = new Integer(0);
  107. }
  108. }
  109. Number windDir = (Number) data[seriesIndex][itemIndex][1];
  110. Number windForce = (Number) data[seriesIndex][itemIndex][2];
  111. oneSeriesData.add(new WindDataItem(xNumber, windDir, windForce));
  112. }
  113. }
  114. Collections.sort(oneSeriesData);
  115. this.allSeriesData.add(seriesIndex, oneSeriesData);
  116. }
  117. }
  118. /**
  119. * Returns the number of series in the dataset.
  120. *
  121. * @return The series count.
  122. */
  123. public int getSeriesCount() {
  124. return this.allSeriesData.size();
  125. }
  126. /**
  127. * Returns the number of items in a series.
  128. *
  129. * @param series the series (zero-based index).
  130. *
  131. * @return The item count.
  132. */
  133. public int getItemCount(int series) {
  134. List oneSeriesData = (List) this.allSeriesData.get(series);
  135. return oneSeriesData.size();
  136. }
  137. /**
  138. * Returns the name of a series.
  139. *
  140. * @param series the series (zero-based index).
  141. *
  142. * @return The series name.
  143. */
  144. public String getSeriesName(int series) {
  145. return this.seriesNames.get(series).toString();
  146. }
  147. /**
  148. * Returns the x-value for one item within a series. This should represent
  149. * a point in time, encoded as milliseconds in the same way as
  150. * java.util.Date.
  151. *
  152. * @param series the series (zero-based index).
  153. * @param item the item (zero-based index).
  154. *
  155. * @return The x-value for the item within the series.
  156. */
  157. public Number getX(int series, int item) {
  158. List oneSeriesData = (List) this.allSeriesData.get(series);
  159. WindDataItem windItem = (WindDataItem) oneSeriesData.get(item);
  160. return windItem.getX();
  161. }
  162. /**
  163. * Returns the y-value for one item within a series. This maps to the
  164. * {@link #getWindForce(int, int)} method and is implemented because
  165. * <code>WindDataset</code> is an extension of {@link XYDataset}.
  166. *
  167. * @param series the series (zero-based index).
  168. * @param item the item (zero-based index).
  169. *
  170. * @return The y-value for the item within the series.
  171. */
  172. public Number getY(int series, int item) {
  173. return getWindForce(series, item);
  174. }
  175. /**
  176. * Returns the wind direction for one item within a series. This is a
  177. * number between 0 and 12, like the numbers on a clock face.
  178. *
  179. * @param series the series (zero-based index).
  180. * @param item the item (zero-based index).
  181. *
  182. * @return The wind direction for the item within the series.
  183. */
  184. public Number getWindDirection(int series, int item) {
  185. List oneSeriesData = (List) this.allSeriesData.get(series);
  186. WindDataItem windItem = (WindDataItem) oneSeriesData.get(item);
  187. return windItem.getWindDirection();
  188. }
  189. /**
  190. * Returns the wind force for one item within a series. This is a number
  191. * between 0 and 12, as defined by the Beaufort scale.
  192. *
  193. * @param series the series (zero-based index).
  194. * @param item the item (zero-based index).
  195. *
  196. * @return The wind force for the item within the series.
  197. */
  198. public Number getWindForce(int series, int item) {
  199. List oneSeriesData = (List) this.allSeriesData.get(series);
  200. WindDataItem windItem = (WindDataItem) oneSeriesData.get(item);
  201. return windItem.getWindForce();
  202. }
  203. /**
  204. * Utility method for automatically generating series names.
  205. * @param data the wind dataset.
  206. *
  207. * @return An array of <i>Series N</i> with N = { 1 .. data.length }.
  208. */
  209. public static List seriesNameListFromDataArray(Object[][] data) {
  210. int seriesCount = data.length;
  211. List seriesNameList = new java.util.ArrayList(seriesCount);
  212. for (int i = 0; i < seriesCount; i++) {
  213. seriesNameList.add("Series " + (i + 1));
  214. }
  215. return seriesNameList;
  216. }
  217. }
  218. /**
  219. * A wind data item.
  220. *
  221. * @author Achilleus Mantzios
  222. */
  223. class WindDataItem implements Comparable {
  224. /** The x-value. */
  225. private Number x;
  226. /** The wind direction. */
  227. private Number windDir;
  228. /** The wind force. */
  229. private Number windForce;
  230. /**
  231. * Creates a new wind data item.
  232. *
  233. * @param x the x-value.
  234. * @param windDir the direction.
  235. * @param windForce the force.
  236. */
  237. public WindDataItem(Number x, Number windDir, Number windForce) {
  238. this.x = x;
  239. this.windDir = windDir;
  240. this.windForce = windForce;
  241. }
  242. /**
  243. * Returns the x-value.
  244. *
  245. * @return The x-value.
  246. */
  247. public Number getX() {
  248. return this.x;
  249. }
  250. /**
  251. * Returns the wind direction.
  252. *
  253. * @return The wind direction.
  254. */
  255. public Number getWindDirection() {
  256. return this.windDir;
  257. }
  258. /**
  259. * Returns the wind force.
  260. *
  261. * @return The wind force.
  262. */
  263. public Number getWindForce() {
  264. return this.windForce;
  265. }
  266. /**
  267. * Compares this item to another object.
  268. *
  269. * @param object the other object.
  270. *
  271. * @return An int that indicates the relative comparison.
  272. */
  273. public int compareTo(Object object) {
  274. if (object instanceof WindDataItem) {
  275. WindDataItem item = (WindDataItem) object;
  276. if (this.x.doubleValue() > item.x.doubleValue()) {
  277. return 1;
  278. }
  279. else if (this.x.equals(item.x)) {
  280. return 0;
  281. }
  282. else {
  283. return -1;
  284. }
  285. }
  286. else {
  287. throw new ClassCastException("WindDataItem.compareTo(error)");
  288. }
  289. }
  290. }