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. * DefaultBoxAndWhiskerCategoryDataset.java
  28. * ----------------------------------------
  29. * (C) Copyright 2003-2005, by David Browning and Contributors.
  30. *
  31. * Original Author: David Browning (for Australian Institute of Marine
  32. * Science);
  33. * Contributor(s): David Gilbert (for Object Refinery Limited);
  34. *
  35. * $Id: DefaultBoxAndWhiskerCategoryDataset.java,v 1.8 2005/03/09 11:44:59 mungady Exp $
  36. *
  37. * Changes
  38. * -------
  39. * 05-Aug-2003 : Version 1, contributed by David Browning (DG);
  40. * 27-Aug-2003 : Moved from org.jfree.data --> org.jfree.data.statistics (DG);
  41. * 12-Nov-2003 : Changed 'data' from private to protected and added a new 'add'
  42. * method as proposed by Tim Bardzil. Also removed old code (DG);
  43. * 01-Mar-2004 : Added equals() method (DG);
  44. * 18-Nov-2004 : Updates for changes in RangeInfo interface (DG);
  45. * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0
  46. * release (DG);
  47. *
  48. */
  49. package org.jfree.data.statistics;
  50. import java.util.List;
  51. import org.jfree.data.KeyedObjects2D;
  52. import org.jfree.data.Range;
  53. import org.jfree.data.RangeInfo;
  54. import org.jfree.data.general.AbstractDataset;
  55. import org.jfree.util.ObjectUtilities;
  56. /**
  57. * A convenience class that provides a default implementation of the
  58. * {@link BoxAndWhiskerCategoryDataset} interface.
  59. *
  60. * @author David Browning (for Australian Institute of Marine Science)
  61. */
  62. public class DefaultBoxAndWhiskerCategoryDataset extends AbstractDataset
  63. implements BoxAndWhiskerCategoryDataset, RangeInfo {
  64. /** Storage for the data. */
  65. protected KeyedObjects2D data;
  66. /** The minimum range value. */
  67. private Number minimumRangeValue;
  68. /** The maximum range value. */
  69. private Number maximumRangeValue;
  70. /** The range of values. */
  71. private Range rangeBounds;
  72. /**
  73. * Creates a new dataset.
  74. */
  75. public DefaultBoxAndWhiskerCategoryDataset() {
  76. this.data = new KeyedObjects2D();
  77. this.minimumRangeValue = null;
  78. this.maximumRangeValue = null;
  79. this.rangeBounds = new Range(0.0, 0.0);
  80. }
  81. /**
  82. * Adds a list of values relating to one box-and-whisker entity to the
  83. * table. The various median values are calculated.
  84. *
  85. * @param list a collection of values from which the various medians will
  86. * be calculated.
  87. * @param rowKey the row key.
  88. * @param columnKey the column key.
  89. */
  90. public void add(List list, Comparable rowKey, Comparable columnKey) {
  91. BoxAndWhiskerItem item
  92. = BoxAndWhiskerCalculator.calculateBoxAndWhiskerStatistics(list);
  93. add(item, rowKey, columnKey);
  94. }
  95. /**
  96. * Adds a list of values relating to one Box and Whisker entity to the
  97. * table. The various median values are calculated.
  98. *
  99. * @param item a box and whisker item.
  100. * @param rowKey the row key.
  101. * @param columnKey the column key.
  102. */
  103. public void add(BoxAndWhiskerItem item,
  104. Comparable rowKey,
  105. Comparable columnKey) {
  106. this.data.addObject(item, rowKey, columnKey);
  107. double minval = item.getMinOutlier().doubleValue();
  108. double maxval = item.getMaxOutlier().doubleValue();
  109. if (this.maximumRangeValue == null) {
  110. this.maximumRangeValue = new Double(maxval);
  111. }
  112. else if (maxval > this.maximumRangeValue.doubleValue()) {
  113. this.maximumRangeValue = new Double(maxval);
  114. }
  115. if (this.minimumRangeValue == null) {
  116. this.minimumRangeValue = new Double(minval);
  117. }
  118. else if (minval < this.minimumRangeValue.doubleValue()) {
  119. this.minimumRangeValue = new Double(minval);
  120. }
  121. this.rangeBounds = new Range(
  122. this.minimumRangeValue.doubleValue(),
  123. this.maximumRangeValue.doubleValue()
  124. );
  125. fireDatasetChanged();
  126. }
  127. /**
  128. * Returns the value for an item.
  129. *
  130. * @param row the row index.
  131. * @param column the column index.
  132. *
  133. * @return The value.
  134. */
  135. public Number getValue(int row, int column) {
  136. return getMedianValue(row, column);
  137. }
  138. /**
  139. * Returns the value for an item.
  140. *
  141. * @param rowKey the row key.
  142. * @param columnKey the columnKey.
  143. *
  144. * @return The value.
  145. */
  146. public Number getValue(Comparable rowKey, Comparable columnKey) {
  147. return getMedianValue(rowKey, columnKey);
  148. }
  149. /**
  150. * Returns the mean value for an item.
  151. *
  152. * @param row the row index (zero-based).
  153. * @param column the column index (zero-based).
  154. *
  155. * @return The mean value.
  156. */
  157. public Number getMeanValue(int row, int column) {
  158. Number result = null;
  159. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  160. row, column
  161. );
  162. if (item != null) {
  163. result = item.getMean();
  164. }
  165. return result;
  166. }
  167. /**
  168. * Returns the mean value for an item.
  169. *
  170. * @param rowKey the row key.
  171. * @param columnKey the column key.
  172. *
  173. * @return The mean value.
  174. */
  175. public Number getMeanValue(Comparable rowKey, Comparable columnKey) {
  176. Number result = null;
  177. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  178. rowKey, columnKey
  179. );
  180. if (item != null) {
  181. result = item.getMean();
  182. }
  183. return result;
  184. }
  185. /**
  186. * Returns the median value for an item.
  187. *
  188. * @param row the row index (zero-based).
  189. * @param column the column index (zero-based).
  190. *
  191. * @return The median value.
  192. */
  193. public Number getMedianValue(int row, int column) {
  194. Number result = null;
  195. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  196. row, column
  197. );
  198. if (item != null) {
  199. result = item.getMedian();
  200. }
  201. return result;
  202. }
  203. /**
  204. * Returns the median value for an item.
  205. *
  206. * @param rowKey the row key.
  207. * @param columnKey the columnKey.
  208. *
  209. * @return The median value.
  210. */
  211. public Number getMedianValue(Comparable rowKey, Comparable columnKey) {
  212. Number result = null;
  213. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  214. rowKey, columnKey
  215. );
  216. if (item != null) {
  217. result = item.getMedian();
  218. }
  219. return result;
  220. }
  221. /**
  222. * Returns the first quartile value.
  223. *
  224. * @param row the row index (zero-based).
  225. * @param column the column index (zero-based).
  226. *
  227. * @return The first quartile value.
  228. */
  229. public Number getQ1Value(int row, int column) {
  230. Number result = null;
  231. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  232. row, column
  233. );
  234. if (item != null) {
  235. result = item.getQ1();
  236. }
  237. return result;
  238. }
  239. /**
  240. * Returns the first quartile value.
  241. *
  242. * @param rowKey the row key.
  243. * @param columnKey the column key.
  244. *
  245. * @return The first quartile value.
  246. */
  247. public Number getQ1Value(Comparable rowKey, Comparable columnKey) {
  248. Number result = null;
  249. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  250. rowKey, columnKey
  251. );
  252. if (item != null) {
  253. result = item.getQ1();
  254. }
  255. return result;
  256. }
  257. /**
  258. * Returns the third quartile value.
  259. *
  260. * @param row the row index (zero-based).
  261. * @param column the column index (zero-based).
  262. *
  263. * @return The third quartile value.
  264. */
  265. public Number getQ3Value(int row, int column) {
  266. Number result = null;
  267. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  268. row, column
  269. );
  270. if (item != null) {
  271. result = item.getQ3();
  272. }
  273. return result;
  274. }
  275. /**
  276. * Returns the third quartile value.
  277. *
  278. * @param rowKey the row key.
  279. * @param columnKey the column key.
  280. *
  281. * @return The third quartile value.
  282. */
  283. public Number getQ3Value(Comparable rowKey, Comparable columnKey) {
  284. Number result = null;
  285. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  286. rowKey, columnKey
  287. );
  288. if (item != null) {
  289. result = item.getQ3();
  290. }
  291. return result;
  292. }
  293. /**
  294. * Returns the column index for a given key.
  295. *
  296. * @param key the column key.
  297. *
  298. * @return The column index.
  299. */
  300. public int getColumnIndex(Comparable key) {
  301. return this.data.getColumnIndex(key);
  302. }
  303. /**
  304. * Returns a column key.
  305. *
  306. * @param column the column index (zero-based).
  307. *
  308. * @return The column key.
  309. */
  310. public Comparable getColumnKey(int column) {
  311. return this.data.getColumnKey(column);
  312. }
  313. /**
  314. * Returns the column keys.
  315. *
  316. * @return The keys.
  317. */
  318. public List getColumnKeys() {
  319. return this.data.getColumnKeys();
  320. }
  321. /**
  322. * Returns the row index for a given key.
  323. *
  324. * @param key the row key.
  325. *
  326. * @return The row index.
  327. */
  328. public int getRowIndex(Comparable key) {
  329. return this.data.getRowIndex(key);
  330. }
  331. /**
  332. * Returns a row key.
  333. *
  334. * @param row the row index (zero-based).
  335. *
  336. * @return The row key.
  337. */
  338. public Comparable getRowKey(int row) {
  339. return this.data.getRowKey(row);
  340. }
  341. /**
  342. * Returns the row keys.
  343. *
  344. * @return The keys.
  345. */
  346. public List getRowKeys() {
  347. return this.data.getRowKeys();
  348. }
  349. /**
  350. * Returns the number of rows in the table.
  351. *
  352. * @return The row count.
  353. */
  354. public int getRowCount() {
  355. return this.data.getRowCount();
  356. }
  357. /**
  358. * Returns the number of columns in the table.
  359. *
  360. * @return The column count.
  361. */
  362. public int getColumnCount() {
  363. return this.data.getColumnCount();
  364. }
  365. /**
  366. * Returns the minimum y-value in the dataset.
  367. *
  368. * @param includeInterval a flag that determines whether or not the
  369. * y-interval is taken into account.
  370. *
  371. * @return The minimum value.
  372. */
  373. public double getRangeLowerBound(boolean includeInterval) {
  374. double result = Double.NaN;
  375. if (this.minimumRangeValue != null) {
  376. result = this.minimumRangeValue.doubleValue();
  377. }
  378. return result;
  379. }
  380. /**
  381. * Returns the maximum y-value in the dataset.
  382. *
  383. * @param includeInterval a flag that determines whether or not the
  384. * y-interval is taken into account.
  385. *
  386. * @return The maximum value.
  387. */
  388. public double getRangeUpperBound(boolean includeInterval) {
  389. double result = Double.NaN;
  390. if (this.maximumRangeValue != null) {
  391. result = this.maximumRangeValue.doubleValue();
  392. }
  393. return result;
  394. }
  395. /**
  396. * Returns the range of the values in this dataset's range.
  397. *
  398. * @param includeInterval a flag that determines whether or not the
  399. * y-interval is taken into account.
  400. *
  401. * @return The range.
  402. */
  403. public Range getRangeBounds(boolean includeInterval) {
  404. return this.rangeBounds;
  405. }
  406. /**
  407. * Returns the minimum regular (non outlier) value for an item.
  408. *
  409. * @param row the row index (zero-based).
  410. * @param column the column index (zero-based).
  411. *
  412. * @return The minimum regular value.
  413. */
  414. public Number getMinRegularValue(int row, int column) {
  415. Number result = null;
  416. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  417. row, column
  418. );
  419. if (item != null) {
  420. result = item.getMinRegularValue();
  421. }
  422. return result;
  423. }
  424. /**
  425. * Returns the minimum regular (non outlier) value for an item.
  426. *
  427. * @param rowKey the row key.
  428. * @param columnKey the column key.
  429. *
  430. * @return The minimum regular value.
  431. */
  432. public Number getMinRegularValue(Comparable rowKey, Comparable columnKey) {
  433. Number result = null;
  434. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  435. rowKey, columnKey
  436. );
  437. if (item != null) {
  438. result = item.getMinRegularValue();
  439. }
  440. return result;
  441. }
  442. /**
  443. * Returns the maximum regular (non outlier) value for an item.
  444. *
  445. * @param row the row index (zero-based).
  446. * @param column the column index (zero-based).
  447. *
  448. * @return The maximum regular value.
  449. */
  450. public Number getMaxRegularValue(int row, int column) {
  451. Number result = null;
  452. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  453. row, column
  454. );
  455. if (item != null) {
  456. result = item.getMaxRegularValue();
  457. }
  458. return result;
  459. }
  460. /**
  461. * Returns the maximum regular (non outlier) value for an item.
  462. *
  463. * @param rowKey the row key.
  464. * @param columnKey the column key.
  465. *
  466. * @return The maximum regular value.
  467. */
  468. public Number getMaxRegularValue(Comparable rowKey, Comparable columnKey) {
  469. Number result = null;
  470. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  471. rowKey, columnKey
  472. );
  473. if (item != null) {
  474. result = item.getMaxRegularValue();
  475. }
  476. return result;
  477. }
  478. /**
  479. * Returns the minimum outlier (non farout) value for an item.
  480. *
  481. * @param row the row index (zero-based).
  482. * @param column the column index (zero-based).
  483. *
  484. * @return The minimum outlier.
  485. */
  486. public Number getMinOutlier(int row, int column) {
  487. Number result = null;
  488. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  489. row, column
  490. );
  491. if (item != null) {
  492. result = item.getMinOutlier();
  493. }
  494. return result;
  495. }
  496. /**
  497. * Returns the minimum outlier (non farout) value for an item.
  498. *
  499. * @param rowKey the row key.
  500. * @param columnKey the column key.
  501. *
  502. * @return The minimum outlier.
  503. */
  504. public Number getMinOutlier(Comparable rowKey, Comparable columnKey) {
  505. Number result = null;
  506. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  507. rowKey, columnKey
  508. );
  509. if (item != null) {
  510. result = item.getMinOutlier();
  511. }
  512. return result;
  513. }
  514. /**
  515. * Returns the maximum outlier (non farout) value for an item.
  516. *
  517. * @param row the row index (zero-based).
  518. * @param column the column index (zero-based).
  519. *
  520. * @return The maximum outlier.
  521. */
  522. public Number getMaxOutlier(int row, int column) {
  523. Number result = null;
  524. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  525. row, column
  526. );
  527. if (item != null) {
  528. result = item.getMaxOutlier();
  529. }
  530. return result;
  531. }
  532. /**
  533. * Returns the maximum outlier (non farout) value for an item.
  534. *
  535. * @param rowKey the row key.
  536. * @param columnKey the column key.
  537. *
  538. * @return The maximum outlier.
  539. */
  540. public Number getMaxOutlier(Comparable rowKey, Comparable columnKey) {
  541. Number result = null;
  542. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  543. rowKey, columnKey
  544. );
  545. if (item != null) {
  546. result = item.getMaxOutlier();
  547. }
  548. return result;
  549. }
  550. /**
  551. * Returns a list of outlier values for an item.
  552. *
  553. * @param row the row index (zero-based).
  554. * @param column the column index (zero-based).
  555. *
  556. * @return A list of outlier values.
  557. */
  558. public List getOutliers(int row, int column) {
  559. List result = null;
  560. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  561. row, column
  562. );
  563. if (item != null) {
  564. result = item.getOutliers();
  565. }
  566. return result;
  567. }
  568. /**
  569. * Returns a list of outlier values for an item.
  570. *
  571. * @param rowKey the row key.
  572. * @param columnKey the column key.
  573. *
  574. * @return A list of outlier values.
  575. */
  576. public List getOutliers(Comparable rowKey, Comparable columnKey) {
  577. List result = null;
  578. BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(
  579. rowKey, columnKey
  580. );
  581. if (item != null) {
  582. result = item.getOutliers();
  583. }
  584. return result;
  585. }
  586. /**
  587. * Tests this dataset for equality with an arbitrary object.
  588. *
  589. * @param obj the object to test against (<code>null</code> permitted).
  590. *
  591. * @return A boolean.
  592. */
  593. public boolean equals(Object obj) {
  594. if (obj == null) {
  595. return false;
  596. }
  597. if (obj == this) {
  598. return true;
  599. }
  600. if (obj instanceof DefaultBoxAndWhiskerCategoryDataset) {
  601. DefaultBoxAndWhiskerCategoryDataset dataset
  602. = (DefaultBoxAndWhiskerCategoryDataset) obj;
  603. return ObjectUtilities.equal(this.data, dataset.data);
  604. }
  605. return false;
  606. }
  607. }