Source for org.jfree.data.statistics.DefaultStatisticalCategoryDataset

   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:  * DefaultStatisticalCategoryDataset.java
  29:  * --------------------------------------
  30:  * (C) Copyright 2002-2007, by Pascal Collet and Contributors.
  31:  *
  32:  * Original Author:  Pascal Collet;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *
  35:  * Changes
  36:  * -------
  37:  * 21-Aug-2002 : Version 1, contributed by Pascal Collet (DG);
  38:  * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  39:  * 05-Feb-2003 : Revised implementation to use KeyedObjects2D (DG);
  40:  * 28-Aug-2003 : Moved from org.jfree.data --> org.jfree.data.statistics (DG);
  41:  * 06-Oct-2003 : Removed incorrect Javadoc text (DG);
  42:  * 18-Nov-2004 : Updated for changes in RangeInfo interface (DG);
  43:  * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0 
  44:  *               release (DG);
  45:  * 01-Feb-2005 : Changed minimumRangeValue and maximumRangeValue from Double
  46:  *               to double (DG);
  47:  * 05-Feb-2005 : Implemented equals() method (DG);
  48:  * ------------- JFREECHART 1.0.x ---------------------------------------------
  49:  * 08-Aug-2006 : Reworked implementation of RangeInfo methods (DG);
  50:  * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
  51:  * 28-Sep-2007 : Fixed cloning bug (DG);
  52:  * 02-Oct-2007 : Fixed bug updating cached range values (DG);
  53:  * 
  54:  */
  55: 
  56: package org.jfree.data.statistics;
  57: 
  58: import java.util.List;
  59: 
  60: import org.jfree.data.KeyedObjects2D;
  61: import org.jfree.data.Range;
  62: import org.jfree.data.RangeInfo;
  63: import org.jfree.data.general.AbstractDataset;
  64: import org.jfree.data.general.DatasetChangeEvent;
  65: import org.jfree.util.PublicCloneable;
  66: 
  67: /**
  68:  * A convenience class that provides a default implementation of the
  69:  * {@link StatisticalCategoryDataset} interface.
  70:  */
  71: public class DefaultStatisticalCategoryDataset extends AbstractDataset
  72:         implements StatisticalCategoryDataset, RangeInfo, PublicCloneable {
  73: 
  74:     /** Storage for the data. */
  75:     private KeyedObjects2D data;
  76: 
  77:     /** The minimum range value. */
  78:     private double minimumRangeValue;
  79: 
  80:     /** The row index for the minimum range value. */
  81:     private int minimumRangeValueRow;
  82:     
  83:     /** The column index for the minimum range value. */
  84:     private int minimumRangeValueColumn;
  85:     
  86:     /** The minimum range value including the standard deviation. */
  87:     private double minimumRangeValueIncStdDev;
  88:     
  89:     /** 
  90:      * The row index for the minimum range value (including the standard 
  91:      * deviation). 
  92:      */
  93:     private int minimumRangeValueIncStdDevRow;
  94:     
  95:     /** 
  96:      * The column index for the minimum range value (including the standard 
  97:      * deviation). 
  98:      */
  99:     private int minimumRangeValueIncStdDevColumn;
 100:     
 101:     /** The maximum range value. */
 102:     private double maximumRangeValue;
 103:     
 104:     /** The row index for the maximum range value. */
 105:     private int maximumRangeValueRow;
 106:     
 107:     /** The column index for the maximum range value. */
 108:     private int maximumRangeValueColumn;
 109: 
 110:     /** The maximum range value including the standard deviation. */
 111:     private double maximumRangeValueIncStdDev;
 112: 
 113:     /** 
 114:      * The row index for the maximum range value (including the standard 
 115:      * deviation). 
 116:      */
 117:     private int maximumRangeValueIncStdDevRow;
 118:     
 119:     /** 
 120:      * The column index for the maximum range value (including the standard 
 121:      * deviation). 
 122:      */
 123:     private int maximumRangeValueIncStdDevColumn;
 124:     
 125:     /**
 126:      * Creates a new dataset.
 127:      */
 128:     public DefaultStatisticalCategoryDataset() {
 129:         this.data = new KeyedObjects2D();
 130:         this.minimumRangeValue = Double.NaN;
 131:         this.minimumRangeValueRow = -1;
 132:         this.minimumRangeValueColumn = -1;
 133:         this.maximumRangeValue = Double.NaN;
 134:         this.maximumRangeValueRow = -1;
 135:         this.maximumRangeValueColumn = -1;
 136:         this.minimumRangeValueIncStdDev = Double.NaN;
 137:         this.minimumRangeValueIncStdDevRow = -1;
 138:         this.minimumRangeValueIncStdDevColumn = -1;
 139:         this.maximumRangeValueIncStdDev = Double.NaN;
 140:         this.maximumRangeValueIncStdDevRow = -1;
 141:         this.maximumRangeValueIncStdDevColumn = -1;
 142:     }
 143: 
 144:     /**
 145:      * Returns the mean value for an item.
 146:      *
 147:      * @param row  the row index (zero-based).
 148:      * @param column  the column index (zero-based).
 149:      *
 150:      * @return The mean value (possibly <code>null</code>).
 151:      */
 152:     public Number getMeanValue(int row, int column) {
 153:         Number result = null;
 154:         MeanAndStandardDeviation masd = (MeanAndStandardDeviation) 
 155:                 this.data.getObject(row, column);
 156:         if (masd != null) {
 157:             result = masd.getMean();
 158:         }
 159:         return result;
 160:     }
 161: 
 162:     /**
 163:      * Returns the value for an item (for this dataset, the mean value is
 164:      * returned).
 165:      *
 166:      * @param row  the row index.
 167:      * @param column  the column index.
 168:      *
 169:      * @return The value (possibly <code>null</code>).
 170:      */
 171:     public Number getValue(int row, int column) {
 172:         return getMeanValue(row, column);
 173:     }
 174: 
 175:     /**
 176:      * Returns the value for an item (for this dataset, the mean value is
 177:      * returned).
 178:      *
 179:      * @param rowKey  the row key.
 180:      * @param columnKey  the columnKey.
 181:      *
 182:      * @return The value (possibly <code>null</code>).
 183:      */
 184:     public Number getValue(Comparable rowKey, Comparable columnKey) {
 185:         return getMeanValue(rowKey, columnKey);
 186:     }
 187: 
 188:     /**
 189:      * Returns the mean value for an item.
 190:      *
 191:      * @param rowKey  the row key.
 192:      * @param columnKey  the columnKey.
 193:      *
 194:      * @return The mean value (possibly <code>null</code>).
 195:      */
 196:     public Number getMeanValue(Comparable rowKey, Comparable columnKey) {
 197:         Number result = null;
 198:         MeanAndStandardDeviation masd = (MeanAndStandardDeviation) 
 199:                 this.data.getObject(rowKey, columnKey);
 200:         if (masd != null) {
 201:             result = masd.getMean();
 202:         }
 203:         return result;
 204:     }
 205: 
 206:     /**
 207:      * Returns the standard deviation value for an item.
 208:      *
 209:      * @param row  the row index (zero-based).
 210:      * @param column  the column index (zero-based).
 211:      *
 212:      * @return The standard deviation (possibly <code>null</code>).
 213:      */
 214:     public Number getStdDevValue(int row, int column) {
 215:         Number result = null;
 216:         MeanAndStandardDeviation masd = (MeanAndStandardDeviation) 
 217:                 this.data.getObject(row, column);
 218:         if (masd != null) {
 219:             result = masd.getStandardDeviation();
 220:         }
 221:         return result;
 222:     }
 223: 
 224:     /**
 225:      * Returns the standard deviation value for an item.
 226:      *
 227:      * @param rowKey  the row key.
 228:      * @param columnKey  the columnKey.
 229:      *
 230:      * @return The standard deviation (possibly <code>null</code>).
 231:      */
 232:     public Number getStdDevValue(Comparable rowKey, Comparable columnKey) {
 233:         Number result = null;
 234:         MeanAndStandardDeviation masd = (MeanAndStandardDeviation) 
 235:                 this.data.getObject(rowKey, columnKey);
 236:         if (masd != null) {
 237:             result = masd.getStandardDeviation();
 238:         }
 239:         return result;
 240:     }
 241: 
 242:     /**
 243:      * Returns the column index for a given key.
 244:      *
 245:      * @param key  the column key (<code>null</code> not permitted).
 246:      *
 247:      * @return The column index.
 248:      */
 249:     public int getColumnIndex(Comparable key) {
 250:         // defer null argument check
 251:         return this.data.getColumnIndex(key);
 252:     }
 253: 
 254:     /**
 255:      * Returns a column key.
 256:      *
 257:      * @param column  the column index (zero-based).
 258:      *
 259:      * @return The column key.
 260:      */
 261:     public Comparable getColumnKey(int column) {
 262:         return this.data.getColumnKey(column);
 263:     }
 264: 
 265:     /**
 266:      * Returns the column keys.
 267:      *
 268:      * @return The keys.
 269:      */
 270:     public List getColumnKeys() {
 271:         return this.data.getColumnKeys();
 272:     }
 273: 
 274:     /**
 275:      * Returns the row index for a given key.
 276:      *
 277:      * @param key  the row key (<code>null</code> not permitted).
 278:      *
 279:      * @return The row index.
 280:      */
 281:     public int getRowIndex(Comparable key) {
 282:         // defer null argument check
 283:         return this.data.getRowIndex(key);
 284:     }
 285: 
 286:     /**
 287:      * Returns a row key.
 288:      *
 289:      * @param row  the row index (zero-based).
 290:      *
 291:      * @return The row key.
 292:      */
 293:     public Comparable getRowKey(int row) {
 294:         return this.data.getRowKey(row);
 295:     }
 296: 
 297:     /**
 298:      * Returns the row keys.
 299:      *
 300:      * @return The keys.
 301:      */
 302:     public List getRowKeys() {
 303:         return this.data.getRowKeys();
 304:     }
 305: 
 306:     /**
 307:      * Returns the number of rows in the table.
 308:      *
 309:      * @return The row count.
 310:      * 
 311:      * @see #getColumnCount()
 312:      */
 313:     public int getRowCount() {
 314:         return this.data.getRowCount();
 315:     }
 316: 
 317:     /**
 318:      * Returns the number of columns in the table.
 319:      *
 320:      * @return The column count.
 321:      * 
 322:      * @see #getRowCount()
 323:      */
 324:     public int getColumnCount() {
 325:         return this.data.getColumnCount();
 326:     }
 327: 
 328:     /**
 329:      * Adds a mean and standard deviation to the table.
 330:      *
 331:      * @param mean  the mean.
 332:      * @param standardDeviation  the standard deviation.
 333:      * @param rowKey  the row key.
 334:      * @param columnKey  the column key.
 335:      */
 336:     public void add(double mean, double standardDeviation,
 337:                     Comparable rowKey, Comparable columnKey) {
 338:         add(new Double(mean), new Double(standardDeviation), rowKey, columnKey);
 339:     }
 340: 
 341:     /**
 342:      * Adds a mean and standard deviation to the table.
 343:      *
 344:      * @param mean  the mean.
 345:      * @param standardDeviation  the standard deviation.
 346:      * @param rowKey  the row key.
 347:      * @param columnKey  the column key.
 348:      */
 349:     public void add(Number mean, Number standardDeviation,
 350:                     Comparable rowKey, Comparable columnKey) {
 351:         MeanAndStandardDeviation item = new MeanAndStandardDeviation(
 352:                 mean, standardDeviation);
 353:         this.data.addObject(item, rowKey, columnKey);
 354:         
 355:         double m = Double.NaN;
 356:         double sd = Double.NaN;
 357:         if (mean != null) {
 358:             m = mean.doubleValue();
 359:         }
 360:         if (standardDeviation != null) {
 361:             sd = standardDeviation.doubleValue();   
 362:         }
 363:         
 364:         // update cached range values
 365:         int r = this.data.getColumnIndex(columnKey);
 366:         int c = this.data.getRowIndex(rowKey);
 367:         if ((r == this.maximumRangeValueRow && c 
 368:                 == this.maximumRangeValueColumn) || (r 
 369:                 == this.maximumRangeValueIncStdDevRow && c 
 370:                 == this.maximumRangeValueIncStdDevColumn) || (r 
 371:                 == this.minimumRangeValueRow && c 
 372:                 == this.minimumRangeValueColumn) || (r 
 373:                 == this.minimumRangeValueIncStdDevRow && c 
 374:                 == this.minimumRangeValueIncStdDevColumn)) {
 375:             
 376:             // iterate over all data items and update mins and maxes
 377:             updateBounds();
 378:         } 
 379:         else {
 380:             if (!Double.isNaN(m)) {
 381:                 if (Double.isNaN(this.maximumRangeValue) 
 382:                         || m > this.maximumRangeValue) {
 383:                     this.maximumRangeValue = m;
 384:                     this.maximumRangeValueRow = r;
 385:                     this.maximumRangeValueColumn = c;
 386:                 }
 387:             }
 388:         
 389:             if (!Double.isNaN(m + sd)) {
 390:                 if (Double.isNaN(this.maximumRangeValueIncStdDev) 
 391:                         || (m + sd) > this.maximumRangeValueIncStdDev) {
 392:                     this.maximumRangeValueIncStdDev = m + sd;
 393:                     this.maximumRangeValueIncStdDevRow = r;
 394:                     this.maximumRangeValueIncStdDevColumn = c;
 395:                 }
 396:             }
 397: 
 398:             if (!Double.isNaN(m)) {
 399:                 if (Double.isNaN(this.minimumRangeValue) 
 400:                         || m < this.minimumRangeValue) {
 401:                     this.minimumRangeValue = m;
 402:                     this.minimumRangeValueRow = r;
 403:                     this.minimumRangeValueColumn = c;
 404:                 }
 405:             }
 406: 
 407:             if (!Double.isNaN(m - sd)) {
 408:                 if (Double.isNaN(this.minimumRangeValueIncStdDev) 
 409:                         || (m - sd) < this.minimumRangeValueIncStdDev) {
 410:                     this.minimumRangeValueIncStdDev = m - sd;
 411:                     this.minimumRangeValueIncStdDevRow = r;
 412:                     this.minimumRangeValueIncStdDevColumn = c;
 413:                 }
 414:             }
 415:         }
 416:         fireDatasetChanged();
 417:     }
 418:     
 419:     /**
 420:      * Removes an item from the dataset and sends a {@link DatasetChangeEvent}
 421:      * to all registered listeners.
 422:      *
 423:      * @param rowKey  the row key (<code>null</code> not permitted).
 424:      * @param columnKey  the column key (<code>null</code> not permitted).
 425:      * 
 426:      * @see #add(double, double, Comparable, Comparable)
 427:      * 
 428:      * @since 1.0.7
 429:      */
 430:     public void remove(Comparable rowKey, Comparable columnKey) {
 431:         // defer null argument checks
 432:         int r = getRowIndex(rowKey);
 433:         int c = getColumnIndex(columnKey);
 434:         this.data.removeObject(rowKey, columnKey);
 435:         
 436:         // if this cell held a maximum and/or minimum value, we'll need to
 437:         // update the cached bounds...
 438:         if ((r == this.maximumRangeValueRow && c 
 439:                 == this.maximumRangeValueColumn) || (r 
 440:                 == this.maximumRangeValueIncStdDevRow && c 
 441:                 == this.maximumRangeValueIncStdDevColumn) || (r 
 442:                 == this.minimumRangeValueRow && c 
 443:                 == this.minimumRangeValueColumn) || (r 
 444:                 == this.minimumRangeValueIncStdDevRow && c 
 445:                 == this.minimumRangeValueIncStdDevColumn)) {
 446:             
 447:             // iterate over all data items and update mins and maxes
 448:             updateBounds();
 449:         } 
 450:         
 451:         fireDatasetChanged();
 452:     }    
 453: 
 454: 
 455:     /**
 456:      * Removes a row from the dataset and sends a {@link DatasetChangeEvent}
 457:      * to all registered listeners.
 458:      *
 459:      * @param rowIndex  the row index.
 460:      * 
 461:      * @see #removeColumn(int)
 462:      * 
 463:      * @since 1.0.7
 464:      */
 465:     public void removeRow(int rowIndex) {
 466:         this.data.removeRow(rowIndex);
 467:         updateBounds();
 468:         fireDatasetChanged();
 469:     }
 470: 
 471:     /**
 472:      * Removes a row from the dataset and sends a {@link DatasetChangeEvent}
 473:      * to all registered listeners.
 474:      *
 475:      * @param rowKey  the row key (<code>null</code> not permitted).
 476:      * 
 477:      * @see #removeColumn(Comparable)
 478:      * 
 479:      * @since 1.0.7
 480:      */
 481:     public void removeRow(Comparable rowKey) {
 482:         this.data.removeRow(rowKey);
 483:         updateBounds();
 484:         fireDatasetChanged();
 485:     }
 486: 
 487:     /**
 488:      * Removes a column from the dataset and sends a {@link DatasetChangeEvent}
 489:      * to all registered listeners.
 490:      *
 491:      * @param columnIndex  the column index.
 492:      * 
 493:      * @see #removeRow(int)
 494:      * 
 495:      * @since 1.0.7
 496:      */
 497:     public void removeColumn(int columnIndex) {
 498:         this.data.removeColumn(columnIndex);
 499:         updateBounds();
 500:         fireDatasetChanged();
 501:     }
 502: 
 503:     /**
 504:      * Removes a column from the dataset and sends a {@link DatasetChangeEvent}
 505:      * to all registered listeners.
 506:      *
 507:      * @param columnKey  the column key (<code>null</code> not permitted).
 508:      * 
 509:      * @see #removeRow(Comparable)
 510:      * 
 511:      * @since 1.0.7
 512:      */
 513:     public void removeColumn(Comparable columnKey) {
 514:         this.data.removeColumn(columnKey);
 515:         updateBounds();
 516:         fireDatasetChanged();
 517:     }
 518: 
 519:     /**
 520:      * Clears all data from the dataset and sends a {@link DatasetChangeEvent} 
 521:      * to all registered listeners.
 522:      * 
 523:      * @since 1.0.7
 524:      */
 525:     public void clear() {
 526:         this.data.clear();
 527:         updateBounds();
 528:         fireDatasetChanged();
 529:     }
 530:     
 531:     /**
 532:      * Iterate over all the data items and update the cached bound values.
 533:      */
 534:     private void updateBounds() {
 535:         this.maximumRangeValue = Double.NaN;
 536:         this.maximumRangeValueRow = -1;
 537:         this.maximumRangeValueColumn = -1;
 538:         this.minimumRangeValue = Double.NaN;
 539:         this.minimumRangeValueRow = -1;
 540:         this.minimumRangeValueColumn = -1;
 541:         this.maximumRangeValueIncStdDev = Double.NaN;
 542:         this.maximumRangeValueIncStdDevRow = -1;
 543:         this.maximumRangeValueIncStdDevColumn = -1;
 544:         this.minimumRangeValueIncStdDev = Double.NaN;
 545:         this.minimumRangeValueIncStdDevRow = -1;
 546:         this.minimumRangeValueIncStdDevColumn = -1;
 547:         
 548:         int rowCount = this.data.getRowCount();
 549:         int columnCount = this.data.getColumnCount();
 550:         for (int r = 0; r < rowCount; r++) {
 551:             for (int c = 0; c < columnCount; c++) {
 552:                 double m = Double.NaN;
 553:                 double sd = Double.NaN;
 554:                 MeanAndStandardDeviation masd = (MeanAndStandardDeviation) 
 555:                         this.data.getObject(r, c);
 556:                 if (masd == null) {
 557:                     continue;
 558:                 }
 559:                 m = masd.getMeanValue();
 560:                 sd = masd.getStandardDeviationValue();
 561:                 
 562:                 if (!Double.isNaN(m)) {
 563:                     
 564:                     // update the max value
 565:                     if (Double.isNaN(this.maximumRangeValue)) {
 566:                         this.maximumRangeValue = m;
 567:                         this.maximumRangeValueRow = r;
 568:                         this.maximumRangeValueColumn = c;
 569:                     }
 570:                     else {
 571:                         if (m > this.maximumRangeValue) {
 572:                             this.maximumRangeValue = m;
 573:                             this.maximumRangeValueRow = r;
 574:                             this.maximumRangeValueColumn = c;
 575:                         }
 576:                     }
 577:                     
 578:                     // update the min value
 579:                     if (Double.isNaN(this.minimumRangeValue)) {
 580:                         this.minimumRangeValue = m;
 581:                         this.minimumRangeValueRow = r;
 582:                         this.minimumRangeValueColumn = c;
 583:                     }
 584:                     else {
 585:                         if (m < this.minimumRangeValue) {
 586:                             this.minimumRangeValue = m;
 587:                             this.minimumRangeValueRow = r;
 588:                             this.minimumRangeValueColumn = c;
 589:                         }
 590:                     }
 591:                     
 592:                     if (!Double.isNaN(sd)) {
 593:                         // update the max value
 594:                         if (Double.isNaN(this.maximumRangeValueIncStdDev)) {
 595:                             this.maximumRangeValueIncStdDev = m + sd;
 596:                             this.maximumRangeValueIncStdDevRow = r;
 597:                             this.maximumRangeValueIncStdDevColumn = c;
 598:                         }
 599:                         else {
 600:                             if (m + sd > this.maximumRangeValueIncStdDev) {
 601:                                 this.maximumRangeValueIncStdDev = m + sd;
 602:                                 this.maximumRangeValueIncStdDevRow = r;
 603:                                 this.maximumRangeValueIncStdDevColumn = c;
 604:                             }
 605:                         }
 606:                         
 607:                         // update the min value
 608:                         if (Double.isNaN(this.minimumRangeValueIncStdDev)) {
 609:                             this.minimumRangeValueIncStdDev = m - sd;
 610:                             this.minimumRangeValueIncStdDevRow = r;
 611:                             this.minimumRangeValueIncStdDevColumn = c;
 612:                         }
 613:                         else {
 614:                             if (m - sd < this.minimumRangeValueIncStdDev) {
 615:                                 this.minimumRangeValueIncStdDev = m - sd;
 616:                                 this.minimumRangeValueIncStdDevRow = r;
 617:                                 this.minimumRangeValueIncStdDevColumn = c;
 618:                             }
 619:                         }
 620:                     }
 621:                 }
 622:             }
 623:         }
 624:     }
 625:     
 626:     /**
 627:      * Returns the minimum y-value in the dataset.
 628:      *
 629:      * @param includeInterval  a flag that determines whether or not the
 630:      *                         y-interval is taken into account.
 631:      * 
 632:      * @return The minimum value.
 633:      * 
 634:      * @see #getRangeUpperBound(boolean)
 635:      */
 636:     public double getRangeLowerBound(boolean includeInterval) {
 637:         if (includeInterval) {
 638:             return this.minimumRangeValueIncStdDev;
 639:         }
 640:         else {
 641:             return this.minimumRangeValue;     
 642:         }  
 643:     }
 644: 
 645:     /**
 646:      * Returns the maximum y-value in the dataset.
 647:      *
 648:      * @param includeInterval  a flag that determines whether or not the
 649:      *                         y-interval is taken into account.
 650:      * 
 651:      * @return The maximum value.
 652:      * 
 653:      * @see #getRangeLowerBound(boolean)
 654:      */
 655:     public double getRangeUpperBound(boolean includeInterval) {
 656:         if (includeInterval) {
 657:             return this.maximumRangeValueIncStdDev;
 658:         }
 659:         else {
 660:             return this.maximumRangeValue;     
 661:         }  
 662:     }
 663: 
 664:     /**
 665:      * Returns the range of the values in this dataset's range.
 666:      *
 667:      * @param includeInterval  a flag that determines whether or not the
 668:      *                         y-interval is taken into account.
 669:      * 
 670:      * @return The range.
 671:      */
 672:     public Range getRangeBounds(boolean includeInterval) {
 673:         Range result = null;
 674:         if (includeInterval) {
 675:             if (!Double.isNaN(this.minimumRangeValueIncStdDev) 
 676:                     && !Double.isNaN(this.maximumRangeValueIncStdDev)) {
 677:                 result = new Range(this.minimumRangeValueIncStdDev, 
 678:                         this.maximumRangeValueIncStdDev);
 679:             }
 680:         }
 681:         else {
 682:             if (!Double.isNaN(this.minimumRangeValue) 
 683:                     && !Double.isNaN(this.maximumRangeValue)) {
 684:                 result = new Range(this.minimumRangeValue, 
 685:                         this.maximumRangeValue);
 686:             }
 687:         }
 688:         return result;
 689:     }
 690: 
 691:     /**
 692:      * Tests this instance for equality with an arbitrary object.
 693:      * 
 694:      * @param obj  the object (<code>null</code> permitted).
 695:      * 
 696:      * @return A boolean.
 697:      */
 698:     public boolean equals(Object obj) {
 699:         if (obj == this) {
 700:             return true;   
 701:         }
 702:         if (!(obj instanceof DefaultStatisticalCategoryDataset)) {
 703:             return false;   
 704:         }
 705:         DefaultStatisticalCategoryDataset that 
 706:                 = (DefaultStatisticalCategoryDataset) obj;
 707:         if (!this.data.equals(that.data)) {
 708:             return false;   
 709:         }
 710:         return true;
 711:     }
 712:     
 713:     /**
 714:      * Returns a clone of this dataset.
 715:      * 
 716:      * @return A clone of this dataset.
 717:      * 
 718:      * @throws CloneNotSupportedException if cloning cannot be completed.
 719:      */
 720:     public Object clone() throws CloneNotSupportedException {
 721:         DefaultStatisticalCategoryDataset clone 
 722:                 = (DefaultStatisticalCategoryDataset) super.clone();
 723:         clone.data = (KeyedObjects2D) this.data.clone();
 724:         return clone;
 725:     }
 726: }