Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2007, 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-2007, 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.3 2007/02/02 15:50:24 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: * ------------- JFREECHART 1.0.x --------------------------------------------- 49: * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG); 50: * 51: */ 52: 53: package org.jfree.data.statistics; 54: 55: import java.util.List; 56: 57: import org.jfree.data.KeyedObjects2D; 58: import org.jfree.data.Range; 59: import org.jfree.data.RangeInfo; 60: import org.jfree.data.general.AbstractDataset; 61: import org.jfree.util.ObjectUtilities; 62: 63: /** 64: * A convenience class that provides a default implementation of the 65: * {@link BoxAndWhiskerCategoryDataset} interface. 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 (<code>null</code> not permitted). 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(this.minimumRangeValue.doubleValue(), 138: this.maximumRangeValue.doubleValue()); 139: 140: fireDatasetChanged(); 141: 142: } 143: 144: /** 145: * Return an item from within the dataset. 146: * 147: * @param row the row index. 148: * @param column the column index. 149: * 150: * @return The item. 151: */ 152: public BoxAndWhiskerItem getItem(int row, int column) { 153: return (BoxAndWhiskerItem) this.data.getObject(row, column); 154: } 155: 156: /** 157: * Returns the value for an item. 158: * 159: * @param row the row index. 160: * @param column the column index. 161: * 162: * @return The value. 163: */ 164: public Number getValue(int row, int column) { 165: return getMedianValue(row, column); 166: } 167: 168: /** 169: * Returns the value for an item. 170: * 171: * @param rowKey the row key. 172: * @param columnKey the columnKey. 173: * 174: * @return The value. 175: */ 176: public Number getValue(Comparable rowKey, Comparable columnKey) { 177: return getMedianValue(rowKey, columnKey); 178: } 179: 180: /** 181: * Returns the mean value for an item. 182: * 183: * @param row the row index (zero-based). 184: * @param column the column index (zero-based). 185: * 186: * @return The mean value. 187: */ 188: public Number getMeanValue(int row, int column) { 189: 190: Number result = null; 191: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(row, 192: column); 193: if (item != null) { 194: result = item.getMean(); 195: } 196: return result; 197: 198: } 199: 200: /** 201: * Returns the mean value for an item. 202: * 203: * @param rowKey the row key. 204: * @param columnKey the column key. 205: * 206: * @return The mean value. 207: */ 208: public Number getMeanValue(Comparable rowKey, Comparable columnKey) { 209: Number result = null; 210: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 211: rowKey, columnKey); 212: if (item != null) { 213: result = item.getMean(); 214: } 215: return result; 216: } 217: 218: /** 219: * Returns the median value for an item. 220: * 221: * @param row the row index (zero-based). 222: * @param column the column index (zero-based). 223: * 224: * @return The median value. 225: */ 226: public Number getMedianValue(int row, int column) { 227: Number result = null; 228: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(row, 229: column); 230: if (item != null) { 231: result = item.getMedian(); 232: } 233: return result; 234: } 235: 236: /** 237: * Returns the median value for an item. 238: * 239: * @param rowKey the row key. 240: * @param columnKey the columnKey. 241: * 242: * @return The median value. 243: */ 244: public Number getMedianValue(Comparable rowKey, Comparable columnKey) { 245: Number result = null; 246: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 247: rowKey, columnKey); 248: if (item != null) { 249: result = item.getMedian(); 250: } 251: return result; 252: } 253: 254: /** 255: * Returns the first quartile value. 256: * 257: * @param row the row index (zero-based). 258: * @param column the column index (zero-based). 259: * 260: * @return The first quartile value. 261: */ 262: public Number getQ1Value(int row, int column) { 263: Number result = null; 264: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 265: row, column); 266: if (item != null) { 267: result = item.getQ1(); 268: } 269: return result; 270: } 271: 272: /** 273: * Returns the first quartile value. 274: * 275: * @param rowKey the row key. 276: * @param columnKey the column key. 277: * 278: * @return The first quartile value. 279: */ 280: public Number getQ1Value(Comparable rowKey, Comparable columnKey) { 281: Number result = null; 282: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 283: rowKey, columnKey); 284: if (item != null) { 285: result = item.getQ1(); 286: } 287: return result; 288: } 289: 290: /** 291: * Returns the third quartile value. 292: * 293: * @param row the row index (zero-based). 294: * @param column the column index (zero-based). 295: * 296: * @return The third quartile value. 297: */ 298: public Number getQ3Value(int row, int column) { 299: Number result = null; 300: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 301: row, column); 302: if (item != null) { 303: result = item.getQ3(); 304: } 305: return result; 306: } 307: 308: /** 309: * Returns the third quartile value. 310: * 311: * @param rowKey the row key. 312: * @param columnKey the column key. 313: * 314: * @return The third quartile value. 315: */ 316: public Number getQ3Value(Comparable rowKey, Comparable columnKey) { 317: Number result = null; 318: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 319: rowKey, columnKey); 320: if (item != null) { 321: result = item.getQ3(); 322: } 323: return result; 324: } 325: 326: /** 327: * Returns the column index for a given key. 328: * 329: * @param key the column key. 330: * 331: * @return The column index. 332: */ 333: public int getColumnIndex(Comparable key) { 334: return this.data.getColumnIndex(key); 335: } 336: 337: /** 338: * Returns a column key. 339: * 340: * @param column the column index (zero-based). 341: * 342: * @return The column key. 343: */ 344: public Comparable getColumnKey(int column) { 345: return this.data.getColumnKey(column); 346: } 347: 348: /** 349: * Returns the column keys. 350: * 351: * @return The keys. 352: */ 353: public List getColumnKeys() { 354: return this.data.getColumnKeys(); 355: } 356: 357: /** 358: * Returns the row index for a given key. 359: * 360: * @param key the row key. 361: * 362: * @return The row index. 363: */ 364: public int getRowIndex(Comparable key) { 365: return this.data.getRowIndex(key); 366: } 367: 368: /** 369: * Returns a row key. 370: * 371: * @param row the row index (zero-based). 372: * 373: * @return The row key. 374: */ 375: public Comparable getRowKey(int row) { 376: return this.data.getRowKey(row); 377: } 378: 379: /** 380: * Returns the row keys. 381: * 382: * @return The keys. 383: */ 384: public List getRowKeys() { 385: return this.data.getRowKeys(); 386: } 387: 388: /** 389: * Returns the number of rows in the table. 390: * 391: * @return The row count. 392: */ 393: public int getRowCount() { 394: return this.data.getRowCount(); 395: } 396: 397: /** 398: * Returns the number of columns in the table. 399: * 400: * @return The column count. 401: */ 402: public int getColumnCount() { 403: return this.data.getColumnCount(); 404: } 405: 406: /** 407: * Returns the minimum y-value in the dataset. 408: * 409: * @param includeInterval a flag that determines whether or not the 410: * y-interval is taken into account. 411: * 412: * @return The minimum value. 413: */ 414: public double getRangeLowerBound(boolean includeInterval) { 415: double result = Double.NaN; 416: if (this.minimumRangeValue != null) { 417: result = this.minimumRangeValue.doubleValue(); 418: } 419: return result; 420: } 421: 422: /** 423: * Returns the maximum y-value in the dataset. 424: * 425: * @param includeInterval a flag that determines whether or not the 426: * y-interval is taken into account. 427: * 428: * @return The maximum value. 429: */ 430: public double getRangeUpperBound(boolean includeInterval) { 431: double result = Double.NaN; 432: if (this.maximumRangeValue != null) { 433: result = this.maximumRangeValue.doubleValue(); 434: } 435: return result; 436: } 437: 438: /** 439: * Returns the range of the values in this dataset's range. 440: * 441: * @param includeInterval a flag that determines whether or not the 442: * y-interval is taken into account. 443: * 444: * @return The range. 445: */ 446: public Range getRangeBounds(boolean includeInterval) { 447: return this.rangeBounds; 448: } 449: 450: /** 451: * Returns the minimum regular (non outlier) value for an item. 452: * 453: * @param row the row index (zero-based). 454: * @param column the column index (zero-based). 455: * 456: * @return The minimum regular value. 457: */ 458: public Number getMinRegularValue(int row, int column) { 459: Number result = null; 460: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 461: row, column); 462: if (item != null) { 463: result = item.getMinRegularValue(); 464: } 465: return result; 466: } 467: 468: /** 469: * Returns the minimum regular (non outlier) value for an item. 470: * 471: * @param rowKey the row key. 472: * @param columnKey the column key. 473: * 474: * @return The minimum regular value. 475: */ 476: public Number getMinRegularValue(Comparable rowKey, Comparable columnKey) { 477: Number result = null; 478: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 479: rowKey, columnKey); 480: if (item != null) { 481: result = item.getMinRegularValue(); 482: } 483: return result; 484: } 485: 486: /** 487: * Returns the maximum regular (non outlier) value for an item. 488: * 489: * @param row the row index (zero-based). 490: * @param column the column index (zero-based). 491: * 492: * @return The maximum regular value. 493: */ 494: public Number getMaxRegularValue(int row, int column) { 495: Number result = null; 496: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 497: row, column); 498: if (item != null) { 499: result = item.getMaxRegularValue(); 500: } 501: return result; 502: } 503: 504: /** 505: * Returns the maximum regular (non outlier) value for an item. 506: * 507: * @param rowKey the row key. 508: * @param columnKey the column key. 509: * 510: * @return The maximum regular value. 511: */ 512: public Number getMaxRegularValue(Comparable rowKey, Comparable columnKey) { 513: Number result = null; 514: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 515: rowKey, columnKey); 516: if (item != null) { 517: result = item.getMaxRegularValue(); 518: } 519: return result; 520: } 521: 522: /** 523: * Returns the minimum outlier (non farout) value for an item. 524: * 525: * @param row the row index (zero-based). 526: * @param column the column index (zero-based). 527: * 528: * @return The minimum outlier. 529: */ 530: public Number getMinOutlier(int row, int column) { 531: Number result = null; 532: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 533: row, column); 534: if (item != null) { 535: result = item.getMinOutlier(); 536: } 537: return result; 538: } 539: 540: /** 541: * Returns the minimum outlier (non farout) value for an item. 542: * 543: * @param rowKey the row key. 544: * @param columnKey the column key. 545: * 546: * @return The minimum outlier. 547: */ 548: public Number getMinOutlier(Comparable rowKey, Comparable columnKey) { 549: Number result = null; 550: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 551: rowKey, columnKey); 552: if (item != null) { 553: result = item.getMinOutlier(); 554: } 555: return result; 556: } 557: 558: /** 559: * Returns the maximum outlier (non farout) value for an item. 560: * 561: * @param row the row index (zero-based). 562: * @param column the column index (zero-based). 563: * 564: * @return The maximum outlier. 565: */ 566: public Number getMaxOutlier(int row, int column) { 567: Number result = null; 568: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 569: row, column); 570: if (item != null) { 571: result = item.getMaxOutlier(); 572: } 573: return result; 574: } 575: 576: /** 577: * Returns the maximum outlier (non farout) value for an item. 578: * 579: * @param rowKey the row key. 580: * @param columnKey the column key. 581: * 582: * @return The maximum outlier. 583: */ 584: public Number getMaxOutlier(Comparable rowKey, Comparable columnKey) { 585: Number result = null; 586: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 587: rowKey, columnKey); 588: if (item != null) { 589: result = item.getMaxOutlier(); 590: } 591: return result; 592: } 593: 594: /** 595: * Returns a list of outlier values for an item. 596: * 597: * @param row the row index (zero-based). 598: * @param column the column index (zero-based). 599: * 600: * @return A list of outlier values. 601: */ 602: public List getOutliers(int row, int column) { 603: List result = null; 604: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 605: row, column); 606: if (item != null) { 607: result = item.getOutliers(); 608: } 609: return result; 610: } 611: 612: /** 613: * Returns a list of outlier values for an item. 614: * 615: * @param rowKey the row key. 616: * @param columnKey the column key. 617: * 618: * @return A list of outlier values. 619: */ 620: public List getOutliers(Comparable rowKey, Comparable columnKey) { 621: List result = null; 622: BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject( 623: rowKey, columnKey); 624: if (item != null) { 625: result = item.getOutliers(); 626: } 627: return result; 628: } 629: 630: /** 631: * Tests this dataset for equality with an arbitrary object. 632: * 633: * @param obj the object to test against (<code>null</code> permitted). 634: * 635: * @return A boolean. 636: */ 637: public boolean equals(Object obj) { 638: if (obj == this) { 639: return true; 640: } 641: if (obj instanceof DefaultBoxAndWhiskerCategoryDataset) { 642: DefaultBoxAndWhiskerCategoryDataset dataset 643: = (DefaultBoxAndWhiskerCategoryDataset) obj; 644: return ObjectUtilities.equal(this.data, dataset.data); 645: } 646: return false; 647: } 648: 649: }