7

我们正在使用 JFreeChart 制作 XY 图,并且我们有一个功能请求来做一个与鼠标一起移动的十字准线,并突出显示最接近映射到鼠标 x 值的数据点。您可以在 Google 财经上看到类似的示例 - http://www.google.com/finance?q=INDEXDJX:.DJI,INDEXSP:.INX,INDEXNASDAQ:.IXIC

那些 Google 图表仅突出显示当前值(我们希望这样做并显示十字准线),但它们显示了我们正在寻找的实时鼠标交互。

有人有什么优雅的建议吗?

谢谢。

4

4 回答 4

5

我使用鼠标侦听器和 CrosshairOverlay 类完成了这项工作。假期旅行回来后,我将发布我的代码。结果并不太难。


对不起,我忘了这个!

首先,您要计算十字准线所在位置的 x、y 值。对我来说,我希望它沿着我们线的点移动,所以我计算了最接近的 x 值并将该数据对用于 x,y。

然后我调用这个方法:

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

请注意,crosshairOverlay 是 CrosshairOverlay 的一个实例。

于 2009-12-20T04:12:52.970 回答
1

JFreeChart 无法呈现图表的子部分,因此您需要做一些不需要重新绘制图表的事情。您可以将图表写入 BufferedImage 并将其存储在内存中,然后有一个自定义组件使用缓冲图表作为背景图像,并在其上绘制十字准线和其他弹出窗口。

JFreeChart 中有一些方法可以获取渲染图表上给定坐标的数据点。不记得这些在我脑海中是什么。根据您的需要,您可能会考虑渲染自己的图表数据,这并不像您想象的那么难。

于 2009-12-14T18:47:15.863 回答
0

我首先想到的是编写一个自定义光标并将其设置在您的图表上。它可以引用图表并突出显示与光标的 x/y 位置一致的 x 值。

于 2009-12-14T18:05:09.257 回答
0

这对我有用。我设置

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)
    {

    }
    }

}

于 2012-02-02T14:31:47.700 回答