从javaFX线图中读取数据集

时间:2018-06-21 10:22:34

标签: javafx linechart

我在应用程序中使用JavaFX Linechart。我想从显示器上读取图形的X和Y轴。我的意思是从图中。 我怎样才能做到这一点?  我想将值保存在ArrayList / Array中。

谢谢。

1 个答案:

答案 0 :(得分:0)

由于我相信您的问题可能是要查询数据的视觉坐标 还是用于绘制图表的实际数据?将为这两个问题提供答案。


真实数据

LineChart从具有XYChartdata property扩展而来。此属性包含XYChart.Series中的ObservableList。每个XYChart.Series 也有自己的data property属性包含XYChart.Data中的ObservableList。每个XYChart.Data都有一个property for its X value和一个property for its Y value。访问这些属性以获取用于绘制图形的X和Y值。

由于图表已经包含您要在集合中查找的数据,因此可能无需将其添加到单独的ArrayList或数组中。


视觉坐标

XYChart(也是LineChart的延伸)具有a X axisa Y axis。这些类型为Axis,提供以下方法:getDisplayPosition(Object)。该方法将绘制在轴上的实际数据作为参数。例如,如果绘制了点(4,16),则可以通过以下方式获得显示位置:

  • 对于X坐标:chart.getXAxis().getDisplayPosition(4);
  • 对于Y坐标:chart.getYAxis().getDisplayPosition(16);

使用LineChart(以及其他可能的其他图表,但我仅使用LineChart进行了测试)时,这些坐标相对于LineChart 。相反,它们相对于具有Region样式类的子项chart-plot-background(至少在我的测试中)。这是我用来测试获得视觉坐标的代码。它使用{0-10]的指数函数创建一个LineChart,并将Circle添加到堆积在Group顶部的LineChart上,位置与绘制的位置相同数据。

注意:我在Java 10中大量使用了var关键字。您将需要Java 10+来运行它,或者需要替换var具有明确类型的关键字

import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.animation.ParallelTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        var chart = createChart();

        var group = new Group();
        group.setManaged(false);
        primaryStage.setOnShown(we -> addFadingCircles(group, chart));

        var root = new StackPane(chart, group);
        var scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Workshop");
        primaryStage.setResizable(false);
        primaryStage.show();

    }

    private LineChart<Number, Number> createChart() {
        var xAxis = new NumberAxis();
        xAxis.setLabel("X");

        var yAxis = new NumberAxis();
        yAxis.setLabel("Y");

        var chart = new LineChart<>(xAxis, yAxis);
        var series = new XYChart.Series<Number, Number>();

        for (int x = 0; x <= 10; x++) {
            series.getData().add(new XYChart.Data<>(x, Math.pow(x, 2)));
        }

        chart.getData().add(series);
        return chart;
    }

    /*
     * This method assumes that "group" is stacked on top of "chart" and takes up the
     * same area in the scene-graph.
     */
    private void addFadingCircles(Group group, LineChart<Number, Number> chart) {
        var animation = new ParallelTransition();
        animation.setAutoReverse(true);
        animation.setCycleCount(Animation.INDEFINITE);

        var plotRegion = chart.lookup(".chart-plot-background");

        for (var series : chart.getData()) {
            for (var data : series.getData()) {
                var xPos = chart.getXAxis().getDisplayPosition(data.getXValue());
                var yPos = chart.getYAxis().getDisplayPosition(data.getYValue());

                var scenePoint = plotRegion.localToScene(xPos, yPos);
                var groupPoint = group.sceneToLocal(scenePoint);

                var circle = new Circle(groupPoint.getX(), groupPoint.getY(), 10);
                circle.setFill(Color.DEEPSKYBLUE);

                var fadeTrans = new FadeTransition(Duration.millis(500), circle);
                fadeTrans.setFromValue(0.0);
                fadeTrans.setToValue(0.8);
                animation.getChildren().add(fadeTrans);

                group.getChildren().add(circle);
            }
        }

        animation.play();
    }

}

运行此代码会导致:

GIF animation of circles stacked on top of LineChart's plotted data

但是,如果您的目标是在用于表示绘制数据的Node中添加内容,则最好操纵XYChart.Data中的node property