在拖动Linechart时使可见的旧数据(向左)

时间:2019-02-19 17:34:09

标签: java javafx charts drag-and-drop

我的任务是构建实时图表,用户可以在该图表上停止绘制(动画)并借助鼠标下注(左侧)返回到旧数据。我尝试从Ensemle Oracle示例中开发股票折线图示例。
我编写了两个方法:updateXAxisBounds和addScrollAndMouseDragListeners,拖动效果很好,但是旧数据不在图表中(只有新数据已更新,而旧数据却消失了,您可以在图片中看到-底部的链接,新值之前的图表为空图表广场)。帮助,请在用户拖动到左侧时显示可见的旧数据。可能需要添加更多动画吗?

public class StockLineChartApp extends Application {

    private LineChart<Number, Number> chart;
    private Series<Number, Number> hourDataSeries;
    private NumberAxis xAxis;
    private Timeline animation;
    private double hours = 0;
    private double minutes = 0;
    private double timeInHours = 0;
    private double prevY = 10;
    private double y = 10;

    public StockLineChartApp() {
        // 6 minutes data per frame
        final KeyFrame frame =
            new KeyFrame(Duration.millis(1000 / 60),
                         (ActionEvent actionEvent) -> {
                             for (int count = 0; count < 6; count++) {
                                 nextTime();
                                 plotTime();
                             }
                         });
        // create timeline to add new data every 60th of second
        animation = new Timeline();
        animation.getKeyFrames().add(frame);
        animation.setCycleCount(Animation.INDEFINITE);
    }

    public Parent createContent() {
        xAxis = new NumberAxis(0, 24, 3);
        final NumberAxis yAxis = new NumberAxis(0, 100, 10);
        chart = new LineChart<>(xAxis, yAxis);
        // setup chart
//        final String stockLineChartCss =            getClass().getResource("StockLineChart.css").toExternalForm();
//        chart.getStylesheets().add(stockLineChartCss);
        chart.setCreateSymbols(false);
        chart.setAnimated(false);
        chart.setLegendVisible(false);
        chart.setTitle("ACME Company Stock");
        xAxis.setLabel("Time");
        xAxis.setForceZeroInRange(false);
        yAxis.setLabel("Share Price");
        yAxis.setTickLabelFormatter(new DefaultFormatter(yAxis, "$", null));
        // add starting data
        hourDataSeries = new Series<>();
        hourDataSeries.setName("Hourly Data");
        // create some starting data
        hourDataSeries.getData().add(new Data<Number, Number>(timeInHours,
                                                              prevY));
        for (double m = 0; m < (60); m++) {
            nextTime();
            plotTime();
        }
        chart.getData().add(hourDataSeries);
return chart;
    }

    private void nextTime() {
        if (minutes == 59) {
            hours++;
            minutes = 0;
        } else {
            minutes++;
        }
        timeInHours = hours + ((1d / 60d) * minutes);
    }

    private void plotTime() {

        //HERE there is the random algorithm of y calculation
            // every hour after 24 move range 1 hour
            if (timeInHours > 24) {
                xAxis.setLowerBound(xAxis.getLowerBound() + 1);
                xAxis.setUpperBound(xAxis.getUpperBound() + 1);
            }
        }
    }

    public void play() {
        animation.play();
    }

    @Override
    public void stop() {
        animation.pause();
    }

    @Override public void start(Stage primaryStage) throws Exception {
        VBox vBox = new VBox();
        vBox.getChildren().add(createContent());
        addScrollAndMouseDragListeners(chart,xAxis,vBox);

        primaryStage.setScene(new Scene(vBox));
        primaryStage.show();
        play();
    }

    private static void addScrollAndMouseDragListeners(final LineChart<Number, Number> chart, final NumberAxis xAxis, final Pane chartsPanel) {
        chart.setOnScroll((ScrollEvent event) -> {
            event.consume();
            if (event.getDeltaY() == 0)
                return;
            final double SCALE_DELTA = 50;
            double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : -SCALE_DELTA;
            double delta = (xAxis.getUpperBound() - xAxis.getLowerBound()) / scaleFactor;
            updateXAxisBounds(xAxis.getLowerBound() + delta, xAxis.getUpperBound() - delta, chartsPanel);
        });

        final double[] startValues = new double[3];

        chart.setOnMousePressed((MouseEvent event) -> {
            event.consume();
            startValues[0] = event.getX();
            startValues[1] = xAxis.getLowerBound();
            startValues[2] = xAxis.getUpperBound();
        });

        chart.setOnMouseDragged((MouseEvent event) -> {
            event.consume();
            final double unitPerPixel = (xAxis.getUpperBound() - xAxis.getLowerBound()) / xAxis.getWidth();
            final double dx = (event.getX() - startValues[0]) * unitPerPixel;
            updateXAxisBounds(startValues[1] - dx, startValues[2] - dx, chartsPanel);
        });
    }

    private static void updateXAxisBounds(final double lowerBound, final double upperBound, final Pane chartsPanel) {
        for (final Node child : chartsPanel.getChildren()) {
            final NumberAxis axis = (NumberAxis) ((LineChart) child).getXAxis();
            axis.setAutoRanging(false);
            axis.setLowerBound(lowerBound);
            axis.setUpperBound(upperBound);
        }
    }

    /**
     * Java main for when running without JavaFX launcher
     * @param args command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

上药期间图表的屏幕截图如下:https://i.stack.imgur.com/Cdz8s.png

0 个答案:

没有答案