我们正在使用JFreeChart制作XY图,我们有一个功能请求来做一个与鼠标一起移动的十字准线,并突出显示最接近地映射到鼠标x值的数据点。您可以在Google财经中找到类似的示例 - http://www.google.com/finance?q=INDEXDJX:.DJI,INDEXSP:.INX,INDEXNASDAQ:.IXIC。
这些Google图表仅突出显示当前值(我们希望这样做并显示十字准线),但它们会显示我们正在寻找的实时鼠标交互。
任何人都有任何优雅的建议吗?
感谢。
答案 0 :(得分:4)
我使用鼠标监听器和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的一个实例。
答案 1 :(得分:1)
JFreeChart无法呈现图表的子部分,因此您需要执行不需要重新绘制图表的操作。您可以将图表写入BufferedImage并将其存储在内存中,然后使用自定义组件将缓冲图表用作背景图像,并在其上绘制十字准线和其他弹出窗口。
JFreeChart中有一些方法可以获取渲染图表上给定坐标的数据点。不记得这些是我的头脑。根据您的需要,您可能会考虑渲染自己的图表数据,这并不像您想象的那么难。
答案 2 :(得分:0)
我想到的第一件事就是编写自定义Cursor并将其设置在您的图表上。它可以引用图表并突出显示与Cursor的x / y位置一致的x值。
答案 3 :(得分: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)
{
}
}
}