Java 如何修复拆分窗格中的折线图缩放比例?

Java 如何修复拆分窗格中的折线图缩放比例?,java,javafx,zooming,scenebuilder,Java,Javafx,Zooming,Scenebuilder,对于我的项目,我必须实现一个可缩放的折线图。我发现了很多zoom的代码,但都不起作用。事实上,我认为问题在于我的窗口被划分为许多窗口,其中4个窗口中有图表。因此,缩放看起来很有效,但当我使用缩放时,新轴不是它应该是的: 1) 我正在选择要缩放的位置: 2) 图表正在使用新轴“重新加载”: 公共类ZoomableLineChart扩展了折线图{ 私有最终区域userTrackArea=新区域(); XYChart.系列; 双值x; 双重价值; 边界窗格图表容器; 公共缩放线性图表(X轴、Y轴、

对于我的项目,我必须实现一个可缩放的折线图。我发现了很多zoom的代码,但都不起作用。事实上,我认为问题在于我的窗口被划分为许多窗口,其中4个窗口中有图表。因此,缩放看起来很有效,但当我使用缩放时,新轴不是它应该是的:

1) 我正在选择要缩放的位置:

2) 图表正在使用新轴“重新加载”:

公共类ZoomableLineChart扩展了折线图{
私有最终区域userTrackArea=新区域();
XYChart.系列;
双值x;
双重价值;
边界窗格图表容器;
公共缩放线性图表(X轴、Y轴、XYChart.系列、边框窗格边框、双值X、双值Y){
超级(xAxis,yAxis);
this.chartContainer=边框;
this.valueX=valueX;
this.valueX=valueX;
最终折线图=createChart();
chart.getData().add(系列);
最终StackPane StackChartContainer=新的StackPane();
StackChartContainer.getChildren().add(图表);
StackChartContainer.setOnMouseClicked(this::handleMouseTrackingClicked);
最终矩形zoomRect=新矩形();
zoomRect.setManaged(假);
zoomRect.setFill(颜色、浅海绿、衍生色(0,1,1,0.5));
StackChartContainer.getChildren().add(zoomRect);
设置缩放(缩放、图表);
最终HBox对照=新HBox();
对照组:设置起搏(10);
控件。设置填充(新插图(10));
控件。设置对齐(位置中心);
最终按钮zoomButton=新按钮(“缩放”);
最终按钮重置按钮=新按钮(“重置”);
setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
doZoom(缩放、图表);
}
});
setButton.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
最终的NumberAxis xAxis=(NumberAxis)chart.getXAxis();
xAxis.setLowerBound(0);
xAxis.setUpperBound(100);
最终的NumberAxis-yAxis=(NumberAxis)chart.getYAxis();
yAxis.setLowerBound(0);
yAxis.setUpperBound(100);
zoomRect.setWidth(0);
zoomRect.setHeight(0);
}
});
最终布尔绑定禁用控件=
zoomRect.widthProperty().lessThan(5)
.或(zoomRect.heightProperty().小于(5));
zoomButton.disableProperty().bind(disableControls);
控件.getChildren().add(zoomButton);
控件.getChildren().add(重置按钮);
边框设置中心(StackChartContainer);
border.setBottom(控制);
}    
已单击private void HandleMouseTracking(最终MouseeEvent MouseeEvent){
最终的NumberAxis xAxis=(NumberAxis)getXAxis();
最终的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(“鼠标%f%f->值%f(%f%f)%f(%f%f)”,mouseX,mouseY,
//valueX,xAxis.getLowerBound(),xAxis.getUpperBound(),
//valueY,yAxis.getLowerBound(),yAxis.getUpperBound()).println();
System.out.println(valueX+“,”+valueY);
}
公共静态BorderPane creerGrapheZoomable(XYChart.Series系列,BorderPane chartContainer){
最终折线图=createChart();
chart.getData().add(系列);
最终StackPane StackChartContainer=新的StackPane();
StackChartContainer.getChildren().add(图表);
最终矩形zoomRect=新矩形();
zoomRect.setManaged(假);
zoomRect.setFill(颜色、浅海绿、衍生色(0,1,1,0.5));
StackChartContainer.getChildren().add(zoomRect);
设置缩放(缩放、图表);
最终HBox对照=新HBox();
对照组:设置起搏(10);
控件。设置填充(新插图(10));
控件。设置对齐(位置中心);
最终按钮zoomButton=新按钮(“缩放”);
最终按钮重置按钮=新按钮(“重置”);
setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
doZoom(缩放、图表);
}
});
setButton.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
最终的NumberAxis xAxis=(NumberAxis)chart.getXAxis();
xAxis.setLowerBound(0);
xAxis.setUpperBound(100);
最终的NumberAxis-yAxis=(NumberAxis)chart.getYAxis();
yAxis.setLowerBound(0);
yAxis.setUpperBound(100);
zoomRect.setWidth(0);
zoomRect.setHeight(0);
}
});
最终布尔绑定禁用控件=
zoomRect.widthProperty().lessThan(5)
.或(zoomRect.heightProperty().小于(5));
zoomButton.disableProperty().bind(disableControls);
控件.getChildren().add(zoomButton);
控件.getChildren().add(重置按钮);
setCenter(StackChartContainer);
chartContainer.setBottom(控件);
返回集装箱;
}
专用静态折线图createChart(){
最终数字axis xAxis=createAxis();
最终数字axis yAxis=createAxis();
最终线形图=新线形图(xAxis,yAxis);
图表.设置动画(假);
chart.setCreateSynumbles(false);
返回字符
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;
    }
}