コード例 #1
0
  /**
   * Created an entity for the axis.
   *
   * @param cursor the initial cursor value.
   * @param state the axis state after completion of the drawing with a possibly updated cursor
   *     position.
   * @param dataArea the data area.
   * @param edge the edge.
   * @param plotState the PlotRenderingInfo from which a reference to the entity collection can be
   *     obtained.
   * @since 1.0.13
   */
  protected void createAndAddEntity(
      double cursor,
      AxisState state,
      Rectangle2D dataArea,
      RectangleEdge edge,
      PlotRenderingInfo plotState) {

    if (plotState == null || plotState.getOwner() == null) {
      return; // no need to create entity if we can´t save it anyways...
    }
    Rectangle2D hotspot = null;
    if (edge.equals(RectangleEdge.TOP)) {
      hotspot =
          new Rectangle2D.Double(
              dataArea.getX(), state.getCursor(), dataArea.getWidth(), cursor - state.getCursor());
    } else if (edge.equals(RectangleEdge.BOTTOM)) {
      hotspot =
          new Rectangle2D.Double(
              dataArea.getX(), cursor, dataArea.getWidth(), state.getCursor() - cursor);
    } else if (edge.equals(RectangleEdge.LEFT)) {
      hotspot =
          new Rectangle2D.Double(
              state.getCursor(), dataArea.getY(), cursor - state.getCursor(), dataArea.getHeight());
    } else if (edge.equals(RectangleEdge.RIGHT)) {
      hotspot =
          new Rectangle2D.Double(
              cursor, dataArea.getY(), state.getCursor() - cursor, dataArea.getHeight());
    }
    EntityCollection e = plotState.getOwner().getEntityCollection();
    if (e != null) {
      e.add(new AxisEntity(hotspot, this));
    }
  }
コード例 #2
0
  /**
   * Creates an image map element that complies with the XHTML 1.0 specification.
   *
   * @param name the map name (<code>null</code> not permitted).
   * @param info the chart rendering info (<code>null</code> not permitted).
   * @param toolTipTagFragmentGenerator a generator for the HTML fragment that will contain the
   *     tooltip text (<code>null</code> not permitted if <code>info</code> contains tooltip
   *     information).
   * @param urlTagFragmentGenerator a generator for the HTML fragment that will contain the URL
   *     reference (<code>null</code> not permitted if <code>info</code> contains URLs).
   * @return The map tag.
   */
  public static String getImageMap(
      String name,
      ChartRenderingInfo info,
      ToolTipTagFragmentGenerator toolTipTagFragmentGenerator,
      URLTagFragmentGenerator urlTagFragmentGenerator) {

    StringBuilder sb = new StringBuilder();
    sb.append("<map id=\"").append(htmlEscape(name));
    sb.append("\" name=\"").append(htmlEscape(name)).append("\">");
    sb.append(StringUtils.getLineSeparator());
    EntityCollection entities = info.getEntityCollection();
    if (entities != null) {
      int count = entities.getEntityCount();
      for (int i = count - 1; i >= 0; i--) {
        ChartEntity entity = entities.getEntity(i);
        if (entity.getToolTipText() != null || entity.getURLText() != null) {
          String area =
              entity.getImageMapAreaTag(toolTipTagFragmentGenerator, urlTagFragmentGenerator);
          if (area.length() > 0) {
            sb.append(area);
            sb.append(StringUtils.getLineSeparator());
          }
        }
      }
    }
    sb.append("</map>");
    return sb.toString();
  }
  @SuppressWarnings("rawtypes")
  @Override
  public void zoom(Rectangle selection) {
    if (map == null || layer == null) {
      return;
    }
    Set<FeatureId> selected = new HashSet<FeatureId>();
    try {
      XYSeriesCollection ds = (XYSeriesCollection) getChart().getXYPlot().getDataset(2);
      XYSeries selectionSeries = ds.getSeries(0);
      selectionSeries.clear();

      EntityCollection entities = this.getChartRenderingInfo().getEntityCollection();
      Iterator iter = entities.iterator();
      while (iter.hasNext()) {
        ChartEntity entity = (ChartEntity) iter.next();
        if (entity instanceof XYItemEntity) {
          XYItemEntity item = (XYItemEntity) entity;
          if (item.getSeriesIndex() != 0) {
            continue;
          }

          java.awt.Rectangle bound = item.getArea().getBounds();
          if (selection.intersects(bound.x, bound.y, bound.width, bound.height)) {
            XYSeriesCollection dataSet = (XYSeriesCollection) item.getDataset();
            XYSeries xySeries = dataSet.getSeries(item.getSeriesIndex());
            XYDataItem xyDataItem = xySeries.getDataItem(item.getItem());
            if (xyDataItem instanceof XYDataItem2) {
              XYDataItem2 dataItem = (XYDataItem2) xyDataItem;
              selectionSeries.add(dataItem);
              selected.add(ff.featureId(dataItem.getFeature().getID()));
            }
          }
        }
      }
    } catch (Exception e) {
      // skip
    } finally {
      if (selected.size() > 0) {
        map.select(ff.id(selected), layer);
      } else {
        map.select(Filter.EXCLUDE, layer);
      }
      this.forceRedraw();
    }
  }
