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