XYDotRenderer has no tooltips

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Naxter
Posts: 45
Joined: Thu Jun 26, 2014 8:24 am
antibot: No, of course not.
Location: Germany, Aachen

XYDotRenderer has no tooltips

Post by Naxter » Thu Oct 29, 2015 1:08 pm

Hey guys!

I have to use the XYDotRenderer and everything works perfect. The only problem i noticed is, that the BaseToolTipGenerator does not work for this renderer. I read that this is caused because the XYDotRendere does not support chart entities.
Is there a common way to get tooltips for my data point? Is there maybe someone who had the same problem?

Thank you for your help!

Here is the code, which works for the XYLineAndShapeRenderer and I tried to apply this for XYDotRenderer:

Code: Select all

dotRenderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()
    {
      private static final long serialVersionUID = 5390307268371711543L;

      @Override
      public String generateToolTip(XYDataset dataset, int series, int item)
      {
        Double xValue = dataset.getXValue(series, item);
        Double yValue = dataset.getYValue(series, item);

        String label = "("
            + NumberUtils.format(xValue)
            + " / "
            + NumberUtils.format(yValue) + ")";
        return label;
      }

    });

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: XYDotRenderer has no tooltips

Post by david.gilbert » Sat Oct 31, 2015 8:17 am

The XYDotRenderer doesn't support tooltips. It was originally added as a faster and more light-weight alternative to XYLineAndShapeRenderer for generating scatter plots with larger datasets. XYLineAndShapeRenderer will draw custom shapes, optionally with different fill and outline colours, and will add hotspot data to support tooltips and chart mouse events. That all takes rendering time and memory. By skipping that and just rendering each data point as a simple rectangle, XYDotRenderer can be a lot faster.

You could modify the code to add the hotspot support and tooltip generation...just take a look at how it is done in XYLineAndShapeRenderer.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

Naxter
Posts: 45
Joined: Thu Jun 26, 2014 8:24 am
antibot: No, of course not.
Location: Germany, Aachen

Re: XYDotRenderer has no tooltips

Post by Naxter » Wed Nov 04, 2015 8:06 am

Thanks David, I will give it a try.

Naxter
Posts: 45
Joined: Thu Jun 26, 2014 8:24 am
antibot: No, of course not.
Location: Germany, Aachen

Re: XYDotRenderer has no tooltips

Post by Naxter » Wed Nov 04, 2015 10:09 am

This is what the drawItem method looks like right now. I just tested it and it works fine.
I guess it is not the best solution, but I just copied the important parts of the XYLineAndShapeRenderer to the XYDotRenderer.

Code: Select all

/**
	 * 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 (horizontal) axis.
	 * @param rangeAxis
	 *            the range (vertical) 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.
	 */
	@Override
	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) {

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

		// get the data point...
		double x = dataset.getXValue(series, item);
		double y = dataset.getYValue(series, item);
		double adjx = (this.dotWidth - 1) / 2.0;
		double adjy = (this.dotHeight - 1) / 2.0;
		if (!Double.isNaN(y)) {
			RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
			RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
			double transX = domainAxis.valueToJava2D(x, dataArea, xAxisLocation) - adjx;
			double transY = rangeAxis.valueToJava2D(y, dataArea, yAxisLocation) - adjy;

			g2.setPaint(getItemPaint(series, item));
			PlotOrientation orientation = plot.getOrientation();
			if (orientation == PlotOrientation.HORIZONTAL) {
				g2.fillRect((int) transY, (int) transX, this.dotHeight, this.dotWidth);
			} else if (orientation == PlotOrientation.VERTICAL) {
				g2.fillRect((int) transX, (int) transY, this.dotWidth, this.dotHeight);
			}

			int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
			int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);

			Shape entityArea = null;
			double transX1 = domainAxis.valueToJava2D(x, dataArea, xAxisLocation);
			double transY1 = rangeAxis.valueToJava2D(y, dataArea, yAxisLocation);

			if (getItemVisible(series, item)) {
				Shape shape = getItemShape(series, item);
				if (orientation == PlotOrientation.HORIZONTAL) {
					shape = ShapeUtilities.createTranslatedShape(shape, transY1, transX1);
				} else if (orientation == PlotOrientation.VERTICAL) {
					shape = ShapeUtilities.createTranslatedShape(shape, transX1, transY1);
				}
				entityArea = shape;

			}
			double xx = transX1;
			double yy = transY1;
			if (orientation == PlotOrientation.HORIZONTAL) {
				xx = transY1;
				yy = transX1;
			}

			EntityCollection entities = null;
			if (info != null && info.getOwner() != null) {
				entities = info.getOwner().getEntityCollection();
			}

			if (entities != null && isPointInRect(dataArea, xx, yy)) {
				addEntity(entities, entityArea, dataset, series, item, xx, yy);
			}

			updateCrosshairValues(crosshairState, x, y, domainAxisIndex, rangeAxisIndex, transX, transY, orientation);
		}

	}

Locked