我正在尝试设置一个折线图,以便当单击并拖动一个节点时,其值和位置会随着图表的相应调整而变化。我目前创建了一个由 4 个固定点组成的图表:
两个中间点稍后将添加到文本框中,其中 R=x 轴,S = y 轴。 是否可以拖动并移动中间点以便图表实时更新? 创建图的代码如下:
private void setContrastChart() {
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
LineChart<Number,Number> contrastChart =
new LineChart<>(xAxis,yAxis);
XYChart.Series series = new XYChart.Series();
series.setName("ContrastValues");
//populating the series with data
series.getData().add(new XYChart.Data(0, 0));
series.getData().add(new XYChart.Data(75, 75));
series.getData().add(new XYChart.Data(150, 150));
series.getData().add(new XYChart.Data(255, 255));
contrastChart.setMaxWidth(255);
contrastChart.setMaxHeight(255);
contrastChart.setLegendVisible(true);
chartHolder.getChildren().add(contrastChart);
contrastChart.getData().add(series);
txtR1.setText("75");
txtS1.setText("75");
txtR2.setText("150");
txtS2.setText("150");
}
最佳答案
快速而肮脏,但我相信这可以满足您的要求。需要注意的是,该点在运动时往往会明显抖动,并且不能很好地调整大小。我怀疑这些问题可以通过更多的故障排除来解决,但希望这能让您开始。
public class Main extends Application {
private Stage window;
private double chartMaxX;
private double chartMinX;
private double chartMaxY;
private double chartMinY;
@Override
public void start(Stage primaryStage) {
try {
window = primaryStage;
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
xAxis.setAutoRanging(false); //prevent automatic resizing for simplicity
yAxis.setAutoRanging(false); //prevent automatic resizing for simplicity
chartMaxX = 250.0;
chartMinX = 0.0;
chartMaxY = 300.0;
chartMinY = 0.0;
/*
* ranges of Axis are preset for simplicity, but could be altered without much trouble
*/
xAxis.setUpperBound(chartMaxX);
xAxis.setLowerBound(chartMinX);
yAxis.setUpperBound(chartMaxY);
yAxis.setLowerBound(chartMinY);
LineChart<Number,Number> contrastChart = new LineChart<>(xAxis,yAxis);
XYChart.Series<Number, Number> series = new XYChart.Series<>();
series.setName("ContrastValues");
//populating the series with data
Data<Number, Number> d0 = new Data<Number, Number>(10, 10);
Data<Number, Number> d1 = new Data<Number, Number>(75, 75);
Data<Number, Number> d2 = new Data<Number, Number>(150, 150);
Data<Number, Number> d3 = new Data<Number, Number>(240, 240);
series.getData().add(d0);
series.getData().add(d1);
series.getData().add(d2);
series.getData().add(d3);
contrastChart.setLegendVisible(true);
contrastChart.getData().add(series);
contrastChart.setAnimated(false); //prevent animations, as they will pull the point out of sync with the cursor.
for(Data<Number, Number> point: series.getData()) {
point.getNode().setOnMouseDragged(event -> {
Point2D translateXY = point.getNode().screenToLocal(event.getScreenX(), event.getScreenY());
point.setXValue(translateXY.getX()+point.getXValue().doubleValue());
point.setYValue(reverseNumberInRange(translateXY.getY()+(chartMaxY-point.getYValue().doubleValue()), chartMinY, chartMaxY));
});
}
//SCENE
Scene myScene = new Scene(contrastChart, chartMaxY, chartMaxX);
window.setScene(myScene);
window.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
public double reverseNumberInRange(double value, double minVal, double maxVal) {
/*
* y0 is top left on screen, and bottom left in chart, need to reverse.
*/
return (maxVal + minVal) - value;
}
}
关于JavaFX 折线图点操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54638542/