Как я могу исправить масштаб моего lineChart в разделенной области? - PullRequest
1 голос
/ 22 мая 2019

Для моего проекта я должен реализовать масштабируемую линейную диаграмму.Я нашел много кодов увеличения, но ни один из них не работает.На самом деле, я думаю, что проблема в том, что мои окна разделены на множество окон, и в 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;
    }
}
...