Для моего проекта я должен реализовать масштабируемую линейную диаграмму.Я нашел много кодов увеличения, но ни один из них не работает.На самом деле, я думаю, что проблема в том, что мои окна разделены на множество окон, и в 4 из этих окон есть диаграммы.Таким образом, масштабирование выглядит так, как будто оно работает, но когда я использую масштабирование, новая ось не соответствует предполагаемой:
1) Я выбираю, где я хочу увеличить: https://imgur.com/a/j6LwrsH
2) график «перезагружается» с новой осью: https://imgur.com/a/SyeqnEV
public class ZoomableLineChart<X extends Number, Y extends Number> extends LineChart<X, Y> {
private final Region userTrackArea = new Region();
XYChart.Series series;
double valueX;
double valueY;
BorderPane chartContainer;
public ZoomableLineChart( Axis xAxis, Axis yAxis, XYChart.Series series, BorderPane border, double valueX, double valueY ) {
super(xAxis, yAxis);
this.chartContainer = border;
this.valueX = valueX;
this.valueX = valueX;
final LineChart<Number, Number> chart = createChart();
chart.getData().add(series);
final StackPane StackChartContainer = new StackPane();
StackChartContainer.getChildren().add(chart);
StackChartContainer.setOnMouseClicked(this::handleMouseTrackingClicked);
final Rectangle zoomRect = new Rectangle();
zoomRect.setManaged(false);
zoomRect.setFill(Color.LIGHTSEAGREEN.deriveColor(0, 1, 1, 0.5));
StackChartContainer.getChildren().add(zoomRect);
setUpZooming(zoomRect, chart);
final HBox controls = new HBox();
controls.setSpacing(10);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
final Button zoomButton = new Button("Zoom");
final Button resetButton = new Button("Reset");
zoomButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
doZoom(zoomRect, chart);
}
});
resetButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
final NumberAxis xAxis = (NumberAxis)chart.getXAxis();
xAxis.setLowerBound(0);
xAxis.setUpperBound(100);
final NumberAxis yAxis = (NumberAxis)chart.getYAxis();
yAxis.setLowerBound(0);
yAxis.setUpperBound(100);
zoomRect.setWidth(0);
zoomRect.setHeight(0);
}
});
final BooleanBinding disableControls =
zoomRect.widthProperty().lessThan(5)
.or(zoomRect.heightProperty().lessThan(5));
zoomButton.disableProperty().bind(disableControls);
controls.getChildren().add(zoomButton);
controls.getChildren().add(resetButton);
border.setCenter(StackChartContainer);
border.setBottom(controls);
}
private void handleMouseTrackingClicked(final MouseEvent mouseEvent) {
final NumberAxis xAxis = (NumberAxis) getXAxis();
final NumberAxis yAxis = (NumberAxis) getYAxis();
final double mouseX = mouseEvent.getX();
final double mouseY = mouseEvent.getY();
valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
valueY = yAxis.getValueForDisplay(mouseY).doubleValue();
// System.out.printf("Mouse %f %f -> value %f (%f %f) %f (%f %f)", mouseX, mouseY,
// valueX, xAxis.getLowerBound(), xAxis.getUpperBound(),
// valueY, yAxis.getLowerBound(), yAxis.getUpperBound()).println();
System.out.println(valueX + "," + valueY);
}
public static BorderPane creerGrapheZoomable(XYChart.Series series, BorderPane chartContainer) {
final LineChart<Number, Number> chart = createChart();
chart.getData().add(series);
final StackPane StackChartContainer = new StackPane();
StackChartContainer.getChildren().add(chart);
final Rectangle zoomRect = new Rectangle();
zoomRect.setManaged(false);
zoomRect.setFill(Color.LIGHTSEAGREEN.deriveColor(0, 1, 1, 0.5));
StackChartContainer.getChildren().add(zoomRect);
setUpZooming(zoomRect, chart);
final HBox controls = new HBox();
controls.setSpacing(10);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
final Button zoomButton = new Button("Zoom");
final Button resetButton = new Button("Reset");
zoomButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
doZoom(zoomRect, chart);
}
});
resetButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
final NumberAxis xAxis = (NumberAxis)chart.getXAxis();
xAxis.setLowerBound(0);
xAxis.setUpperBound(100);
final NumberAxis yAxis = (NumberAxis)chart.getYAxis();
yAxis.setLowerBound(0);
yAxis.setUpperBound(100);
zoomRect.setWidth(0);
zoomRect.setHeight(0);
}
});
final BooleanBinding disableControls =
zoomRect.widthProperty().lessThan(5)
.or(zoomRect.heightProperty().lessThan(5));
zoomButton.disableProperty().bind(disableControls);
controls.getChildren().add(zoomButton);
controls.getChildren().add(resetButton);
chartContainer.setCenter(StackChartContainer);
chartContainer.setBottom(controls);
return chartContainer;
}
private static LineChart<Number, Number> createChart() {
final NumberAxis xAxis = createAxis();
final NumberAxis yAxis = createAxis();
final LineChart<Number, Number> chart = new LineChart<>(xAxis, yAxis);
chart.setAnimated(false);
chart.setCreateSymbols(false);
return chart ;
}
private static NumberAxis createAxis() {
final NumberAxis xAxis = new NumberAxis();
xAxis.setAutoRanging(false);
xAxis.setLowerBound(0);
xAxis.setUpperBound(100);
return xAxis;
}
private static void setUpZooming(final Rectangle rect, final Node zoomingNode) {
final ObjectProperty<Point2D> mouseAnchor = new SimpleObjectProperty<>();
zoomingNode.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
System.out.println("Mouse Event OK");
mouseAnchor.set(new Point2D(event.getX(), event.getY()));
System.out.println(event.getX() + " " + event.getY() );
rect.setWidth(0);
rect.setHeight(0);
}
});
zoomingNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
double x = event.getX();
double y = event.getY();
rect.setX(Math.min(x, mouseAnchor.get().getX()));
rect.setY(Math.min(y, mouseAnchor.get().getY()));
System.out.println(x + ' ' + y);
rect.setWidth(Math.abs(x - mouseAnchor.get().getX()));
rect.setHeight(Math.abs(y - mouseAnchor.get().getY()));
}
});
}
private static void doZoom(Rectangle zoomRect, LineChart<Number, Number> chart) {
Point2D zoomTopLeft = new Point2D(zoomRect.getX(), zoomRect.getY());
Point2D zoomBottomRight = new Point2D(zoomRect.getX() + zoomRect.getWidth(), zoomRect.getY() + zoomRect.getHeight());
final NumberAxis yAxis = (NumberAxis) chart.getYAxis();
Point2D yAxisInScene = yAxis.localToScene(0, 0);
final NumberAxis xAxis = (NumberAxis) chart.getXAxis();
Point2D xAxisInScene = xAxis.localToScene(0, 0);
double xOffset = zoomTopLeft.getX() - yAxisInScene.getX() ;
double yOffset = zoomBottomRight.getY() - xAxisInScene.getY();
double xAxisScale = xAxis.getScale();
double yAxisScale = yAxis.getScale();
xAxis.setLowerBound(xAxis.getLowerBound() + xOffset / xAxisScale);
xAxis.setUpperBound(xAxis.getLowerBound() + zoomRect.getWidth() / xAxisScale);
yAxis.setLowerBound(yAxis.getLowerBound() + yOffset / yAxisScale);
yAxis.setUpperBound(yAxis.getLowerBound() - zoomRect.getHeight() / yAxisScale);
System.out.println(yAxis.getLowerBound() + " , " + yAxis.getUpperBound());
zoomRect.setWidth(0);
zoomRect.setHeight(0);
}
public int getValueX() {
return (int) valueX;
}
public int getValueY() {
return (int) valueY;
}
}