/**
   * Draw a single data item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area in which the data is drawn.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the dataset.
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   * @param pass the pass index.
   */
  public void drawItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      CategoryDataset dataset,
      int row,
      int column,
      int pass) {

    // do nothing if item is not visible
    if (!getItemVisible(row, column)) {
      return;
    }

    Number value = dataset.getValue(row, column);
    if (value == null) {
      return;
    }
    PlotOrientation orientation = plot.getOrientation();

    // current data point...
    double x1s =
        domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    double x1 =
        domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    double x1e = 2 * x1 - x1s; // or: x1s + 2*(x1-x1s)
    double y1 = rangeAxis.valueToJava2D(value.doubleValue(), dataArea, plot.getRangeAxisEdge());
    g2.setPaint(getItemPaint(row, column));
    g2.setStroke(getItemStroke(row, column));

    if (column != 0) {
      Number previousValue = dataset.getValue(row, column - 1);
      if (previousValue != null) {
        // previous data point...
        double previous = previousValue.doubleValue();
        double x0s =
            domainAxis.getCategoryStart(
                column - 1, getColumnCount(), dataArea, plot.getDomainAxisEdge());
        double x0 =
            domainAxis.getCategoryMiddle(
                column - 1, getColumnCount(), dataArea, plot.getDomainAxisEdge());
        double x0e = 2 * x0 - x0s; // or: x0s + 2*(x0-x0s)
        double y0 = rangeAxis.valueToJava2D(previous, dataArea, plot.getRangeAxisEdge());
        if (getStagger()) {
          int xStagger = row * STAGGER_WIDTH;
          if (xStagger > (x1s - x0e)) {
            xStagger = (int) (x1s - x0e);
          }
          x1s = x0e + xStagger;
        }
        drawLine(g2, (State) state, orientation, x0e, y0, x1s, y0);
        // extend x0's flat bar

        drawLine(g2, (State) state, orientation, x1s, y0, x1s, y1);
        // upright bar
      }
    }
    drawLine(g2, (State) state, orientation, x1s, y1, x1e, y1);
    // x1's flat bar

    // draw the item labels if there are any...
    if (isItemLabelVisible(row, column)) {
      drawItemLabel(g2, orientation, dataset, row, column, x1, y1, (value.doubleValue() < 0.0));
    }

    // add an item entity, if this information is being collected
    EntityCollection entities = state.getEntityCollection();
    if (entities != null) {
      Rectangle2D hotspot = new Rectangle2D.Double();
      if (orientation == PlotOrientation.VERTICAL) {
        hotspot.setRect(x1s, y1, x1e - x1s, 4.0);
      } else {
        hotspot.setRect(y1 - 2.0, x1s, 4.0, x1e - x1s);
      }
      addItemEntity(entities, dataset, row, column, hotspot);
    }
  }
  /**
   * Draws the visual representation of a single data item when the plot has a horizontal
   * orientation.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area within which the plot is being drawn.
   * @param plot the plot (can be used to obtain standard color information etc).
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the dataset (must be an instance of {@link BoxAndWhiskerCategoryDataset}).
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   */
  public void drawHorizontalItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      CategoryDataset dataset,
      int row,
      int column) {

    BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset;

    double categoryEnd =
        domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    double categoryStart =
        domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    double categoryWidth = Math.abs(categoryEnd - categoryStart);

    double yy = categoryStart;
    int seriesCount = getRowCount();
    int categoryCount = getColumnCount();

    if (seriesCount > 1) {
      double seriesGap =
          dataArea.getHeight() * getItemMargin() / (categoryCount * (seriesCount - 1));
      double usedWidth = (state.getBarWidth() * seriesCount) + (seriesGap * (seriesCount - 1));
      // offset the start of the boxes if the total width used is smaller
      // than the category width
      double offset = (categoryWidth - usedWidth) / 2;
      yy = yy + offset + (row * (state.getBarWidth() + seriesGap));
    } else {
      // offset the start of the box if the box width is smaller than
      // the category width
      double offset = (categoryWidth - state.getBarWidth()) / 2;
      yy = yy + offset;
    }

    g2.setPaint(getItemPaint(row, column));
    Stroke s = getItemStroke(row, column);
    g2.setStroke(s);

    RectangleEdge location = plot.getRangeAxisEdge();

    Number xQ1 = bawDataset.getQ1Value(row, column);
    Number xQ3 = bawDataset.getQ3Value(row, column);
    Number xMax = bawDataset.getMaxRegularValue(row, column);
    Number xMin = bawDataset.getMinRegularValue(row, column);

    Shape box = null;
    if (xQ1 != null && xQ3 != null && xMax != null && xMin != null) {

      double xxQ1 = rangeAxis.valueToJava2D(xQ1.doubleValue(), dataArea, location);
      double xxQ3 = rangeAxis.valueToJava2D(xQ3.doubleValue(), dataArea, location);
      double xxMax = rangeAxis.valueToJava2D(xMax.doubleValue(), dataArea, location);
      double xxMin = rangeAxis.valueToJava2D(xMin.doubleValue(), dataArea, location);
      double yymid = yy + state.getBarWidth() / 2.0;

      // draw the upper shadow...
      g2.draw(new Line2D.Double(xxMax, yymid, xxQ3, yymid));
      g2.draw(new Line2D.Double(xxMax, yy, xxMax, yy + state.getBarWidth()));

      // draw the lower shadow...
      g2.draw(new Line2D.Double(xxMin, yymid, xxQ1, yymid));
      g2.draw(new Line2D.Double(xxMin, yy, xxMin, yy + state.getBarWidth()));

      // draw the box...
      box =
          new Rectangle2D.Double(
              Math.min(xxQ1, xxQ3), yy, Math.abs(xxQ1 - xxQ3), state.getBarWidth());
      if (this.fillBox) {
        g2.fill(box);
      }
      g2.setStroke(getItemOutlineStroke(row, column));
      g2.setPaint(getItemOutlinePaint(row, column));
      g2.draw(box);
    }

    g2.setPaint(this.artifactPaint);
    double aRadius = 0; // average radius

    // draw mean - SPECIAL AIMS REQUIREMENT...
    Number xMean = bawDataset.getMeanValue(row, column);
    if (xMean != null) {
      double xxMean = rangeAxis.valueToJava2D(xMean.doubleValue(), dataArea, location);
      aRadius = state.getBarWidth() / 4;
      // here we check that the average marker will in fact be visible
      // before drawing it...
      if ((xxMean > (dataArea.getMinX() - aRadius)) && (xxMean < (dataArea.getMaxX() + aRadius))) {
        Ellipse2D.Double avgEllipse =
            new Ellipse2D.Double(xxMean - aRadius, yy + aRadius, aRadius * 2, aRadius * 2);
        g2.fill(avgEllipse);
        g2.draw(avgEllipse);
      }
    }

    // draw median...
    Number xMedian = bawDataset.getMedianValue(row, column);
    if (xMedian != null) {
      double xxMedian = rangeAxis.valueToJava2D(xMedian.doubleValue(), dataArea, location);
      g2.draw(new Line2D.Double(xxMedian, yy, xxMedian, yy + state.getBarWidth()));
    }

    // collect entity and tool tip information...
    if (state.getInfo() != null && box != null) {
      EntityCollection entities = state.getEntityCollection();
      if (entities != null) {
        addItemEntity(entities, dataset, row, column, box);
      }
    }
  }
  /**
   * Draws the visual representation of a single data item when the plot has a vertical orientation.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area within which the plot is being drawn.
   * @param plot the plot (can be used to obtain standard color information etc).
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the dataset (must be an instance of {@link BoxAndWhiskerCategoryDataset}).
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   */
  public void drawVerticalItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      CategoryDataset dataset,
      int row,
      int column) {

    BoxAndWhiskerCategoryDataset bawDataset = (BoxAndWhiskerCategoryDataset) dataset;

    double categoryEnd =
        domainAxis.getCategoryEnd(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    double categoryStart =
        domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    double categoryWidth = categoryEnd - categoryStart;

    double xx = categoryStart;
    int seriesCount = getRowCount();
    int categoryCount = getColumnCount();

    if (seriesCount > 1) {
      double seriesGap =
          dataArea.getWidth() * getItemMargin() / (categoryCount * (seriesCount - 1));
      double usedWidth = (state.getBarWidth() * seriesCount) + (seriesGap * (seriesCount - 1));
      // offset the start of the boxes if the total width used is smaller
      // than the category width
      double offset = (categoryWidth - usedWidth) / 2;
      xx = xx + offset + (row * (state.getBarWidth() + seriesGap));
    } else {
      // offset the start of the box if the box width is smaller than the
      // category width
      double offset = (categoryWidth - state.getBarWidth()) / 2;
      xx = xx + offset;
    }

    double yyAverage = 0.0;
    double yyOutlier;

    Paint itemPaint = getItemPaint(row, column);
    g2.setPaint(itemPaint);
    Stroke s = getItemStroke(row, column);
    g2.setStroke(s);

    double aRadius = 0; // average radius

    RectangleEdge location = plot.getRangeAxisEdge();

    Number yQ1 = bawDataset.getQ1Value(row, column);
    Number yQ3 = bawDataset.getQ3Value(row, column);
    Number yMax = bawDataset.getMaxRegularValue(row, column);
    Number yMin = bawDataset.getMinRegularValue(row, column);
    Shape box = null;
    if (yQ1 != null && yQ3 != null && yMax != null && yMin != null) {

      double yyQ1 = rangeAxis.valueToJava2D(yQ1.doubleValue(), dataArea, location);
      double yyQ3 = rangeAxis.valueToJava2D(yQ3.doubleValue(), dataArea, location);
      double yyMax = rangeAxis.valueToJava2D(yMax.doubleValue(), dataArea, location);
      double yyMin = rangeAxis.valueToJava2D(yMin.doubleValue(), dataArea, location);
      double xxmid = xx + state.getBarWidth() / 2.0;

      // draw the upper shadow...
      g2.draw(new Line2D.Double(xxmid, yyMax, xxmid, yyQ3));
      g2.draw(new Line2D.Double(xx, yyMax, xx + state.getBarWidth(), yyMax));

      // draw the lower shadow...
      g2.draw(new Line2D.Double(xxmid, yyMin, xxmid, yyQ1));
      g2.draw(new Line2D.Double(xx, yyMin, xx + state.getBarWidth(), yyMin));

      // draw the body...
      box =
          new Rectangle2D.Double(
              xx, Math.min(yyQ1, yyQ3), state.getBarWidth(), Math.abs(yyQ1 - yyQ3));
      if (this.fillBox) {
        g2.fill(box);
      }
      g2.setStroke(getItemOutlineStroke(row, column));
      g2.setPaint(getItemOutlinePaint(row, column));
      g2.draw(box);
    }

    g2.setPaint(this.artifactPaint);

    // draw mean - SPECIAL AIMS REQUIREMENT...
    Number yMean = bawDataset.getMeanValue(row, column);
    if (yMean != null) {
      yyAverage = rangeAxis.valueToJava2D(yMean.doubleValue(), dataArea, location);
      aRadius = state.getBarWidth() / 4;
      // here we check that the average marker will in fact be visible
      // before drawing it...
      if ((yyAverage > (dataArea.getMinY() - aRadius))
          && (yyAverage < (dataArea.getMaxY() + aRadius))) {
        Ellipse2D.Double avgEllipse =
            new Ellipse2D.Double(xx + aRadius, yyAverage - aRadius, aRadius * 2, aRadius * 2);
        g2.fill(avgEllipse);
        g2.draw(avgEllipse);
      }
    }

    // draw median...
    Number yMedian = bawDataset.getMedianValue(row, column);
    if (yMedian != null) {
      double yyMedian = rangeAxis.valueToJava2D(yMedian.doubleValue(), dataArea, location);
      g2.draw(new Line2D.Double(xx, yyMedian, xx + state.getBarWidth(), yyMedian));
    }

    // draw yOutliers...
    double maxAxisValue =
        rangeAxis.valueToJava2D(rangeAxis.getUpperBound(), dataArea, location) + aRadius;
    double minAxisValue =
        rangeAxis.valueToJava2D(rangeAxis.getLowerBound(), dataArea, location) - aRadius;

    g2.setPaint(itemPaint);

    // draw outliers
    double oRadius = state.getBarWidth() / 3; // outlier radius
    List outliers = new ArrayList();
    OutlierListCollection outlierListCollection = new OutlierListCollection();

    // From outlier array sort out which are outliers and put these into a
    // list If there are any farouts, set the flag on the
    // OutlierListCollection
    List yOutliers = bawDataset.getOutliers(row, column);
    if (yOutliers != null) {
      for (int i = 0; i < yOutliers.size(); i++) {
        double outlier = ((Number) yOutliers.get(i)).doubleValue();
        Number minOutlier = bawDataset.getMinOutlier(row, column);
        Number maxOutlier = bawDataset.getMaxOutlier(row, column);
        Number minRegular = bawDataset.getMinRegularValue(row, column);
        Number maxRegular = bawDataset.getMaxRegularValue(row, column);
        if (outlier > maxOutlier.doubleValue()) {
          outlierListCollection.setHighFarOut(true);
        } else if (outlier < minOutlier.doubleValue()) {
          outlierListCollection.setLowFarOut(true);
        } else if (outlier > maxRegular.doubleValue()) {
          yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location);
          outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius));
        } else if (outlier < minRegular.doubleValue()) {
          yyOutlier = rangeAxis.valueToJava2D(outlier, dataArea, location);
          outliers.add(new Outlier(xx + state.getBarWidth() / 2.0, yyOutlier, oRadius));
        }
        Collections.sort(outliers);
      }

      // Process outliers. Each outlier is either added to the
      // appropriate outlier list or a new outlier list is made
      for (Iterator iterator = outliers.iterator(); iterator.hasNext(); ) {
        Outlier outlier = (Outlier) iterator.next();
        outlierListCollection.add(outlier);
      }

      for (Iterator iterator = outlierListCollection.iterator(); iterator.hasNext(); ) {
        OutlierList list = (OutlierList) iterator.next();
        Outlier outlier = list.getAveragedOutlier();
        Point2D point = outlier.getPoint();

        if (list.isMultiple()) {
          drawMultipleEllipse(point, state.getBarWidth(), oRadius, g2);
        } else {
          drawEllipse(point, oRadius, g2);
        }
      }

      // draw farout indicators
      if (outlierListCollection.isHighFarOut()) {
        drawHighFarOut(aRadius / 2.0, g2, xx + state.getBarWidth() / 2.0, maxAxisValue);
      }

      if (outlierListCollection.isLowFarOut()) {
        drawLowFarOut(aRadius / 2.0, g2, xx + state.getBarWidth() / 2.0, minAxisValue);
      }
    }
    // collect entity and tool tip information...
    if (state.getInfo() != null && box != null) {
      EntityCollection entities = state.getEntityCollection();
      if (entities != null) {
        addItemEntity(entities, dataset, row, column, box);
      }
    }
  }
  /**
   * Draw a single data item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area in which the data is drawn.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the dataset (a {@link StatisticalCategoryDataset} is required).
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   * @param pass the pass.
   */
  @Override
  public void drawItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      CategoryDataset dataset,
      int row,
      int column,
      int pass) {

    // do nothing if item is not visible
    if (!getItemVisible(row, column)) {
      return;
    }

    // if the dataset is not a StatisticalCategoryDataset then just revert
    // to the superclass (LineAndShapeRenderer) behaviour...
    if (!(dataset instanceof StatisticalCategoryDataset)) {
      super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column, pass);
      return;
    }

    int visibleRow = state.getVisibleSeriesIndex(row);
    if (visibleRow < 0) {
      return;
    }
    int visibleRowCount = state.getVisibleSeriesCount();

    StatisticalCategoryDataset statDataset = (StatisticalCategoryDataset) dataset;
    Number meanValue = statDataset.getMeanValue(row, column);
    if (meanValue == null) {
      return;
    }
    PlotOrientation orientation = plot.getOrientation();

    // current data point...
    double x1;
    if (getUseSeriesOffset()) {
      x1 =
          domainAxis.getCategorySeriesMiddle(
              column,
              dataset.getColumnCount(),
              visibleRow,
              visibleRowCount,
              getItemMargin(),
              dataArea,
              plot.getDomainAxisEdge());
    } else {
      x1 =
          domainAxis.getCategoryMiddle(
              column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
    }
    double y1 = rangeAxis.valueToJava2D(meanValue.doubleValue(), dataArea, plot.getRangeAxisEdge());

    // draw the standard deviation lines *before* the shapes (if they're
    // visible) - it looks better if the shape fill colour is different to
    // the line colour
    Number sdv = statDataset.getStdDevValue(row, column);
    if (pass == 1 && sdv != null) {
      // standard deviation lines
      RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
      double valueDelta = sdv.doubleValue();
      double highVal, lowVal;
      if ((meanValue.doubleValue() + valueDelta) > rangeAxis.getRange().getUpperBound()) {
        highVal =
            rangeAxis.valueToJava2D(rangeAxis.getRange().getUpperBound(), dataArea, yAxisLocation);
      } else {
        highVal =
            rangeAxis.valueToJava2D(meanValue.doubleValue() + valueDelta, dataArea, yAxisLocation);
      }

      if ((meanValue.doubleValue() + valueDelta) < rangeAxis.getRange().getLowerBound()) {
        lowVal =
            rangeAxis.valueToJava2D(rangeAxis.getRange().getLowerBound(), dataArea, yAxisLocation);
      } else {
        lowVal =
            rangeAxis.valueToJava2D(meanValue.doubleValue() - valueDelta, dataArea, yAxisLocation);
      }

      if (this.errorIndicatorPaint != null) {
        g2.setPaint(this.errorIndicatorPaint);
      } else {
        g2.setPaint(getItemPaint(row, column));
      }
      if (this.errorIndicatorStroke != null) {
        g2.setStroke(this.errorIndicatorStroke);
      } else {
        g2.setStroke(getItemOutlineStroke(row, column));
      }
      Line2D line = new Line2D.Double();
      if (orientation == PlotOrientation.HORIZONTAL) {
        line.setLine(lowVal, x1, highVal, x1);
        g2.draw(line);
        line.setLine(lowVal, x1 - 5.0d, lowVal, x1 + 5.0d);
        g2.draw(line);
        line.setLine(highVal, x1 - 5.0d, highVal, x1 + 5.0d);
        g2.draw(line);
      } else { // PlotOrientation.VERTICAL
        line.setLine(x1, lowVal, x1, highVal);
        g2.draw(line);
        line.setLine(x1 - 5.0d, highVal, x1 + 5.0d, highVal);
        g2.draw(line);
        line.setLine(x1 - 5.0d, lowVal, x1 + 5.0d, lowVal);
        g2.draw(line);
      }
    }

    Shape hotspot = null;
    if (pass == 1 && getItemShapeVisible(row, column)) {
      Shape shape = getItemShape(row, column);
      if (orientation == PlotOrientation.HORIZONTAL) {
        shape = ShapeUtilities.createTranslatedShape(shape, y1, x1);
      } else if (orientation == PlotOrientation.VERTICAL) {
        shape = ShapeUtilities.createTranslatedShape(shape, x1, y1);
      }
      hotspot = shape;

      if (getItemShapeFilled(row, column)) {
        if (getUseFillPaint()) {
          g2.setPaint(getItemFillPaint(row, column));
        } else {
          g2.setPaint(getItemPaint(row, column));
        }
        g2.fill(shape);
      }
      if (getDrawOutlines()) {
        if (getUseOutlinePaint()) {
          g2.setPaint(getItemOutlinePaint(row, column));
        } else {
          g2.setPaint(getItemPaint(row, column));
        }
        g2.setStroke(getItemOutlineStroke(row, column));
        g2.draw(shape);
      }
      // draw the item label if there is one...
      if (isItemLabelVisible(row, column)) {
        if (orientation == PlotOrientation.HORIZONTAL) {
          drawItemLabel(
              g2, orientation, dataset, row, column, y1, x1, (meanValue.doubleValue() < 0.0));
        } else if (orientation == PlotOrientation.VERTICAL) {
          drawItemLabel(
              g2, orientation, dataset, row, column, x1, y1, (meanValue.doubleValue() < 0.0));
        }
      }
    }

    if (pass == 0 && getItemLineVisible(row, column)) {
      if (column != 0) {

        Number previousValue = statDataset.getValue(row, column - 1);
        if (previousValue != null) {

          // previous data point...
          double previous = previousValue.doubleValue();
          double x0;
          if (getUseSeriesOffset()) {
            x0 =
                domainAxis.getCategorySeriesMiddle(
                    column - 1,
                    dataset.getColumnCount(),
                    visibleRow,
                    visibleRowCount,
                    getItemMargin(),
                    dataArea,
                    plot.getDomainAxisEdge());
          } else {
            x0 =
                domainAxis.getCategoryMiddle(
                    column - 1, getColumnCount(), dataArea, plot.getDomainAxisEdge());
          }
          double y0 = rangeAxis.valueToJava2D(previous, dataArea, plot.getRangeAxisEdge());

          Line2D line = null;
          if (orientation == PlotOrientation.HORIZONTAL) {
            line = new Line2D.Double(y0, x0, y1, x1);
          } else if (orientation == PlotOrientation.VERTICAL) {
            line = new Line2D.Double(x0, y0, x1, y1);
          }
          g2.setPaint(getItemPaint(row, column));
          g2.setStroke(getItemStroke(row, column));
          g2.draw(line);
        }
      }
    }

    if (pass == 1) {
      // add an item entity, if this information is being collected
      EntityCollection entities = state.getEntityCollection();
      if (entities != null) {
        addEntity(entities, hotspot, dataset, row, column, x1, y1);
      }
    }
  }
