Сделать видимыми старые данные при перетаскивании линейной диаграммы (слева) - PullRequest
0 голосов
/ 19 февраля 2019

Моя задача - построить график в реальном времени, в котором пользователь может остановить рисование (анимацию) и вернуться к старым данным с помощью введения наркотика мышью (слева).Я пытаюсь разработать пример графика линии запаса из примеров Oracle Ensemle.
Я пишу два метода: 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...