コード例 #4
0
 /**
  * Draws the block within the specified area.
  *
  * @param g2  the graphics device.
  * @param area  the area.
  * @param params  passed on to blocks within the container
  *                (<code>null</code> permitted).
  *
  * @return An instance of {@link EntityBlockResult}, or <code>null</code>.
  */
 public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
     // draw the block without collecting entities
     super.draw(g2, area, null);
     EntityBlockParams ebp = null;
     BlockResult r = new BlockResult();
     if (params instanceof EntityBlockParams) {
         ebp = (EntityBlockParams) params;
         if (ebp.getGenerateEntities()) {
             EntityCollection ec = new StandardEntityCollection();
             LegendItemEntity entity = new LegendItemEntity(
                     (Shape) area.clone());
             entity.setSeriesIndex(this.series);
             entity.setSeriesKey(this.seriesKey);
             entity.setDataset(this.dataset);
             entity.setToolTipText(getToolTipText());
             entity.setURLText(getURLText());
             ec.add(entity);
             r.setEntityCollection(ec);
         }
     }
     return r;
 }
コード例 #5
0
  /**
   * Adds an entity with the specified hotspot, but only if an entity collection is accessible via
   * the renderer state.
   *
   * @param entities the entity collection.
   * @param dataset the dataset.
   * @param row the row index.
   * @param column the column index.
   * @param hotspot the hotspot.
   */
  protected void addItemEntity(
      EntityCollection entities, CategoryDataset dataset, int row, int column, Shape hotspot) {

    String tip = null;
    CategoryToolTipGenerator tipster = getToolTipGenerator(row, column);
    if (tipster != null) {
      tip = tipster.generateToolTip(dataset, row, column);
    }
    String url = null;
    CategoryURLGenerator urlster = getItemURLGenerator(row, column);
    if (urlster != null) {
      url = urlster.generateURL(dataset, row, column);
    }
    CategoryItemEntity entity =
        new CategoryItemEntity(
            hotspot, tip, url, dataset, row, dataset.getColumnKey(column), column);
    entities.add(entity);
  }