Beispiel #5
0
  /**
   * Draw a single data item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area in which the data is drawn.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the dataset.
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   * @param pass the pass index.
   */
  @Override
  public void drawItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      CategoryDataset dataset,
      int row,
      int column,
      int pass) {

    if (!getItemVisible(row, column)) {
      return;
    }

    // nothing is drawn for null...
    Number v = dataset.getValue(row, column);
    if (v == null) {
      return;
    }

    Rectangle2D adjusted =
        new Rectangle2D.Double(
            dataArea.getX(),
            dataArea.getY() + getYOffset(),
            dataArea.getWidth() - getXOffset(),
            dataArea.getHeight() - getYOffset());

    PlotOrientation orientation = plot.getOrientation();

    // current data point...
    double x1 =
        domainAxis.getCategoryMiddle(column, getColumnCount(), adjusted, plot.getDomainAxisEdge());
    double value = v.doubleValue();
    double y1 = rangeAxis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());

    Shape shape = getItemShape(row, column);
    if (orientation == PlotOrientation.HORIZONTAL) {
      shape = ShapeUtilities.createTranslatedShape(shape, y1, x1);
    } else if (orientation == PlotOrientation.VERTICAL) {
      shape = ShapeUtilities.createTranslatedShape(shape, x1, y1);
    }

    if (pass == 0 && getItemLineVisible(row, column)) {
      if (column != 0) {

        Number previousValue = dataset.getValue(row, column - 1);
        if (previousValue != null) {

          // previous data point...
          double previous = previousValue.doubleValue();
          double x0 =
              domainAxis.getCategoryMiddle(
                  column - 1, getColumnCount(), adjusted, plot.getDomainAxisEdge());
          double y0 = rangeAxis.valueToJava2D(previous, adjusted, plot.getRangeAxisEdge());

          double x2 = x0 + getXOffset();
          double y2 = y0 - getYOffset();
          double x3 = x1 + getXOffset();
          double y3 = y1 - getYOffset();

          GeneralPath clip = new GeneralPath();

          if (orientation == PlotOrientation.HORIZONTAL) {
            clip.moveTo((float) y0, (float) x0);
            clip.lineTo((float) y1, (float) x1);
            clip.lineTo((float) y3, (float) x3);
            clip.lineTo((float) y2, (float) x2);
            clip.lineTo((float) y0, (float) x0);
            clip.closePath();
          } else if (orientation == PlotOrientation.VERTICAL) {
            clip.moveTo((float) x0, (float) y0);
            clip.lineTo((float) x1, (float) y1);
            clip.lineTo((float) x3, (float) y3);
            clip.lineTo((float) x2, (float) y2);
            clip.lineTo((float) x0, (float) y0);
            clip.closePath();
          }

          g2.setPaint(getItemPaint(row, column));
          g2.fill(clip);
          g2.setStroke(getItemOutlineStroke(row, column));
          g2.setPaint(getItemOutlinePaint(row, column));
          g2.draw(clip);
        }
      }
    }

    // draw the item label if there is one...
    if (pass == 1 && isItemLabelVisible(row, column)) {
      if (orientation == PlotOrientation.HORIZONTAL) {
        drawItemLabel(g2, orientation, dataset, row, column, y1, x1, (value < 0.0));
      } else if (orientation == PlotOrientation.VERTICAL) {
        drawItemLabel(g2, orientation, dataset, row, column, x1, y1, (value < 0.0));
      }
    }

    // add an item entity, if this information is being collected
    EntityCollection entities = state.getEntityCollection();
    if (entities != null) {
      addItemEntity(entities, dataset, row, column, shape);
    }
  }
