/**
   * Draws a grid line against the domain axis.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
   * @param value the Java2D value at which the grid line should be drawn.
   */
  public void drawDomainGridline(
      Graphics2D g2, CategoryPlot plot, Rectangle2D dataArea, double value) {

    Line2D line1 = null;
    Line2D line2 = null;
    PlotOrientation orientation = plot.getOrientation();
    if (orientation == PlotOrientation.HORIZONTAL) {
      double y0 = value;
      double y1 = value - getYOffset();
      double x0 = dataArea.getMinX();
      double x1 = x0 + getXOffset();
      double x2 = dataArea.getMaxX();
      line1 = new Line2D.Double(x0, y0, x1, y1);
      line2 = new Line2D.Double(x1, y1, x2, y1);
    } else if (orientation == PlotOrientation.VERTICAL) {
      double x0 = value;
      double x1 = value + getXOffset();
      double y0 = dataArea.getMaxY();
      double y1 = y0 - getYOffset();
      double y2 = dataArea.getMinY();
      line1 = new Line2D.Double(x0, y0, x1, y1);
      line2 = new Line2D.Double(x1, y1, x1, y2);
    }
    Paint paint = plot.getDomainGridlinePaint();
    Stroke stroke = plot.getDomainGridlineStroke();
    g2.setPaint(paint != null ? paint : Plot.DEFAULT_OUTLINE_PAINT);
    g2.setStroke(stroke != null ? stroke : Plot.DEFAULT_OUTLINE_STROKE);
    g2.draw(line1);
    g2.draw(line2);
  }
  /**
   * Draws a grid line against the range axis.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param axis the value axis.
   * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
   * @param value the value at which the grid line should be drawn.
   */
  public void drawRangeGridline(
      Graphics2D g2, CategoryPlot plot, ValueAxis axis, Rectangle2D dataArea, double value) {

    Range range = axis.getRange();
    if (!range.contains(value)) {
      return;
    }

    PlotOrientation orientation = plot.getOrientation();
    double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
    Line2D line = null;
    if (orientation == PlotOrientation.HORIZONTAL) {
      line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea.getMaxY());
    } else if (orientation == PlotOrientation.VERTICAL) {
      line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(), v);
    }

    Paint paint = plot.getRangeGridlinePaint();
    if (paint == null) {
      paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
    }
    g2.setPaint(paint);

    Stroke stroke = plot.getRangeGridlineStroke();
    if (stroke == null) {
      stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
    }
    g2.setStroke(stroke);

    g2.draw(line);
  }
  /**
   * Draws the bar with its standard deviation line range for a single (series, category) data item.
   *
   * @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 data the data.
   * @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 data,
      int row,
      int column,
      int pass) {

    int visibleRow = state.getVisibleSeriesIndex(row);
    if (visibleRow < 0) {
      return;
    }
    // defensive check
    if (!(data instanceof StatisticalCategoryDataset)) {
      throw new IllegalArgumentException("Requires StatisticalCategoryDataset.");
    }
    StatisticalCategoryDataset statData = (StatisticalCategoryDataset) data;

    PlotOrientation orientation = plot.getOrientation();
    if (orientation == PlotOrientation.HORIZONTAL) {
      drawHorizontalItem(
          g2, state, dataArea, plot, domainAxis, rangeAxis, statData, visibleRow, row, column);
    } else if (orientation == PlotOrientation.VERTICAL) {
      drawVerticalItem(
          g2, state, dataArea, plot, domainAxis, rangeAxis, statData, visibleRow, row, column);
    }
  }
Beispiel #4
0
  /**
   * Draws a grid line against the domain axis.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
   * @param value the Java2D value at which the grid line should be drawn.
   */
  @Override
  public void drawDomainGridline(
      Graphics2D g2, CategoryPlot plot, Rectangle2D dataArea, double value) {

    Line2D line1 = null;
    Line2D line2 = null;
    PlotOrientation orientation = plot.getOrientation();
    if (orientation == PlotOrientation.HORIZONTAL) {
      double y0 = value;
      double y1 = value - getYOffset();
      double x0 = dataArea.getMinX();
      double x1 = x0 + getXOffset();
      double x2 = dataArea.getMaxX();
      line1 = new Line2D.Double(x0, y0, x1, y1);
      line2 = new Line2D.Double(x1, y1, x2, y1);
    } else if (orientation == PlotOrientation.VERTICAL) {
      double x0 = value;
      double x1 = value + getXOffset();
      double y0 = dataArea.getMaxY();
      double y1 = y0 - getYOffset();
      double y2 = dataArea.getMinY();
      line1 = new Line2D.Double(x0, y0, x1, y1);
      line2 = new Line2D.Double(x1, y1, x1, y2);
    }
    g2.setPaint(plot.getDomainGridlinePaint());
    g2.setStroke(plot.getDomainGridlineStroke());
    g2.draw(line1);
    g2.draw(line2);
  }
  /**
   * 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 data (must be an instance of {@link BoxAndWhiskerCategoryDataset}).
   * @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) {

    if (!(dataset instanceof BoxAndWhiskerCategoryDataset)) {
      throw new IllegalArgumentException(
          "BoxAndWhiskerRenderer.drawItem() : the data should be "
              + "of type BoxAndWhiskerCategoryDataset only.");
    }

    PlotOrientation orientation = plot.getOrientation();

    if (orientation == PlotOrientation.HORIZONTAL) {
      drawHorizontalItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column);
    } else if (orientation == PlotOrientation.VERTICAL) {
      drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis, dataset, row, column);
    }
  }
  /**
   * Draws a grid line against the domain axis.
   *
   * <p>Note that this default implementation assumes that the horizontal axis is the domain axis.
   * If this is not the case, you will need to override this method.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
   * @param value the Java2D value at which the grid line should be drawn.
   */
  public void drawDomainGridline(
      Graphics2D g2, CategoryPlot plot, Rectangle2D dataArea, double value) {

    Line2D line = null;
    PlotOrientation orientation = plot.getOrientation();

    if (orientation == PlotOrientation.HORIZONTAL) {
      line = new Line2D.Double(dataArea.getMinX(), value, dataArea.getMaxX(), value);
    } else if (orientation == PlotOrientation.VERTICAL) {
      line = new Line2D.Double(value, dataArea.getMinY(), value, dataArea.getMaxY());
    }

    Paint paint = plot.getDomainGridlinePaint();
    if (paint == null) {
      paint = CategoryPlot.DEFAULT_GRIDLINE_PAINT;
    }
    g2.setPaint(paint);

    Stroke stroke = plot.getDomainGridlineStroke();
    if (stroke == null) {
      stroke = CategoryPlot.DEFAULT_GRIDLINE_STROKE;
    }
    g2.setStroke(stroke);

    g2.draw(line);
  }