コード例 #6
0
ファイル: HistogramChart.java プロジェクト: benanhalt/Specify
    /* (non-Javadoc)
     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
     */
    @Override
    public void paint(Graphics g) {
      super.paint(g);

      if (rect != null) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.RED);

        adjustRect(rect);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(lineStroke);

        if (boundings == null) {
          boundings = new Rectangle[4];

          if (entities == null) {
            entities = new ArrayList<CategoryItemEntity>();
            EntityCollection entCol = chartPanel.getChartRenderingInfo().getEntityCollection();

            for (int i = 0; i < entCol.getEntityCount(); i++) {
              ChartEntity ce = (ChartEntity) entCol.getEntity(i);
              if (ce instanceof CategoryItemEntity) {
                CategoryItemEntity cie = (CategoryItemEntity) ce;
                Rectangle r = adjustRect(cie.getArea().getBounds());
                if (r.height > maxHeight) {
                  maxHeight = (int) cie.getArea().getBounds().getHeight();
                  maxY = r.y;
                }
                entities.add(cie);
              }
            }
          }

          int half = (entities.size() - 1) / 2;
          boundings[0] = getEntityPoint(entities, 0);
          boundings[1] = getEntityPoint(entities, half);
          boundings[2] = getEntityPoint(entities, half + 1);
          boundings[3] = getEntityPoint(entities, entities.size() - 1);

          int[] inxs = new int[] {0, half, half + 1, entities.size() - 1};
          currEntities = new CategoryItemEntity[4];
          for (int i = 0; i < inxs.length; i++) {
            currEntities[i] = entities.get(inxs[i]);
          }
        }

        for (Rectangle r : boundings) {
          g.drawImage(
              thumb.getImage(),
              r.x - (thumb.getIconWidth() / 2) + 2,
              r.y + r.height - thumb.getIconHeight(),
              null);
        }

        int x = (int) ((double) boundings[0].x * 1); // chartPanel.getScaleX());
        int w = (int) ((double) (boundings[1].x - boundings[0].x) * 1); // chartPanel.getScaleX());

        // int y = (int)((double)maxY * chartPanel.getScaleY());
        int h = (int) ((double) maxHeight * chartPanel.getScaleY());

        g2d.setColor(new Color(255, 255, 255, 64));
        g2d.fillRect(x + 2, maxY, w, h);

        x = (int) ((double) boundings[2].x * 1); // chartPanel.getScaleX());
        w = (int) ((double) (boundings[3].x - boundings[2].x) * 1); // chartPanel.getScaleX());

        g2d.setColor(new Color(255, 255, 255, 64));
        g2d.fillRect(x + 2, maxY, w, h);
      }
    }
