/** Confirm that the equals method can distinguish all the required fields. */
  @Test
  public void testEquals() {

    BoxAndWhiskerItem i1 =
        new BoxAndWhiskerItem(
            new Double(1.0),
            new Double(2.0),
            new Double(3.0),
            new Double(4.0),
            new Double(5.0),
            new Double(6.0),
            new Double(7.0),
            new Double(8.0),
            new ArrayList());
    BoxAndWhiskerItem i2 =
        new BoxAndWhiskerItem(
            new Double(1.0),
            new Double(2.0),
            new Double(3.0),
            new Double(4.0),
            new Double(5.0),
            new Double(6.0),
            new Double(7.0),
            new Double(8.0),
            new ArrayList());
    assertTrue(i1.equals(i2));
    assertTrue(i2.equals(i1));
  }
 /**
  * Returns an array of outliers for the specified series and item.
  *
  * @param series the series (zero-based index).
  * @param item the item (zero-based index).
  * @return The array of outliers for the specified series and item.
  */
 public List getOutliers(int series, int item) {
   List result = null;
   BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
   if (stats != null) {
     result = stats.getOutliers();
   }
   return result;
 }
 /**
  * Returns the maximum value which is not a farout, ie Q3 + (interquartile range * farout
  * coefficient).
  *
  * @param series the series (zero-based index).
  * @param item the item (zero-based index).
  * @return A <code>Number</code> representing the maximum non-farout value.
  */
 public Number getMaxOutlier(int series, int item) {
   Number result = null;
   BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
   if (stats != null) {
     result = stats.getMaxOutlier();
   }
   return result;
 }
 /**
  * Returns the min-value for the specified series and item.
  *
  * @param series the series (zero-based index).
  * @param item the item (zero-based index).
  * @return The min-value for the specified series and item.
  */
 public Number getMinRegularValue(int series, int item) {
   Number result = null;
   BoxAndWhiskerItem stats = (BoxAndWhiskerItem) this.items.get(item);
   if (stats != null) {
     result = stats.getMinRegularValue();
   }
   return result;
 }
 /**
  * Returns a list of outlier values for an item.
  *
  * @param rowKey the row key.
  * @param columnKey the column key.
  * @return A list of outlier values.
  * @see #getItem(int, int)
  */
 public List getOutliers(Comparable rowKey, Comparable columnKey) {
   List result = null;
   BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(rowKey, columnKey);
   if (item != null) {
     result = item.getOutliers();
   }
   return result;
 }
 /**
  * Returns a list of outlier values for an item.
  *
  * @param row the row index (zero-based).
  * @param column the column index (zero-based).
  * @return A list of outlier values.
  * @see #getItem(int, int)
  */
 public List getOutliers(int row, int column) {
   List result = null;
   BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(row, column);
   if (item != null) {
     result = item.getOutliers();
   }
   return result;
 }
 /**
  * Returns the maximum outlier (non farout) value for an item.
  *
  * @param rowKey the row key.
  * @param columnKey the column key.
  * @return The maximum outlier.
  * @see #getItem(int, int)
  */
 public Number getMaxOutlier(Comparable rowKey, Comparable columnKey) {
   Number result = null;
   BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(rowKey, columnKey);
   if (item != null) {
     result = item.getMaxOutlier();
   }
   return result;
 }
 /**
  * Returns the maximum outlier (non farout) value for an item.
  *
  * @param row the row index (zero-based).
  * @param column the column index (zero-based).
  * @return The maximum outlier.
  * @see #getItem(int, int)
  */
 public Number getMaxOutlier(int row, int column) {
   Number result = null;
   BoxAndWhiskerItem item = (BoxAndWhiskerItem) this.data.getObject(row, column);
   if (item != null) {
     result = item.getMaxOutlier();
   }
   return result;
 }
  /**
   * Adds a list of values relating to one Box and Whisker entity to the table. The various median
   * values are calculated.
   *
   * @param item a box and whisker item (<code>null</code> not permitted).
   * @param rowKey the row key (<code>null</code> not permitted).
   * @param columnKey the column key (<code>null</code> not permitted).
   * @see #add(List, Comparable, Comparable)
   */
  public void add(BoxAndWhiskerItem item, Comparable rowKey, Comparable columnKey) {

    this.data.addObject(item, rowKey, columnKey);

    // update cached min and max values
    int r = this.data.getRowIndex(rowKey);
    int c = this.data.getColumnIndex(columnKey);
    if ((this.maximumRangeValueRow == r && this.maximumRangeValueColumn == c)
        || (this.minimumRangeValueRow == r && this.minimumRangeValueColumn == c)) {
      updateBounds();
    } else {

      double minval = Double.NaN;
      if (item.getMinOutlier() != null) {
        minval = item.getMinOutlier().doubleValue();
      }
      double maxval = Double.NaN;
      if (item.getMaxOutlier() != null) {
        maxval = item.getMaxOutlier().doubleValue();
      }

      if (Double.isNaN(this.maximumRangeValue)) {
        this.maximumRangeValue = maxval;
        this.maximumRangeValueRow = r;
        this.maximumRangeValueColumn = c;
      } else if (maxval > this.maximumRangeValue) {
        this.maximumRangeValue = maxval;
        this.maximumRangeValueRow = r;
        this.maximumRangeValueColumn = c;
      }

      if (Double.isNaN(this.minimumRangeValue)) {
        this.minimumRangeValue = minval;
        this.minimumRangeValueRow = r;
        this.minimumRangeValueColumn = c;
      } else if (minval < this.minimumRangeValue) {
        this.minimumRangeValue = minval;
        this.minimumRangeValueRow = r;
        this.minimumRangeValueColumn = c;
      }
    }

    fireDatasetChanged();
  }
 /** Resets the cached bounds, by iterating over the entire dataset to find the current bounds. */
 private void updateBounds() {
   this.minimumRangeValue = Double.NaN;
   this.minimumRangeValueRow = -1;
   this.minimumRangeValueColumn = -1;
   this.maximumRangeValue = Double.NaN;
   this.maximumRangeValueRow = -1;
   this.maximumRangeValueColumn = -1;
   int rowCount = getRowCount();
   int columnCount = getColumnCount();
   for (int r = 0; r < rowCount; r++) {
     for (int c = 0; c < columnCount; c++) {
       BoxAndWhiskerItem item = getItem(r, c);
       if (item != null) {
         Number min = item.getMinOutlier();
         if (min != null) {
           double minv = min.doubleValue();
           if (!Double.isNaN(minv)) {
             if (minv < this.minimumRangeValue || Double.isNaN(this.minimumRangeValue)) {
               this.minimumRangeValue = minv;
               this.minimumRangeValueRow = r;
               this.minimumRangeValueColumn = c;
             }
           }
         }
         Number max = item.getMaxOutlier();
         if (max != null) {
           double maxv = max.doubleValue();
           if (!Double.isNaN(maxv)) {
             if (maxv > this.maximumRangeValue || Double.isNaN(this.maximumRangeValue)) {
               this.maximumRangeValue = maxv;
               this.maximumRangeValueRow = r;
               this.maximumRangeValueColumn = c;
             }
           }
         }
       }
     }
   }
 }
 /**
  * Adds an item to the dataset.
  *
  * @param date the date.
  * @param item the item.
  */
 public void add(Date date, BoxAndWhiskerItem item) {
   this.dates.add(date);
   this.items.add(item);
   if (this.minimumRangeValue == null) {
     this.minimumRangeValue = item.getMinRegularValue();
   } else {
     if (item.getMinRegularValue().doubleValue() < this.minimumRangeValue.doubleValue()) {
       this.minimumRangeValue = item.getMinRegularValue();
     }
   }
   if (this.maximumRangeValue == null) {
     this.maximumRangeValue = item.getMaxRegularValue();
   } else {
     if (item.getMaxRegularValue().doubleValue() > this.maximumRangeValue.doubleValue()) {
       this.maximumRangeValue = item.getMaxRegularValue();
     }
   }
   this.rangeBounds =
       new Range(this.minimumRangeValue.doubleValue(), this.maximumRangeValue.doubleValue());
 }