如何在JavaFX图表中添加值标记?

我正在尝试使用JavaFX构建一个系列图表,其中数据是动态插入的。

每次插入新值时,我想检查这是否是目前为止的最高值,如果是,我想绘制一条水平线以显示这是最大值。

在JFree图表中,我会使用ValueMarker,但我也尝试使用JavaFX。

我尝试使用Line对象,但它绝对不一样,因为我无法提供Chart值,它需要窗口中的相对像素位置。

这是我想要实现的图表的屏幕截图:

http://postimg.org/image/s5fkupsuz/

有什么建议么? 谢谢。

要将图表值转换为像素,您可以使用方法NumberAxis#getDisplayPosition()返回图表节点的实际坐标。

虽然这些坐标是相对于图表区域的,您可以通过下一个代码找到它:

 Node chartArea = chart.lookup(".chart-plot-background"); Bounds chartAreaBounds = chartArea.localToScene(chartArea.getBoundsInLocal()); 

请注意localToScene()方法,它允许您将任何坐标转换为场景坐标。 因此,您可以使用它们来更新您的值标记坐标。 确保在显示场景后进行localToScene调用。

请参阅下面的示例程序,其中包

在此处输入图像描述

 public class LineChartValueMarker extends Application { private Line valueMarker = new Line(); private XYChart.Series series = new XYChart.Series<>(); private NumberAxis yAxis; private double yShift; private void updateMarker() { // find maximal y value double max = 0; for (Data value : series.getData()) { double y = value.getYValue().doubleValue(); if (y > max) { max = y; } } // find pixel position of that value double displayPosition = yAxis.getDisplayPosition(max); // update marker valueMarker.setStartY(yShift + displayPosition); valueMarker.setEndY(yShift + displayPosition); } @Override public void start(Stage stage) { LineChart chart = new LineChart<>(new NumberAxis(0, 100, 10), yAxis = new NumberAxis(0, 100, 10)); series.getData().add(new XYChart.Data(0, 0)); series.getData().add(new XYChart.Data(10, 20)); chart.getData().addAll(series); Pane pane = new Pane(); pane.getChildren().addAll(chart, valueMarker); Scene scene = new Scene(pane); // add new value on mouseclick for testing chart.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent t) { series.getData().add(new XYChart.Data(series.getData().size() * 10, 30 + 50 * new Random().nextDouble())); updateMarker(); } }); stage.setScene(scene); stage.show(); // find chart area Node Node chartArea = chart.lookup(".chart-plot-background"); Bounds chartAreaBounds = chartArea.localToScene(chartArea.getBoundsInLocal()); // remember scene position of chart area yShift = chartAreaBounds.getMinY(); // set x parameters of the valueMarker to chart area bounds valueMarker.setStartX(chartAreaBounds.getMinX()); valueMarker.setEndX(chartAreaBounds.getMaxX()); updateMarker(); } public static void main(String[] args) { launch(); } }