コード例 #7
0
  /**
   * Draws the visual representation of a single data item, second pass. In the second pass, the
   * renderer draws the lines and shapes for the individual points in the two series.
   *
   * @param x_graphics the graphics device.
   * @param x_dataArea the area within which the data is being drawn.
   * @param x_info collects information about the drawing.
   * @param x_plot the plot (can be used to obtain standard color information etc).
   * @param x_domainAxis the domain (horizontal) axis.
   * @param x_rangeAxis the range (vertical) axis.
   * @param x_dataset the dataset.
   * @param x_series the series index (zero-based).
   * @param x_item the item index (zero-based).
   * @param x_crosshairState crosshair information for the plot (<code>null</code> permitted).
   */
  protected void drawItemPass1(
      Graphics2D x_graphics,
      Rectangle2D x_dataArea,
      PlotRenderingInfo x_info,
      XYPlot x_plot,
      ValueAxis x_domainAxis,
      ValueAxis x_rangeAxis,
      XYDataset x_dataset,
      int x_series,
      int x_item,
      CrosshairState x_crosshairState) {

    Shape l_entityArea = null;
    EntityCollection l_entities = null;
    if (null != x_info) {
      l_entities = x_info.getOwner().getEntityCollection();
    }

    Paint l_seriesPaint = getItemPaint(x_series, x_item);
    Stroke l_seriesStroke = getItemStroke(x_series, x_item);
    x_graphics.setPaint(l_seriesPaint);
    x_graphics.setStroke(l_seriesStroke);

    PlotOrientation l_orientation = x_plot.getOrientation();
    RectangleEdge l_domainAxisLocation = x_plot.getDomainAxisEdge();
    RectangleEdge l_rangeAxisLocation = x_plot.getRangeAxisEdge();

    double l_x0 = x_dataset.getXValue(x_series, x_item);
    double l_y0 = x_dataset.getYValue(x_series, x_item);
    double l_x1 = x_domainAxis.valueToJava2D(l_x0, x_dataArea, l_domainAxisLocation);
    double l_y1 = x_rangeAxis.valueToJava2D(l_y0, x_dataArea, l_rangeAxisLocation);

    if (getShapesVisible()) {
      Shape l_shape = getItemShape(x_series, x_item);
      if (l_orientation == PlotOrientation.HORIZONTAL) {
        l_shape = ShapeUtilities.createTranslatedShape(l_shape, l_y1, l_x1);
      } else {
        l_shape = ShapeUtilities.createTranslatedShape(l_shape, l_x1, l_y1);
      }
      if (l_shape.intersects(x_dataArea)) {
        x_graphics.setPaint(getItemPaint(x_series, x_item));
        x_graphics.fill(l_shape);
      }
      l_entityArea = l_shape;
    }

    // add an entity for the item...
    if (null != l_entities) {
      if (null == l_entityArea) {
        l_entityArea = new Rectangle2D.Double((l_x1 - 2), (l_y1 - 2), 4, 4);
      }
      String l_tip = null;
      XYToolTipGenerator l_tipGenerator = getToolTipGenerator(x_series, x_item);
      if (null != l_tipGenerator) {
        l_tip = l_tipGenerator.generateToolTip(x_dataset, x_series, x_item);
      }
      String l_url = null;
      XYURLGenerator l_urlGenerator = getURLGenerator();
      if (null != l_urlGenerator) {
        l_url = l_urlGenerator.generateURL(x_dataset, x_series, x_item);
      }
      XYItemEntity l_entity =
          new XYItemEntity(l_entityArea, x_dataset, x_series, x_item, l_tip, l_url);
      l_entities.add(l_entity);
    }

    // draw the item label if there is one...
    if (isItemLabelVisible(x_series, x_item)) {
      drawItemLabel(
          x_graphics, l_orientation, x_dataset, x_series, x_item, l_x1, l_y1, (l_y1 < 0.0));
    }

    int l_domainAxisIndex = x_plot.getDomainAxisIndex(x_domainAxis);
    int l_rangeAxisIndex = x_plot.getRangeAxisIndex(x_rangeAxis);
    updateCrosshairValues(
        x_crosshairState,
        l_x0,
        l_y0,
        l_domainAxisIndex,
        l_rangeAxisIndex,
        l_x1,
        l_y1,
        l_orientation);

    if (0 == x_item) {
      return;
    }

    double l_x2 =
        x_domainAxis.valueToJava2D(
            x_dataset.getXValue(x_series, (x_item - 1)), x_dataArea, l_domainAxisLocation);
    double l_y2 =
        x_rangeAxis.valueToJava2D(
            x_dataset.getYValue(x_series, (x_item - 1)), x_dataArea, l_rangeAxisLocation);

    Line2D l_line = null;
    if (PlotOrientation.HORIZONTAL == l_orientation) {
      l_line = new Line2D.Double(l_y1, l_x1, l_y2, l_x2);
    } else if (PlotOrientation.VERTICAL == l_orientation) {
      l_line = new Line2D.Double(l_x1, l_y1, l_x2, l_y2);
    }

    if ((null != l_line) && l_line.intersects(x_dataArea)) {
      x_graphics.setPaint(getItemPaint(x_series, x_item));
      x_graphics.setStroke(getItemStroke(x_series, x_item));
      x_graphics.draw(l_line);
    }
  }
