从javaFX折线图中读取数据集

问题描述 投票:0回答:1

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

提前致谢。

javafx linechart
1个回答
0
投票

因为我相信你的问题可能是要求你的数据的视觉坐标或用于绘制图表的真实数据,我将为两者提供答案。


真实数据

LineChartXYChart延伸,有data property。此属性包含ObservableListXYChart.Series。每个XYChart.Series也有自己的data property。此属性包含ObservableListXYChart.Data。每个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,并将Circles添加到堆积在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上添加东西,那么操纵node propertyXYChart.Data可能会更好。

© www.soinside.com 2019 - 2024. All rights reserved.