Beispiel #6
0
  /**
   * Draws a single task.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the data plot area.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the data.
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   */
  protected void drawTask(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      GanttCategoryDataset dataset,
      int row,
      int column) {

    PlotOrientation orientation = plot.getOrientation();
    RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();

    // Y0
    Number value0 = dataset.getEndValue(row, column);
    if (value0 == null) {
      return;
    }
    double java2dValue0 =
        rangeAxis.valueToJava2D(value0.doubleValue(), dataArea, rangeAxisLocation);

    // Y1
    Number value1 = dataset.getStartValue(row, column);
    if (value1 == null) {
      return;
    }
    double java2dValue1 =
        rangeAxis.valueToJava2D(value1.doubleValue(), dataArea, rangeAxisLocation);

    if (java2dValue1 < java2dValue0) {
      double temp = java2dValue1;
      java2dValue1 = java2dValue0;
      java2dValue0 = temp;
      value1 = value0;
    }

    double rectStart = calculateBarW0(plot, orientation, dataArea, domainAxis, state, row, column);
    double rectBreadth = state.getBarWidth();
    double rectLength = Math.abs(java2dValue1 - java2dValue0);

    Rectangle2D bar = null;
    RectangleEdge barBase = null;
    if (orientation == PlotOrientation.HORIZONTAL) {
      bar = new Rectangle2D.Double(java2dValue0, rectStart, rectLength, rectBreadth);
      barBase = RectangleEdge.LEFT;
    } else if (orientation == PlotOrientation.VERTICAL) {
      bar = new Rectangle2D.Double(rectStart, java2dValue1, rectBreadth, rectLength);
      barBase = RectangleEdge.BOTTOM;
    }

    Rectangle2D completeBar = null;
    Rectangle2D incompleteBar = null;
    Number percent = dataset.getPercentComplete(row, column);
    double start = getStartPercent();
    double end = getEndPercent();
    if (percent != null) {
      double p = percent.doubleValue();
      if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
        completeBar =
            new Rectangle2D.Double(
                java2dValue0,
                rectStart + start * rectBreadth,
                rectLength * p,
                rectBreadth * (end - start));
        incompleteBar =
            new Rectangle2D.Double(
                java2dValue0 + rectLength * p,
                rectStart + start * rectBreadth,
                rectLength * (1 - p),
                rectBreadth * (end - start));
      } else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
        completeBar =
            new Rectangle2D.Double(
                rectStart + start * rectBreadth,
                java2dValue1 + rectLength * (1 - p),
                rectBreadth * (end - start),
                rectLength * p);
        incompleteBar =
            new Rectangle2D.Double(
                rectStart + start * rectBreadth,
                java2dValue1,
                rectBreadth * (end - start),
                rectLength * (1 - p));
      }
    }

    if (getShadowsVisible()) {
      getBarPainter().paintBarShadow(g2, this, row, column, bar, barBase, true);
    }
    getBarPainter().paintBar(g2, this, row, column, bar, barBase);

    if (completeBar != null) {
      g2.setPaint(getCompletePaint());
      g2.fill(completeBar);
    }
    if (incompleteBar != null) {
      g2.setPaint(getIncompletePaint());
      g2.fill(incompleteBar);
    }

    // draw the outline...
    if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
      Stroke stroke = getItemOutlineStroke(row, column);
      Paint paint = getItemOutlinePaint(row, column);
      if (stroke != null && paint != null) {
        g2.setStroke(stroke);
        g2.setPaint(paint);
        g2.draw(bar);
      }
    }

    CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
    if (generator != null && isItemLabelVisible(row, column)) {
      drawItemLabel(g2, dataset, row, column, plot, generator, bar, false);
    }

    // submit the current data point as a crosshair candidate
    int datasetIndex = plot.indexOf(dataset);
    Comparable columnKey = dataset.getColumnKey(column);
    Comparable rowKey = dataset.getRowKey(row);
    double xx =
        domainAxis.getCategorySeriesMiddle(
            columnKey, rowKey, dataset, getItemMargin(), dataArea, plot.getDomainAxisEdge());
    updateCrosshairValues(
        state.getCrosshairState(),
        dataset.getRowKey(row),
        dataset.getColumnKey(column),
        value1.doubleValue(),
        datasetIndex,
        xx,
        java2dValue1,
        orientation);

    // collect entity and tool tip information...
    EntityCollection entities = state.getEntityCollection();
    if (entities != null) {
      addItemEntity(entities, dataset, row, column, bar);
    }
  }
