如何强制XYChart刷新

时间:2018-04-04 22:41:35

标签: java javafx

我有两个图表绘制在同一个堆栈窗格中。

它们有共同的x和y轴,我想让它们可滚动。

以下是我编码的内容:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
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.stage.Stage;

/**
 * Demonstrates how to draw layers of XYCharts.
 * https://forums.oracle.com/forums/thread.jspa?threadID=2435995 "Using StackPane to layer more different type charts"
 */
public class LayeredXyChartsSample extends Application {

    private XYChart.Series<Number, Number> lineSeries1;
    private XYChart.Series<Number, Number> lineSeries2;

    private NumberAxis xAxis;
    private NumberAxis yAxis;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        initSeries();

        // Close the application when the window is closed
        stage.setOnCloseRequest(t -> {
            Platform.exit();
            System.exit(0);
        });

        stage.setScene(
                new Scene(
                        layerCharts(
                                createLineChart1(),
                                createLineChart2()
                        )
                )
        );
        stage.show();
    }

    @SuppressWarnings("unchecked")
    private void initSeries() {
        lineSeries1 = new XYChart.Series(
                FXCollections.observableArrayList(
                        new XYChart.Data(1, 2),
                        new XYChart.Data(2, 10),
                        new XYChart.Data(3, 8),
                        new XYChart.Data(4, 4),
                        new XYChart.Data(5, 7),
                        new XYChart.Data(6, 5),
                        new XYChart.Data(7, 4),
                        new XYChart.Data(8, 8),
                        new XYChart.Data(9, 16.5),
                        new XYChart.Data(10, 13.9),
                        new XYChart.Data(11, 17),
                        new XYChart.Data(12, 10)
                )
        );

        lineSeries2 = new XYChart.Series(
                FXCollections.observableArrayList(
                        new XYChart.Data(1, 1),
                        new XYChart.Data(2, 2),
                        new XYChart.Data(3, 1.5),
                        new XYChart.Data(4, 3),
                        new XYChart.Data(5, 2.5),
                        new XYChart.Data(6, 5),
                        new XYChart.Data(7, 4),
                        new XYChart.Data(8, 8),
                        new XYChart.Data(9, 6.5),
                        new XYChart.Data(10, 13),
                        new XYChart.Data(11, 10),
                        new XYChart.Data(12, 20)
                )
        );

        createXaxis();
        createYaxis();
    }

    private void createYaxis() {
        yAxis = new NumberAxis();
        yAxis.setAutoRanging(false);
        yAxis.setPrefWidth(35);
        yAxis.setMinorTickCount(10);
        yAxis.setLowerBound(0);
        yAxis.setUpperBound(20);
    }

    private void createXaxis() {
        xAxis = new NumberAxis();
        xAxis.setAutoRanging(false);
        xAxis.setLowerBound(-10);
        xAxis.setUpperBound(22);
    }

    @SuppressWarnings("unchecked")
    private LineChart<Number, Number> createLineChart1() {
        final LineChart<Number, Number> chart = new LineChart<>(xAxis, yAxis);
        setDefaultChartProperties(chart);
        chart.setCreateSymbols(false);
        chart.getData().addAll(lineSeries1);
        return chart;
    }

    @SuppressWarnings("unchecked")
    private LineChart<Number, Number> createLineChart2() {
        final LineChart<Number, Number> chart = new LineChart<>(xAxis, yAxis);
        setDefaultChartProperties(chart);
        chart.setCreateSymbols(false);
        chart.getData().addAll(lineSeries2);
        return chart;
    }

    private void setDefaultChartProperties(final XYChart<Number, Number> chart) {
        chart.setLegendVisible(false);
        chart.setAnimated(false);
    }

    @SafeVarargs
    private final StackPane layerCharts(final XYChart<Number, Number>... charts) {
        for (int i = 1; i < charts.length; i++) {
            configureOverlayChart(charts[i]);
        }

        StackPane stackpane = new StackPane();
        stackpane.getChildren().addAll(charts);

        stackpane.setOnScroll(event -> {
            double deltaX = event.getDeltaX();

            if (deltaX != 0) {
                xAxis.setUpperBound(xAxis.getUpperBound() + deltaX / 10);
                xAxis.setLowerBound(xAxis.getLowerBound() + deltaX / 10);
            }
        });

        return stackpane;
    }

    private void configureOverlayChart(final XYChart<Number, Number> chart) {
        chart.setAlternativeRowFillVisible(false);
        chart.setAlternativeColumnFillVisible(false);
        chart.setHorizontalGridLinesVisible(false);
        chart.setVerticalGridLinesVisible(false);
        chart.getXAxis().setVisible(false);
        chart.getYAxis().setVisible(false);

        chart.getStylesheets().addAll(getClass().getResource("/overlay-chart.css").toExternalForm());
    }
}

当我在侧面使用触控板滚动时,只刷新两个图形中的一个...

为什么?我想第二个图表也要更新,但我找不到XYChart类中的方法,我可以调用强制刷新。似乎这样做的所有方法都是私有的......

编辑:而不是在堆栈窗格上设置onScroll侦听器,我也尝试在两个图表上设置它。但似乎只有顶层布局才会收到通知......所以我有相同的结果:只有一个图表翻译......

Edit2:我知道在这个例子中,我可以创建一个包含两个系列的图表,而不是堆叠它们,这样就行了。但实际上,我使用的堆叠图表有不同的类型(折线图和自定义图表),所以我真的需要将它们堆叠在堆栈窗格中。

1 个答案:

答案 0 :(得分:0)

正如@James_D所建议的那样(非常感谢),解决方案是使用多个x轴并分别更新每个轴:

httpClient.Timeout = TimeSpan.FromMinutes(10);