我在应用程序中使用JavaFX Linechart。我想从显示器上读取图形的X和Y轴。我的意思是从图中。 我怎样才能做到这一点? 我想将值保存在ArrayList / Array中。
谢谢。
答案 0 :(得分:0)
由于我相信您的问题可能是要查询数据的视觉坐标 还是用于绘制图表的实际数据?将为这两个问题提供答案。
LineChart
从具有XYChart
的data 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 axis和a Y axis。这些类型为Axis
,提供以下方法:getDisplayPosition(Object)
。该方法将绘制在轴上的实际数据作为参数。例如,如果绘制了点(4,16),则可以通过以下方式获得显示位置:
chart.getXAxis().getDisplayPosition(4);
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();
}
}
运行此代码会导致:
但是,如果您的目标是在用于表示绘制数据的Node
中添加内容,则最好操纵XYChart.Data
中的node property。