コード例 #8
0
  /**
   * Draws a single data item.
   *
   * @param g2 the graphics device (<code>null</code> not permitted).
   * @param section the section index.
   * @param dataArea the data plot area.
   * @param state state information for one chart.
   * @param currentPass the current pass index.
   */
  protected void drawItem(
      Graphics2D g2, int section, Rectangle2D dataArea, PiePlotState state, int currentPass) {

    PieDataset dataset = getDataset();
    Number n = dataset.getValue(section);
    if (n == null) {
      return;
    }
    double value = n.doubleValue();
    double angle1 = 0.0;
    double angle2 = 0.0;

    Rotation direction = getDirection();
    if (direction == Rotation.CLOCKWISE) {
      angle1 = state.getLatestAngle();
      angle2 = angle1 - value / state.getTotal() * 360.0;
    } else if (direction == Rotation.ANTICLOCKWISE) {
      angle1 = state.getLatestAngle();
      angle2 = angle1 + value / state.getTotal() * 360.0;
    } else {
      throw new IllegalStateException("Rotation type not recognised.");
    }

    double angle = (angle2 - angle1);
    if (Math.abs(angle) > getMinimumArcAngleToDraw()) {
      double ep = 0.0;
      double mep = getMaximumExplodePercent();
      if (mep > 0.0) {
        ep = getExplodePercent(section) / mep;
      }
      Rectangle2D arcBounds =
          getArcBounds(state.getPieArea(), state.getExplodedPieArea(), angle1, angle, ep);
      Arc2D.Double arc = new Arc2D.Double(arcBounds, angle1, angle, Arc2D.OPEN);

      // create the bounds for the inner arc
      RectangleInsets s =
          new RectangleInsets(
              UnitType.RELATIVE, sectionDepth, sectionDepth, sectionDepth, sectionDepth);
      Rectangle2D innerArcBounds = new Rectangle2D.Double();
      innerArcBounds.setRect(arcBounds);
      s.trim(innerArcBounds);
      // calculate inner arc in reverse direction, for later
      // GeneralPath construction
      Arc2D.Double arc2 = new Arc2D.Double(innerArcBounds, angle1 + angle, -angle, Arc2D.OPEN);
      GeneralPath path = new GeneralPath();
      path.moveTo((float) arc.getStartPoint().getX(), (float) arc.getStartPoint().getY());
      path.append(arc.getPathIterator(null), false);
      path.append(arc2.getPathIterator(null), true);
      path.closePath();

      Line2D separator = new Line2D.Double(arc2.getEndPoint(), arc.getStartPoint());

      if (currentPass == 0) {
        Paint shadowPaint = getShadowPaint();
        double shadowXOffset = getShadowXOffset();
        double shadowYOffset = getShadowYOffset();
        if (shadowPaint != null) {
          Shape shadowArc =
              ShapeUtilities.createTranslatedShape(
                  path, (float) shadowXOffset, (float) shadowYOffset);
          g2.setPaint(shadowPaint);
          g2.fill(shadowArc);
        }
      } else if (currentPass == 1) {

        Paint paint = getSectionPaint(section);
        g2.setPaint(paint);
        g2.fill(path);
        Paint outlinePaint = getSectionOutlinePaint(section);
        Stroke outlineStroke = getSectionOutlineStroke(section);
        if (getSectionOutlinesVisible()) {
          g2.setPaint(outlinePaint);
          g2.setStroke(outlineStroke);
          g2.draw(path);
        }

        // add an entity for the pie section
        if (state.getInfo() != null) {
          EntityCollection entities = state.getEntityCollection();
          if (entities != null) {
            Comparable key = dataset.getKey(section);
            String tip = null;
            PieToolTipGenerator toolTipGenerator = getToolTipGenerator();
            if (toolTipGenerator != null) {
              tip = toolTipGenerator.generateToolTip(dataset, key);
            }
            String url = null;
            PieURLGenerator urlGenerator = getURLGenerator();
            if (urlGenerator != null) {
              url = urlGenerator.generateURL(dataset, key, getPieIndex());
            }
            PieSectionEntity entity =
                new PieSectionEntity(path, dataset, getPieIndex(), section, key, tip, url);
            entities.add(entity);
          }
        }
      } else if (currentPass == 2) {
        // if there were 3 passes...
        if (this.sectionSeparatorsVisible) {
          Line2D extendedSeparator =
              extendLine(separator, this.innerSeparatorExtension, this.outerSeparatorExtension);
          g2.setStroke(this.separatorStroke);
          g2.setPaint(this.separatorPaint);
          g2.draw(extendedSeparator);
        }
      }
    }
    state.setLatestAngle(angle2);
  }