Beispiel #7
0
  /**
   * Draws the tasks/subtasks for one item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the data plot area.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the data.
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   */
  protected void drawTasks(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      GanttCategoryDataset dataset,
      int row,
      int column) {

    int count = dataset.getSubIntervalCount(row, column);
    if (count == 0) {
      drawTask(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column);
    }

    PlotOrientation orientation = plot.getOrientation();
    for (int subinterval = 0; subinterval < count; subinterval++) {

      RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();

      // value 0
      Number value0 = dataset.getStartValue(row, column, subinterval);
      if (value0 == null) {
        return;
      }
      double translatedValue0 =
          rangeAxis.valueToJava2D(value0.doubleValue(), dataArea, rangeAxisLocation);

      // value 1
      Number value1 = dataset.getEndValue(row, column, subinterval);
      if (value1 == null) {
        return;
      }
      double translatedValue1 =
          rangeAxis.valueToJava2D(value1.doubleValue(), dataArea, rangeAxisLocation);

      if (translatedValue1 < translatedValue0) {
        double temp = translatedValue1;
        translatedValue1 = translatedValue0;
        translatedValue0 = temp;
      }

      double rectStart =
          calculateBarW0(plot, plot.getOrientation(), dataArea, domainAxis, state, row, column);
      double rectLength = Math.abs(translatedValue1 - translatedValue0);
      double rectBreadth = state.getBarWidth();

      // DRAW THE BARS...
      Rectangle2D bar = null;
      RectangleEdge barBase = null;
      if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
        bar = new Rectangle2D.Double(translatedValue0, rectStart, rectLength, rectBreadth);
        barBase = RectangleEdge.LEFT;
      } else if (plot.getOrientation() == PlotOrientation.VERTICAL) {
        bar = new Rectangle2D.Double(rectStart, translatedValue0, rectBreadth, rectLength);
        barBase = RectangleEdge.BOTTOM;
      }

      Rectangle2D completeBar = null;
      Rectangle2D incompleteBar = null;
      Number percent = dataset.getPercentComplete(row, column, subinterval);
      double start = getStartPercent();
      double end = getEndPercent();
      if (percent != null) {
        double p = percent.doubleValue();
        if (orientation == PlotOrientation.HORIZONTAL) {
          completeBar =
              new Rectangle2D.Double(
                  translatedValue0,
                  rectStart + start * rectBreadth,
                  rectLength * p,
                  rectBreadth * (end - start));
          incompleteBar =
              new Rectangle2D.Double(
                  translatedValue0 + rectLength * p,
                  rectStart + start * rectBreadth,
                  rectLength * (1 - p),
                  rectBreadth * (end - start));
        } else if (orientation == PlotOrientation.VERTICAL) {
          completeBar =
              new Rectangle2D.Double(
                  rectStart + start * rectBreadth,
                  translatedValue0 + rectLength * (1 - p),
                  rectBreadth * (end - start),
                  rectLength * p);
          incompleteBar =
              new Rectangle2D.Double(
                  rectStart + start * rectBreadth,
                  translatedValue0,
                  rectBreadth * (end - start),
                  rectLength * (1 - p));
        }
      }

      if (getShadowsVisible()) {
        getBarPainter().paintBarShadow(g2, this, row, column, bar, barBase, true);
      }
      getBarPainter().paintBar(g2, this, row, column, bar, barBase);

      if (completeBar != null) {
        g2.setPaint(getCompletePaint());
        g2.fill(completeBar);
      }
      if (incompleteBar != null) {
        g2.setPaint(getIncompletePaint());
        g2.fill(incompleteBar);
      }
      if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
        g2.setStroke(getItemStroke(row, column));
        g2.setPaint(getItemOutlinePaint(row, column));
        g2.draw(bar);
      }

      if (subinterval == count - 1) {
        // submit the current data point as a crosshair candidate
        int datasetIndex = plot.indexOf(dataset);
        Comparable columnKey = dataset.getColumnKey(column);
        Comparable rowKey = dataset.getRowKey(row);
        double xx =
            domainAxis.getCategorySeriesMiddle(
                columnKey, rowKey, dataset, getItemMargin(), dataArea, plot.getDomainAxisEdge());
        updateCrosshairValues(
            state.getCrosshairState(),
            dataset.getRowKey(row),
            dataset.getColumnKey(column),
            value1.doubleValue(),
            datasetIndex,
            xx,
            translatedValue1,
            orientation);
      }
      // collect entity and tool tip information...
      if (state.getInfo() != null) {
        EntityCollection entities = state.getEntityCollection();
        if (entities != null) {
          addItemEntity(entities, dataset, row, column, bar);
        }
      }
    }
  }
  /**
   * Draw a single data item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the data plot area.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the dataset.
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   * @param pass the pass index.
   */
  @Override
  public void drawItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      CategoryDataset dataset,
      int row,
      int column,
      int pass) {

    // do nothing if item is not visible or null
    if (!getItemVisible(row, column)) {
      return;
    }
    Number value = dataset.getValue(row, column);
    if (value == null) {
      return;
    }
    PlotOrientation orientation = plot.getOrientation();
    RectangleEdge axisEdge = plot.getDomainAxisEdge();
    int count = dataset.getColumnCount();
    float x0 = (float) domainAxis.getCategoryStart(column, count, dataArea, axisEdge);
    float x1 = (float) domainAxis.getCategoryMiddle(column, count, dataArea, axisEdge);
    float x2 = (float) domainAxis.getCategoryEnd(column, count, dataArea, axisEdge);

    x0 = Math.round(x0);
    x1 = Math.round(x1);
    x2 = Math.round(x2);

    if (this.endType == AreaRendererEndType.TRUNCATE) {
      if (column == 0) {
        x0 = x1;
      } else if (column == getColumnCount() - 1) {
        x2 = x1;
      }
    }

    double yy1 = value.doubleValue();

    double yy0 = 0.0;
    if (this.endType == AreaRendererEndType.LEVEL) {
      yy0 = yy1;
    }
    if (column > 0) {
      Number n0 = dataset.getValue(row, column - 1);
      if (n0 != null) {
        yy0 = (n0.doubleValue() + yy1) / 2.0;
      }
    }

    double yy2 = 0.0;
    if (column < dataset.getColumnCount() - 1) {
      Number n2 = dataset.getValue(row, column + 1);
      if (n2 != null) {
        yy2 = (n2.doubleValue() + yy1) / 2.0;
      }
    } else if (this.endType == AreaRendererEndType.LEVEL) {
      yy2 = yy1;
    }

    RectangleEdge edge = plot.getRangeAxisEdge();
    float y0 = (float) rangeAxis.valueToJava2D(yy0, dataArea, edge);
    float y1 = (float) rangeAxis.valueToJava2D(yy1, dataArea, edge);
    float y2 = (float) rangeAxis.valueToJava2D(yy2, dataArea, edge);
    float yz = (float) rangeAxis.valueToJava2D(0.0, dataArea, edge);
    double labelXX = x1;
    double labelYY = y1;
    g2.setPaint(getItemPaint(row, column));
    g2.setStroke(getItemStroke(row, column));

    GeneralPath area = new GeneralPath();

    if (orientation == PlotOrientation.VERTICAL) {
      area.moveTo(x0, yz);
      area.lineTo(x0, y0);
      area.lineTo(x1, y1);
      area.lineTo(x2, y2);
      area.lineTo(x2, yz);
    } else if (orientation == PlotOrientation.HORIZONTAL) {
      area.moveTo(yz, x0);
      area.lineTo(y0, x0);
      area.lineTo(y1, x1);
      area.lineTo(y2, x2);
      area.lineTo(yz, x2);
      double temp = labelXX;
      labelXX = labelYY;
      labelYY = temp;
    }
    area.closePath();

    g2.setPaint(getItemPaint(row, column));
    g2.fill(area);

    // draw the item labels if there are any...
    if (isItemLabelVisible(row, column)) {
      drawItemLabel(
          g2, orientation, dataset, row, column, labelXX, labelYY, (value.doubleValue() < 0.0));
    }

    // submit the current data point as a crosshair candidate
    int datasetIndex = plot.indexOf(dataset);
    updateCrosshairValues(
        state.getCrosshairState(),
        dataset.getRowKey(row),
        dataset.getColumnKey(column),
        yy1,
        datasetIndex,
        x1,
        y1,
        orientation);

    // add an item entity, if this information is being collected
    EntityCollection entities = state.getEntityCollection();
    if (entities != null) {
      addItemEntity(entities, dataset, row, column, area);
    }
  }
  /**
   * Draws a marker for the domain axis.
   *
   * @param g2 the graphics device (not <code>null</code>).
   * @param plot the plot (not <code>null</code>).
   * @param axis the range axis (not <code>null</code>).
   * @param marker the marker to be drawn (not <code>null</code>).
   * @param dataArea the area inside the axes (not <code>null</code>).
   */
  public void drawDomainMarker(
      Graphics2D g2,
      CategoryPlot plot,
      CategoryAxis axis,
      CategoryMarker marker,
      Rectangle2D dataArea) {

    Comparable category = marker.getKey();
    CategoryDataset dataset = plot.getDataset(plot.getIndexOf(this));
    int columnIndex = dataset.getColumnIndex(category);
    if (columnIndex < 0) {
      return;
    }
    PlotOrientation orientation = plot.getOrientation();
    Rectangle2D bounds = null;
    if (marker.getDrawAsLine()) {
      double v =
          axis.getCategoryMiddle(
              columnIndex, dataset.getColumnCount(),
              dataArea, plot.getDomainAxisEdge());
      Line2D line = null;
      if (orientation == PlotOrientation.HORIZONTAL) {
        line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(), v);
      } else if (orientation == PlotOrientation.VERTICAL) {
        line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea.getMaxY());
      }

      g2.setPaint(marker.getPaint());
      g2.setStroke(marker.getStroke());
      g2.draw(line);
      bounds = line.getBounds2D();
    } else {
      double v0 =
          axis.getCategoryStart(
              columnIndex, dataset.getColumnCount(),
              dataArea, plot.getDomainAxisEdge());
      double v1 =
          axis.getCategoryEnd(
              columnIndex, dataset.getColumnCount(),
              dataArea, plot.getDomainAxisEdge());
      Rectangle2D area = null;
      if (orientation == PlotOrientation.HORIZONTAL) {
        area = new Rectangle2D.Double(dataArea.getMinX(), v0, dataArea.getWidth(), (v1 - v0));
      } else if (orientation == PlotOrientation.VERTICAL) {
        area = new Rectangle2D.Double(v0, dataArea.getMinY(), (v1 - v0), dataArea.getHeight());
      }
      g2.setPaint(marker.getPaint());
      g2.fill(area);
      bounds = area;
    }

    String label = marker.getLabel();
    RectangleAnchor anchor = marker.getLabelAnchor();
    if (label != null) {
      Font labelFont = marker.getLabelFont();
      g2.setFont(labelFont);
      g2.setPaint(marker.getLabelPaint());
      Point2D coordinates =
          calculateDomainMarkerTextAnchorPoint(
              g2,
              orientation,
              dataArea,
              bounds,
              marker.getLabelOffset(),
              marker.getLabelOffsetType(),
              anchor);
      TextUtilities.drawAlignedString(
          label,
          g2,
          (float) coordinates.getX(),
          (float) coordinates.getY(),
          marker.getLabelTextAnchor());
    }
  }
  /**
   * Draws an item for a plot with a vertical orientation.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the data area.
   * @param plot the plot.
   * @param domainAxis the domain axis.
   * @param rangeAxis the range axis.
   * @param dataset the data.
   * @param row the row index (zero-based).
   * @param column the column index (zero-based).
   */
  protected void drawVerticalItem(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      StatisticalCategoryDataset dataset,
      int row,
      int column) {

    RectangleEdge xAxisLocation = plot.getDomainAxisEdge();

    // BAR X
    double rectX = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, xAxisLocation);

    int seriesCount = getRowCount();
    int categoryCount = getColumnCount();
    if (seriesCount > 1) {
      double seriesGap =
          dataArea.getWidth() * getItemMargin() / (categoryCount * (seriesCount - 1));
      rectX = rectX + row * (state.getBarWidth() + seriesGap);
    } else {
      rectX = rectX + row * state.getBarWidth();
    }

    // BAR Y
    Number meanValue = dataset.getMeanValue(row, column);

    double value = meanValue.doubleValue();
    double base = 0.0;
    double lclip = getLowerClip();
    double uclip = getUpperClip();

    if (uclip <= 0.0) { // cases 1, 2, 3 and 4
      if (value >= uclip) {
        return; // bar is not visible
      }
      base = uclip;
      if (value <= lclip) {
        value = lclip;
      }
    } else if (lclip <= 0.0) { // cases 5, 6, 7 and 8
      if (value >= uclip) {
        value = uclip;
      } else {
        if (value <= lclip) {
          value = lclip;
        }
      }
    } else { // cases 9, 10, 11 and 12
      if (value <= lclip) {
        return; // bar is not visible
      }
      base = getLowerClip();
      if (value >= uclip) {
        value = uclip;
      }
    }

    RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
    double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation);
    double transY2 = rangeAxis.valueToJava2D(value, dataArea, yAxisLocation);
    double rectY = Math.min(transY2, transY1);

    double rectWidth = state.getBarWidth();
    double rectHeight = Math.abs(transY2 - transY1);

    Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth, rectHeight);
    Paint seriesPaint = getItemPaint(row, column);
    g2.setPaint(seriesPaint);
    g2.fill(bar);
    if (state.getBarWidth() > 3) {
      g2.setStroke(getItemStroke(row, column));
      g2.setPaint(getItemOutlinePaint(row, column));
      g2.draw(bar);
    }

    // standard deviation lines
    double valueDelta = dataset.getStdDevValue(row, column).doubleValue();
    double highVal =
        rangeAxis.valueToJava2D(meanValue.doubleValue() + valueDelta, dataArea, yAxisLocation);
    double lowVal =
        rangeAxis.valueToJava2D(meanValue.doubleValue() - valueDelta, dataArea, yAxisLocation);

    if (this.errorIndicatorPaint != null) {
      g2.setPaint(this.errorIndicatorPaint);
    } else {
      g2.setPaint(getItemOutlinePaint(row, column));
    }
    Line2D line = null;
    line =
        new Line2D.Double(
            rectX + rectWidth / 2.0d, lowVal,
            rectX + rectWidth / 2.0d, highVal);
    g2.draw(line);
    line =
        new Line2D.Double(
            rectX + rectWidth / 2.0d - 5.0d, highVal, rectX + rectWidth / 2.0d + 5.0d, highVal);
    g2.draw(line);
    line =
        new Line2D.Double(
            rectX + rectWidth / 2.0d - 5.0d, lowVal, rectX + rectWidth / 2.0d + 5.0d, lowVal);
    g2.draw(line);

    CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
    if (generator != null && isItemLabelVisible(row, column)) {
      drawItemLabel(g2, dataset, row, column, plot, generator, bar, (value < 0.0));
    }

    // add an item entity, if this information is being collected
    EntityCollection entities = state.getEntityCollection();
    if (entities != null) {
      addItemEntity(entities, dataset, row, column, bar);
    }
  }