/**
  * Returns the range of values the renderer requires to display all the items from the specified
  * dataset.
  *
  * @param dataset the dataset (<code>null</code> permitted).
  * @return The range (or <code>null</code> if the dataset is <code>null</code> or empty).
  */
 @Override
 public Range findRangeBounds(XYDataset dataset) {
   if (dataset == null) {
     return null;
   }
   double min = Double.POSITIVE_INFINITY;
   double max = Double.NEGATIVE_INFINITY;
   TableXYDataset d = (TableXYDataset) dataset;
   int itemCount = d.getItemCount();
   for (int i = 0; i < itemCount; i++) {
     double[] stackValues = getStackValues((TableXYDataset) dataset, d.getSeriesCount(), i);
     min = Math.min(min, stackValues[0]);
     max = Math.max(max, stackValues[1]);
   }
   if (min == Double.POSITIVE_INFINITY) {
     return null;
   }
   return new Range(min, max);
 }
 /**
  * Calculates the stacked values (one positive and one negative) of all series up to, but not
  * including, <code>series</code> for the specified item. It returns [0.0, 0.0] if <code>series
  * </code> is the first series.
  *
  * @param dataset the dataset (<code>null</code> not permitted).
  * @param series the series index.
  * @param index the item index.
  * @return An array containing the cumulative negative and positive values for all series values
  *     up to but excluding <code>series</code> for <code>index</code>.
  */
 private double[] getStackValues(TableXYDataset dataset, int series, int index) {
   double[] result = new double[2];
   for (int i = 0; i < series; i++) {
     double v = dataset.getYValue(i, index);
     if (!Double.isNaN(v)) {
       if (v >= 0.0) {
         result[1] += v;
       } else {
         result[0] += v;
       }
     }
   }
   return result;
 }