コード例 #9
0
  /**
   * Draws the category labels and returns the updated axis state.
   *
   * @param g2 the graphics device (<code>null</code> not permitted).
   * @param plotArea the plot area (<code>null</code> not permitted).
   * @param dataArea the area inside the axes (<code>null</code> not permitted).
   * @param edge the axis location (<code>null</code> not permitted).
   * @param state the axis state (<code>null</code> not permitted).
   * @param plotState collects information about the plot (<code>null</code> permitted).
   * @return The updated axis state (never <code>null</code>).
   */
  protected AxisState drawCategoryLabels(
      Graphics2D g2,
      Rectangle2D plotArea,
      Rectangle2D dataArea,
      RectangleEdge edge,
      AxisState state,
      PlotRenderingInfo plotState) {

    ParamChecks.nullNotPermitted(state, "state");
    if (!isTickLabelsVisible()) {
      return state;
    }
    List<CategoryTick> ticks = refreshTicks(g2, state, plotArea, edge);
    // state.setTicks(ticks);        //FIXME MMC had to remove this as the types don't match

    int categoryIndex = 0;
    for (CategoryTick tick : ticks) {

      g2.setFont(getTickLabelFont(tick.getCategory()));
      g2.setPaint(getTickLabelPaint(tick.getCategory()));

      CategoryLabelPosition position = this.categoryLabelPositions.getLabelPosition(edge);
      double x0 = 0.0;
      double x1 = 0.0;
      double y0 = 0.0;
      double y1 = 0.0;
      if (edge == RectangleEdge.TOP) {
        x0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
        x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
        y1 = state.getCursor() - this.categoryLabelPositionOffset;
        y0 = y1 - state.getMax();
      } else if (edge == RectangleEdge.BOTTOM) {
        x0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
        x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
        y0 = state.getCursor() + this.categoryLabelPositionOffset;
        y1 = y0 + state.getMax();
      } else if (edge == RectangleEdge.LEFT) {
        y0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
        y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
        x1 = state.getCursor() - this.categoryLabelPositionOffset;
        x0 = x1 - state.getMax();
      } else if (edge == RectangleEdge.RIGHT) {
        y0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
        y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
        x0 = state.getCursor() + this.categoryLabelPositionOffset;
        x1 = x0 - state.getMax();
      }
      Rectangle2D area = new Rectangle2D.Double(x0, y0, (x1 - x0), (y1 - y0));
      Point2D anchorPoint = RectangleAnchor.coordinates(area, position.getCategoryAnchor());
      TextBlock block = tick.getLabel();
      block.draw(
          g2,
          (float) anchorPoint.getX(),
          (float) anchorPoint.getY(),
          position.getLabelAnchor(),
          (float) anchorPoint.getX(),
          (float) anchorPoint.getY(),
          position.getAngle());
      Shape bounds =
          block.calculateBounds(
              g2,
              (float) anchorPoint.getX(),
              (float) anchorPoint.getY(),
              position.getLabelAnchor(),
              (float) anchorPoint.getX(),
              (float) anchorPoint.getY(),
              position.getAngle());
      if (plotState != null && plotState.getOwner() != null) {
        EntityCollection entities = plotState.getOwner().getEntityCollection();
        if (entities != null) {
          String tooltip = getCategoryLabelToolTip(tick.getCategory());
          String url = getCategoryLabelURL(tick.getCategory());
          entities.add(new CategoryLabelEntity(tick.getCategory(), bounds, tooltip, url));
        }
      }
      categoryIndex++;
    }

    if (edge.equals(RectangleEdge.TOP)) {
      double h = state.getMax() + this.categoryLabelPositionOffset;
      state.cursorUp(h);
    } else if (edge.equals(RectangleEdge.BOTTOM)) {
      double h = state.getMax() + this.categoryLabelPositionOffset;
      state.cursorDown(h);
    } else if (edge == RectangleEdge.LEFT) {
      double w = state.getMax() + this.categoryLabelPositionOffset;
      state.cursorLeft(w);
    } else if (edge == RectangleEdge.RIGHT) {
      double w = state.getMax() + this.categoryLabelPositionOffset;
      state.cursorRight(w);
    }
    return state;
  }