Beispiel #7
0
  /**
   * Draws a range marker.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param axis the value axis.
   * @param marker the marker.
   * @param dataArea the area for plotting data (not including 3D effect).
   */
  @Override
  public void drawRangeMarker(
      Graphics2D g2, CategoryPlot plot, ValueAxis axis, Marker marker, Rectangle2D dataArea) {

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

    if (marker instanceof ValueMarker) {
      ValueMarker vm = (ValueMarker) marker;
      double value = vm.getValue();
      Range range = axis.getRange();
      if (!range.contains(value)) {
        return;
      }

      GeneralPath path = null;
      PlotOrientation orientation = plot.getOrientation();
      if (orientation == PlotOrientation.HORIZONTAL) {
        float x = (float) axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
        float y = (float) adjusted.getMaxY();
        path = new GeneralPath();
        path.moveTo(x, y);
        path.lineTo((float) (x + getXOffset()), y - (float) getYOffset());
        path.lineTo((float) (x + getXOffset()), (float) (adjusted.getMinY() - getYOffset()));
        path.lineTo(x, (float) adjusted.getMinY());
        path.closePath();
      } else if (orientation == PlotOrientation.VERTICAL) {
        float y = (float) axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
        float x = (float) dataArea.getX();
        path = new GeneralPath();
        path.moveTo(x, y);
        path.lineTo(x + (float) this.xOffset, y - (float) this.yOffset);
        path.lineTo((float) (adjusted.getMaxX() + this.xOffset), y - (float) this.yOffset);
        path.lineTo((float) (adjusted.getMaxX()), y);
        path.closePath();
      }
      g2.setPaint(marker.getPaint());
      g2.fill(path);
      g2.setPaint(marker.getOutlinePaint());
      g2.draw(path);
    } else {
      super.drawRangeMarker(g2, plot, axis, marker, adjusted);
      // TODO: draw the interval marker with a 3D effect
    }
  }
  /**
   * Initialises the renderer. This method gets called once at the start of the process of drawing a
   * chart.
   *
   * @param g2 the graphics device.
   * @param dataArea the area in which the data is to be plotted.
   * @param plot the plot.
   * @param rendererIndex the renderer index.
   * @param info collects chart rendering information for return to caller.
   * @return The renderer state.
   */
  public CategoryItemRendererState initialise(
      Graphics2D g2,
      Rectangle2D dataArea,
      CategoryPlot plot,
      int rendererIndex,
      PlotRenderingInfo info) {

    CategoryItemRendererState state = super.initialise(g2, dataArea, plot, rendererIndex, info);

    // calculate the box width
    CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex);
    CategoryDataset dataset = plot.getDataset(rendererIndex);
    if (dataset != null) {
      int columns = dataset.getColumnCount();
      int rows = dataset.getRowCount();
      double space = 0.0;
      PlotOrientation orientation = plot.getOrientation();
      if (orientation == PlotOrientation.HORIZONTAL) {
        space = dataArea.getHeight();
      } else if (orientation == PlotOrientation.VERTICAL) {
        space = dataArea.getWidth();
      }
      double maxWidth = space * getMaximumBarWidth();
      double categoryMargin = 0.0;
      double currentItemMargin = 0.0;
      if (columns > 1) {
        categoryMargin = domainAxis.getCategoryMargin();
      }
      if (rows > 1) {
        currentItemMargin = getItemMargin();
      }
      double used =
          space
              * (1
                  - domainAxis.getLowerMargin()
                  - domainAxis.getUpperMargin()
                  - categoryMargin
                  - currentItemMargin);
      if ((rows * columns) > 0) {
        state.setBarWidth(
            Math.min(used / (dataset.getColumnCount() * dataset.getRowCount()), maxWidth));
      } else {
        state.setBarWidth(Math.min(used, maxWidth));
      }
    }

    return state;
  }
  /**
   * Draws a line perpendicular to the range axis.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param axis the value axis.
   * @param dataArea the area for plotting data (not yet adjusted for any 3D effect).
   * @param value the value at which the grid line should be drawn.
   * @param paint the paint.
   * @param stroke the stroke.
   * @see #drawRangeGridline
   * @since 1.0.13
   */
  public void drawRangeLine(
      Graphics2D g2,
      CategoryPlot plot,
      ValueAxis axis,
      Rectangle2D dataArea,
      double value,
      Paint paint,
      Stroke stroke) {

    Range range = axis.getRange();
    if (!range.contains(value)) {
      return;
    }

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

    Line2D line1 = null;
    Line2D line2 = null;
    PlotOrientation orientation = plot.getOrientation();
    if (orientation == PlotOrientation.HORIZONTAL) {
      double x0 = axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
      double x1 = x0 + getXOffset();
      double y0 = dataArea.getMaxY();
      double y1 = y0 - getYOffset();
      double y2 = dataArea.getMinY();
      line1 = new Line2D.Double(x0, y0, x1, y1);
      line2 = new Line2D.Double(x1, y1, x1, y2);
    } else if (orientation == PlotOrientation.VERTICAL) {
      double y0 = axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
      double y1 = y0 - getYOffset();
      double x0 = dataArea.getMinX();
      double x1 = x0 + getXOffset();
      double x2 = dataArea.getMaxX();
      line1 = new Line2D.Double(x0, y0, x1, y1);
      line2 = new Line2D.Double(x1, y1, x2, y1);
    }
    g2.setPaint(paint);
    g2.setStroke(stroke);
    g2.draw(line1);
    g2.draw(line2);
  }
  /**
   * 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);
    }
  }
Beispiel #11
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);
    }
  }
  /**
   * 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 a marker for the range 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 drawRangeMarker(
      Graphics2D g2, CategoryPlot plot, ValueAxis axis, Marker marker, Rectangle2D dataArea) {

    if (marker instanceof ValueMarker) {
      ValueMarker vm = (ValueMarker) marker;
      double value = vm.getValue();
      Range range = axis.getRange();

      if (!range.contains(value)) {
        return;
      }

      PlotOrientation orientation = plot.getOrientation();
      double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge());
      Line2D line = null;
      if (orientation == PlotOrientation.HORIZONTAL) {
        line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea.getMaxY());
      } else if (orientation == PlotOrientation.VERTICAL) {
        line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(), v);
      }

      g2.setPaint(marker.getPaint());
      g2.setStroke(marker.getStroke());
      g2.draw(line);

      String label = marker.getLabel();
      RectangleAnchor anchor = marker.getLabelAnchor();
      if (label != null) {
        Font labelFont = marker.getLabelFont();
        g2.setFont(labelFont);
        g2.setPaint(marker.getLabelPaint());
        Point2D coordinates =
            calculateRangeMarkerTextAnchorPoint(
                g2,
                orientation,
                dataArea,
                line.getBounds2D(),
                marker.getLabelOffset(),
                LengthAdjustmentType.EXPAND,
                anchor);
        TextUtilities.drawAlignedString(
            label,
            g2,
            (float) coordinates.getX(),
            (float) coordinates.getY(),
            marker.getLabelTextAnchor());
      }
    } else if (marker instanceof IntervalMarker) {

      IntervalMarker im = (IntervalMarker) marker;
      double start = im.getStartValue();
      double end = im.getEndValue();
      Range range = axis.getRange();
      if (!(range.intersects(start, end))) {
        return;
      }

      // don't draw beyond the axis range...
      start = range.constrain(start);
      end = range.constrain(end);

      double v0 = axis.valueToJava2D(start, dataArea, plot.getRangeAxisEdge());
      double v1 = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge());

      PlotOrientation orientation = plot.getOrientation();
      Rectangle2D rect = null;
      if (orientation == PlotOrientation.HORIZONTAL) {
        rect = new Rectangle2D.Double(v0, dataArea.getMinY(), v1 - v0, dataArea.getHeight());
      } else if (orientation == PlotOrientation.VERTICAL) {
        rect =
            new Rectangle2D.Double(
                dataArea.getMinX(), Math.min(v0, v1),
                dataArea.getWidth(), Math.abs(v1 - v0));
      }
      Paint p = marker.getPaint();
      if (p instanceof GradientPaint) {
        GradientPaint gp = (GradientPaint) p;
        GradientPaintTransformer t = im.getGradientPaintTransformer();
        if (t != null) {
          gp = t.transform(gp, rect);
        }
        g2.setPaint(gp);
      } else {
        g2.setPaint(p);
      }
      g2.fill(rect);

      String label = marker.getLabel();
      RectangleAnchor anchor = marker.getLabelAnchor();
      if (label != null) {
        Font labelFont = marker.getLabelFont();
        g2.setFont(labelFont);
        g2.setPaint(marker.getLabelPaint());
        Point2D coordinates =
            calculateRangeMarkerTextAnchorPoint(
                g2,
                orientation,
                dataArea,
                rect,
                marker.getLabelOffset(),
                marker.getLabelOffsetType(),
                anchor);
        TextUtilities.drawAlignedString(
            label,
            g2,
            (float) coordinates.getX(),
            (float) coordinates.getY(),
            marker.getLabelTextAnchor());
      }
    }
  }
  /**
   * Draws a single interval.
   *
   * @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 drawInterval(
      Graphics2D g2,
      CategoryItemRendererState state,
      Rectangle2D dataArea,
      CategoryPlot plot,
      CategoryAxis domainAxis,
      ValueAxis rangeAxis,
      IntervalCategoryDataset dataset,
      int row,
      int column) {

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

    PlotOrientation orientation = plot.getOrientation();
    double rectX = 0.0;
    double rectY = 0.0;

    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;
    }

    // BAR WIDTH
    double rectWidth = state.getBarWidth();

    // BAR HEIGHT
    double rectHeight = Math.abs(java2dValue1 - java2dValue0);

    RectangleEdge barBase = RectangleEdge.LEFT;
    if (orientation == PlotOrientation.HORIZONTAL) {
      // BAR Y
      rectX = java2dValue0;
      rectY =
          calculateBarW0(getPlot(), orientation, dataArea, domainAxis, state, visibleRow, column);
      rectHeight = state.getBarWidth();
      rectWidth = Math.abs(java2dValue1 - java2dValue0);
      barBase = RectangleEdge.LEFT;
    } else if (orientation == PlotOrientation.VERTICAL) {
      // BAR X
      rectX =
          calculateBarW0(getPlot(), orientation, dataArea, domainAxis, state, visibleRow, column);
      rectY = java2dValue0;
      barBase = RectangleEdge.BOTTOM;
    }
    Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth, rectHeight);
    BarPainter painter = getBarPainter();
    if (getShadowsVisible()) {
      painter.paintBarShadow(g2, this, row, column, bar, barBase, false);
    }
    getBarPainter().paintBar(g2, this, row, column, bar, barBase);

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

    // add an item entity, if this information is being collected
    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 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 #16
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 #17
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);
        }
      }
    }
  }
  /**
   * Draws a range marker.
   *
   * @param g2 the graphics device.
   * @param plot the plot.
   * @param axis the value axis.
   * @param marker the marker.
   * @param dataArea the area for plotting data (not including 3D effect).
   */
  public void drawRangeMarker(
      Graphics2D g2, CategoryPlot plot, ValueAxis axis, Marker marker, Rectangle2D dataArea) {

    Rectangle2D adjusted =
        new Rectangle2D.Double(
            dataArea.getX(),
            dataArea.getY() + getYOffset(),
            dataArea.getWidth() - getXOffset(),
            dataArea.getHeight() - getYOffset());
    if (marker instanceof ValueMarker) {
      ValueMarker vm = (ValueMarker) marker;
      double value = vm.getValue();
      Range range = axis.getRange();
      if (!range.contains(value)) {
        return;
      }

      GeneralPath path = null;
      PlotOrientation orientation = plot.getOrientation();
      if (orientation == PlotOrientation.HORIZONTAL) {
        float x = (float) axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
        float y = (float) adjusted.getMaxY();
        path = new GeneralPath();
        path.moveTo(x, y);
        path.lineTo((float) (x + getXOffset()), y - (float) getYOffset());
        path.lineTo((float) (x + getXOffset()), (float) (adjusted.getMinY() - getYOffset()));
        path.lineTo(x, (float) adjusted.getMinY());
        path.closePath();
      } else if (orientation == PlotOrientation.VERTICAL) {
        float y = (float) axis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
        float x = (float) dataArea.getX();
        path = new GeneralPath();
        path.moveTo(x, y);
        path.lineTo(x + (float) this.xOffset, y - (float) this.yOffset);
        path.lineTo((float) (adjusted.getMaxX() + this.xOffset), y - (float) this.yOffset);
        path.lineTo((float) (adjusted.getMaxX()), y);
        path.closePath();
      }
      g2.setPaint(marker.getPaint());
      g2.fill(path);
      g2.setPaint(marker.getOutlinePaint());
      g2.draw(path);

      String label = marker.getLabel();
      RectangleAnchor anchor = marker.getLabelAnchor();
      if (label != null) {
        Font labelFont = marker.getLabelFont();
        g2.setFont(labelFont);
        g2.setPaint(marker.getLabelPaint());
        Point2D coordinates =
            calculateRangeMarkerTextAnchorPoint(
                g2,
                orientation,
                dataArea,
                path.getBounds2D(),
                marker.getLabelOffset(),
                LengthAdjustmentType.EXPAND,
                anchor);
        TextUtilities.drawAlignedString(
            label,
            g2,
            (float) coordinates.getX(),
            (float) coordinates.getY(),
            marker.getLabelTextAnchor());
      }

    } else {
      super.drawRangeMarker(g2, plot, axis, marker, adjusted);
      // TODO: draw the interval marker with a 3D effect
    }
  }
    // copied and modified from jfreechart-1.0.14 org.jfree.chart.renderer.category.BarRenderer
    private void drawItemInternal(
        Graphics2D g2,
        CategoryItemRendererState state,
        Rectangle2D dataArea,
        CategoryPlot plot,
        CategoryAxis domainAxis,
        ValueAxis rangeAxis,
        CategoryDataset dataset,
        int row,
        int column,
        int pass) {

      // nothing is drawn if the row index is not included in the list with
      // the indices of the visible rows...
      int visibleRow = state.getVisibleSeriesIndex(row);
      if (visibleRow < 0) {
        return;
      }
      // nothing is drawn for null values...
      Number dataValue = dataset.getValue(row, column);
      if (dataValue == null) {
        return;
      }

      final double value = dataValue.doubleValue();
      PlotOrientation orientation = plot.getOrientation();
      double barW0 =
          calculateBarW0(plot, orientation, dataArea, domainAxis, state, visibleRow, column);
      double[] barL0L1 = calculateBarL0L1(value);
      if (barL0L1 == null) {
        return; // the bar is not visible
      }

      RectangleEdge edge = plot.getRangeAxisEdge();
      double transL0 = rangeAxis.valueToJava2D(barL0L1[0], dataArea, edge);
      double transL1 = rangeAxis.valueToJava2D(barL0L1[1], dataArea, edge);

      // in the following code, barL0 is (in Java2D coordinates) the LEFT
      // end of the bar for a horizontal bar chart, and the TOP end of the
      // bar for a vertical bar chart.  Whether this is the BASE of the bar
      // or not depends also on (a) whether the data value is 'negative'
      // relative to the base value and (b) whether or not the range axis is
      // inverted.  This only matters if/when we apply the minimumBarLength
      // attribute, because we should extend the non-base end of the bar
      boolean positive = (value >= this.getBase());
      boolean inverted = rangeAxis.isInverted();
      double barL0 = Math.min(transL0, transL1);
      double barLength = Math.abs(transL1 - transL0);
      double barLengthAdj = 0.0;
      if (barLength > 0.0 && barLength < getMinimumBarLength()) {
        barLengthAdj = getMinimumBarLength() - barLength;
      }
      double barL0Adj = 0.0;
      RectangleEdge barBase;
      if (orientation == PlotOrientation.HORIZONTAL) {
        if (positive && inverted || !positive && !inverted) {
          barL0Adj = barLengthAdj;
          barBase = RectangleEdge.RIGHT;
        } else {
          barBase = RectangleEdge.LEFT;
        }
      } else {
        if (positive && !inverted || !positive && inverted) {
          barL0Adj = barLengthAdj;
          barBase = RectangleEdge.BOTTOM;
        } else {
          barBase = RectangleEdge.TOP;
        }
      }

      // draw the bar...
      RectangularShape bar = null;
      if (orientation == PlotOrientation.HORIZONTAL) {
        bar =
            getBarShape(
                row, barL0 - barL0Adj, barW0, barLength + barLengthAdj, state.getBarWidth());
      } else {
        bar =
            getBarShape(
                row, barW0, barL0 - barL0Adj, state.getBarWidth(), barLength + barLengthAdj);
      }

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

      //          FIXME
      //            CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
      //                    column);
      //            if (generator != null && isItemLabelVisible(row, column)) {
      //                drawItemLabel(g2, dataset, row, column, plot, generator, bar,
      //                        (value < 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),
          value,
          datasetIndex,
          barW0,
          barL0,
          orientation);

      // add an item entity, if this information is being collected
      EntityCollection entities = state.getEntityCollection();
      if (entities != null) {
        addItemEntity(entities, dataset, row, column, bar);
      }
    }
  /**
   * Draws a 3D bar to represent one data item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area for plotting the data.
   * @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) {

    // check the value we are plotting...
    Number dataValue = dataset.getValue(row, column);
    if (dataValue == null) {
      return;
    }

    double value = dataValue.doubleValue();

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

    PlotOrientation orientation = plot.getOrientation();

    double barW0 = calculateBarW0(plot, orientation, adjusted, domainAxis, state, row, column);
    double[] barL0L1 = calculateBarL0L1(value);
    if (barL0L1 == null) {
      return; // the bar is not visible
    }

    RectangleEdge edge = plot.getRangeAxisEdge();
    double transL0 = rangeAxis.valueToJava2D(barL0L1[0], adjusted, edge);
    double transL1 = rangeAxis.valueToJava2D(barL0L1[1], adjusted, edge);
    double barL0 = Math.min(transL0, transL1);
    double barLength = Math.abs(transL1 - transL0);

    // draw the bar...
    Rectangle2D bar = null;
    if (orientation == PlotOrientation.HORIZONTAL) {
      bar = new Rectangle2D.Double(barL0, barW0, barLength, state.getBarWidth());
    } else {
      bar = new Rectangle2D.Double(barW0, barL0, state.getBarWidth(), barLength);
    }
    Paint itemPaint = getItemPaint(row, column);
    g2.setPaint(itemPaint);
    g2.fill(bar);

    double x0 = bar.getMinX();
    double x1 = x0 + getXOffset();
    double x2 = bar.getMaxX();
    double x3 = x2 + getXOffset();

    double y0 = bar.getMinY() - getYOffset();
    double y1 = bar.getMinY();
    double y2 = bar.getMaxY() - getYOffset();
    double y3 = bar.getMaxY();

    GeneralPath bar3dRight = null;
    GeneralPath bar3dTop = null;
    if (barLength > 0.0) {
      bar3dRight = new GeneralPath();
      bar3dRight.moveTo((float) x2, (float) y3);
      bar3dRight.lineTo((float) x2, (float) y1);
      bar3dRight.lineTo((float) x3, (float) y0);
      bar3dRight.lineTo((float) x3, (float) y2);
      bar3dRight.closePath();

      g2.setPaint(PaintAlpha.darker(itemPaint));
      g2.fill(bar3dRight);
    }

    bar3dTop = new GeneralPath();
    bar3dTop.moveTo((float) x0, (float) y1);
    bar3dTop.lineTo((float) x1, (float) y0);
    bar3dTop.lineTo((float) x3, (float) y0);
    bar3dTop.lineTo((float) x2, (float) y1);
    bar3dTop.closePath();
    g2.fill(bar3dTop);

    if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
      g2.setStroke(getItemOutlineStroke(row, column));
      g2.setPaint(getItemOutlinePaint(row, column));
      g2.draw(bar);
      if (bar3dRight != null) {
        g2.draw(bar3dRight);
      }
      g2.draw(bar3dTop);
    }

    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) {
      GeneralPath barOutline = new GeneralPath();
      barOutline.moveTo((float) x0, (float) y3);
      barOutline.lineTo((float) x0, (float) y1);
      barOutline.lineTo((float) x1, (float) y0);
      barOutline.lineTo((float) x3, (float) y0);
      barOutline.lineTo((float) x3, (float) y2);
      barOutline.lineTo((float) x2, (float) y3);
      barOutline.closePath();
      addItemEntity(entities, dataset, row, column, barOutline);
    }
  }
  /**
   * 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 bar for a single (series, category) data item.
   *
   * @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 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) {

    double previous = state.getSeriesRunningTotal();
    if (column == dataset.getColumnCount() - 1) {
      previous = 0.0;
    }
    double current = 0.0;
    Number n = dataset.getValue(row, column);
    if (n != null) {
      current = previous + n.doubleValue();
    }
    state.setSeriesRunningTotal(current);

    int categoryCount = getColumnCount();
    PlotOrientation orientation = plot.getOrientation();

    double rectX = 0.0;
    double rectY = 0.0;

    RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();

    // Y0
    double j2dy0 = rangeAxis.valueToJava2D(previous, dataArea, rangeAxisLocation);

    // Y1
    double j2dy1 = rangeAxis.valueToJava2D(current, dataArea, rangeAxisLocation);

    double valDiff = current - previous;
    if (j2dy1 < j2dy0) {
      double temp = j2dy1;
      j2dy1 = j2dy0;
      j2dy0 = temp;
    }

    // BAR WIDTH
    double rectWidth = state.getBarWidth();

    // BAR HEIGHT
    double rectHeight = Math.max(getMinimumBarLength(), Math.abs(j2dy1 - j2dy0));

    Comparable seriesKey = dataset.getRowKey(row);
    Comparable categoryKey = dataset.getColumnKey(column);
    if (orientation == PlotOrientation.HORIZONTAL) {
      rectY =
          domainAxis.getCategorySeriesMiddle(
              categoryKey, seriesKey, dataset, getItemMargin(), dataArea, RectangleEdge.LEFT);

      rectX = j2dy0;
      rectHeight = state.getBarWidth();
      rectY = rectY - rectHeight / 2.0;
      rectWidth = Math.max(getMinimumBarLength(), Math.abs(j2dy1 - j2dy0));

    } else if (orientation == PlotOrientation.VERTICAL) {
      rectX =
          domainAxis.getCategorySeriesMiddle(
              categoryKey, seriesKey, dataset, getItemMargin(), dataArea, RectangleEdge.TOP);
      rectX = rectX - rectWidth / 2.0;
      rectY = j2dy0;
    }
    Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth, rectHeight);
    Paint seriesPaint = getFirstBarPaint();
    if (column == 0) {
      seriesPaint = getFirstBarPaint();
    } else if (column == categoryCount - 1) {
      seriesPaint = getLastBarPaint();
    } else {
      if (valDiff < 0.0) {
        seriesPaint = getNegativeBarPaint();
      } else if (valDiff > 0.0) {
        seriesPaint = getPositiveBarPaint();
      } else {
        seriesPaint = getLastBarPaint();
      }
    }
    if (getGradientPaintTransformer() != null && seriesPaint instanceof GradientPaint) {
      GradientPaint gp = (GradientPaint) seriesPaint;
      seriesPaint = getGradientPaintTransformer().transform(gp, bar);
    }
    g2.setPaint(seriesPaint);
    g2.fill(bar);

    // 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, (valDiff < 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);
    }
  }