Has anyone done crosshairs that follow the mouse in JFreeChart?
Asked Answered
D

4

7

We are using JFreeChart to make XY plots and we have a feature request to do a crosshair that moves along with the mouse and highlights the data point that most closely maps to the x-value of the mouse. You can see a similar example at Google Finance - http://www.google.com/finance?q=INDEXDJX:.DJI,INDEXSP:.INX,INDEXNASDAQ:.IXIC.

Those Google charts only highlight the current value (we want to do that and also show crosshairs), but they show the live mouse interaction we are looking for.

Anyone have any elegant suggestions?

Thanks.

Dyl answered 14/12, 2009 at 17:55 Comment(0)
D
5

I got this working using a mouse listener and the CrosshairOverlay class. After I get back from holiday travel, I will post my code. It ended up being not too difficult.


Sorry, I forgot about this!

First, you want to calculate the x, y values for where you want your crosshair. For me, I wanted it to move along the points of our line, so I calculated the closest x value and used that data pair for x, y.

Then I call this method:

protected void setCrosshairLocation(double x, Double y) {
    Crosshair domainCrosshair;
    List domainCrosshairs = crosshairOverlay.getDomainCrosshairs();
    if (domainCrosshairs.isEmpty()) {
        domainCrosshair = new Crosshair();
        domainCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0);
        crosshairOverlay.addDomainCrosshair(domainCrosshair);
    }
    else {
        // We only have one at a time
        domainCrosshair = (Crosshair) domainCrosshairs.get(0);
    }
    domainCrosshair.setValue(x);

    if (y != null) {
        Crosshair rangeCrosshair;
        List rangeCrosshairs = crosshairOverlay.getRangeCrosshairs();
        if (rangeCrosshairs.isEmpty()) {
            rangeCrosshair = new Crosshair();
            rangeCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0);
            crosshairOverlay.addRangeCrosshair(rangeCrosshair);
        }
        else {
            // We only have one at a time
            rangeCrosshair = (Crosshair) rangeCrosshairs.get(0);
        }

        rangeCrosshair.setValue(y);
    }
}

Note that crosshairOverlay is an instance of CrosshairOverlay.

Dyl answered 20/12, 2009 at 4:12 Comment(0)
M
1

JFreeChart can't render a sub-section of a chart, so you'll want to do something that doesn't require repainting the chart. You could write your chart to a BufferedImage and store that in memory, then have a custom component which uses the buffered chart as the background image, and draws crosshairs and other popup windows over it.

There are methods in JFreeChart to get the data point for a given coordinate on a rendered chart. Don't recall what these are off the top of my head. Depending on your needs, you might consider rendering your own chart data, it's not as hard as you'd think.

Mundane answered 14/12, 2009 at 18:47 Comment(0)
A
0

The first thing that comes to my mind would be to write a custom Cursor and set it on your chart. It can have a reference to the chart and highlight the x value that's consistent with the Cursor's x/y location.

Alkalimeter answered 14/12, 2009 at 18:5 Comment(0)
A
0

This worked for me. I set the

chartPanel.addChartMouseListener(new ChartMouseListener() {
public void chartMouseMoved(ChartMouseEvent event)
    {
    try
    {
        double[] values = getCrossHairValue(event);

        plot.clearRangeMarkers();
        plot.clearDomainMarkers();

        Marker yMarker = new ValueMarker(values[1]);
        yMarker.setPaint(Color.darkGray);
        plot.addRangeMarker(yMarker);

        Marker xMarker = new ValueMarker(values[0]);
        xMarker.setPaint(Color.darkGray);
        plot.addDomainMarker(xMarker);

        chartPanel.repaint();
    } catch (Exception e)
    {

    }
    }

}

Alanaalanah answered 2/2, 2012 at 14:31 Comment(2)
What about getCrossHairValue method? Where does it come from?Hither
I think that just returns: int mouseX = event.getTrigger().getX(); int mouseY = event.getTrigger().getY(); Grover

© 2022 - 2024 — McMap. All rights reserved.