コード例 #10
0
  /**
   * Draws the visual representation of a single data item.
   *
   * @param g2 the graphics device.
   * @param state the renderer state.
   * @param dataArea the area within which the data is being drawn.
   * @param info collects information about the drawing.
   * @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.
   * @param series the series index (zero-based).
   * @param item the item index (zero-based).
   * @param crosshairState crosshair information for the plot (<code>null</code> permitted).
   * @param pass the pass index.
   */
  public void drawItem(
      Graphics2D g2,
      XYItemRendererState state,
      Rectangle2D dataArea,
      PlotRenderingInfo info,
      XYPlot plot,
      ValueAxis domainAxis,
      ValueAxis rangeAxis,
      XYDataset dataset,
      int series,
      int item,
      CrosshairState crosshairState,
      int pass) {

    if (!getItemVisible(series, item)) {
      return;
    }
    XYAreaRendererState areaState = (XYAreaRendererState) state;

    // get the data point...
    double x1 = dataset.getXValue(series, item);
    double y1 = dataset.getYValue(series, item);
    if (Double.isNaN(y1)) {
      y1 = 0.0;
    }
    double transX1 = domainAxis.valueToJava2D(x1, dataArea, plot.getDomainAxisEdge());
    double transY1 = rangeAxis.valueToJava2D(y1, dataArea, plot.getRangeAxisEdge());

    // get the previous point and the next point so we can calculate a
    // "hot spot" for the area (used by the chart entity)...
    int itemCount = dataset.getItemCount(series);
    double x0 = dataset.getXValue(series, Math.max(item - 1, 0));
    double y0 = dataset.getYValue(series, Math.max(item - 1, 0));
    if (Double.isNaN(y0)) {
      y0 = 0.0;
    }
    double transX0 = domainAxis.valueToJava2D(x0, dataArea, plot.getDomainAxisEdge());
    double transY0 = rangeAxis.valueToJava2D(y0, dataArea, plot.getRangeAxisEdge());

    double x2 = dataset.getXValue(series, Math.min(item + 1, itemCount - 1));
    double y2 = dataset.getYValue(series, Math.min(item + 1, itemCount - 1));
    if (Double.isNaN(y2)) {
      y2 = 0.0;
    }
    double transX2 = domainAxis.valueToJava2D(x2, dataArea, plot.getDomainAxisEdge());
    double transY2 = rangeAxis.valueToJava2D(y2, dataArea, plot.getRangeAxisEdge());

    double transZero = rangeAxis.valueToJava2D(0.0, dataArea, plot.getRangeAxisEdge());
    Polygon hotspot = null;
    if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
      hotspot = new Polygon();
      hotspot.addPoint((int) transZero, (int) ((transX0 + transX1) / 2.0));
      hotspot.addPoint((int) ((transY0 + transY1) / 2.0), (int) ((transX0 + transX1) / 2.0));
      hotspot.addPoint((int) transY1, (int) transX1);
      hotspot.addPoint((int) ((transY1 + transY2) / 2.0), (int) ((transX1 + transX2) / 2.0));
      hotspot.addPoint((int) transZero, (int) ((transX1 + transX2) / 2.0));
    } else { // vertical orientation
      hotspot = new Polygon();
      hotspot.addPoint((int) ((transX0 + transX1) / 2.0), (int) transZero);
      hotspot.addPoint((int) ((transX0 + transX1) / 2.0), (int) ((transY0 + transY1) / 2.0));
      hotspot.addPoint((int) transX1, (int) transY1);
      hotspot.addPoint((int) ((transX1 + transX2) / 2.0), (int) ((transY1 + transY2) / 2.0));
      hotspot.addPoint((int) ((transX1 + transX2) / 2.0), (int) transZero);
    }

    if (item == 0) { // create a new area polygon for the series
      areaState.area = new Polygon();
      // the first point is (x, 0)
      double zero = rangeAxis.valueToJava2D(0.0, dataArea, plot.getRangeAxisEdge());
      if (plot.getOrientation() == PlotOrientation.VERTICAL) {
        areaState.area.addPoint((int) transX1, (int) zero);
      } else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
        areaState.area.addPoint((int) zero, (int) transX1);
      }
    }

    // Add each point to Area (x, y)
    if (plot.getOrientation() == PlotOrientation.VERTICAL) {
      areaState.area.addPoint((int) transX1, (int) transY1);
    } else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
      areaState.area.addPoint((int) transY1, (int) transX1);
    }

    PlotOrientation orientation = plot.getOrientation();
    Paint paint = getItemPaint(series, item);
    Stroke stroke = getItemStroke(series, item);
    g2.setPaint(paint);
    g2.setStroke(stroke);

    Shape shape = null;
    if (getPlotShapes()) {
      shape = getItemShape(series, item);
      if (orientation == PlotOrientation.VERTICAL) {
        shape = ShapeUtilities.createTranslatedShape(shape, transX1, transY1);
      } else if (orientation == PlotOrientation.HORIZONTAL) {
        shape = ShapeUtilities.createTranslatedShape(shape, transY1, transX1);
      }
      g2.draw(shape);
    }

    if (getPlotLines()) {
      if (item > 0) {
        if (plot.getOrientation() == PlotOrientation.VERTICAL) {
          areaState.line.setLine(transX0, transY0, transX1, transY1);
        } else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
          areaState.line.setLine(transY0, transX0, transY1, transX1);
        }
        g2.draw(areaState.line);
      }
    }

    // Check if the item is the last item for the series.
    // and number of items > 0.  We can't draw an area for a single point.
    if (getPlotArea() && item > 0 && item == (itemCount - 1)) {

      if (orientation == PlotOrientation.VERTICAL) {
        // Add the last point (x,0)
        areaState.area.addPoint((int) transX1, (int) transZero);
      } else if (orientation == PlotOrientation.HORIZONTAL) {
        // Add the last point (x,0)
        areaState.area.addPoint((int) transZero, (int) transX1);
      }

      g2.fill(areaState.area);

      // draw an outline around the Area.
      if (isOutline()) {
        g2.setStroke(getItemOutlineStroke(series, item));
        g2.setPaint(getItemOutlinePaint(series, item));
        g2.draw(areaState.area);
      }
    }

    updateCrosshairValues(crosshairState, x1, y1, transX1, transY1, orientation);

    // collect entity and tool tip information...
    if (state.getInfo() != null) {
      EntityCollection entities = state.getEntityCollection();
      if (entities != null && hotspot != null) {
        String tip = null;
        XYToolTipGenerator generator = getToolTipGenerator(series, item);
        if (generator != null) {
          tip = generator.generateToolTip(dataset, series, item);
        }
        String url = null;
        if (getURLGenerator() != null) {
          url = getURLGenerator().generateURL(dataset, series, item);
        }
        XYItemEntity entity = new XYItemEntity(hotspot, dataset, series, item, tip, url);
        entities.add(entity);
      }
    }
  }