Line Chart Live update

前端 未结 2 1357
说谎
说谎 2020-12-03 19:03

Live update Line Chart

I want to modify this simple example of Line Chart and add live update.

import javafx.application.Application;
import javafx.s         


        
相关标签:
2条回答
  • 2020-12-03 19:55

    Based on JewelSea's example on AnimatedAreaChart, I modified it to make a similar example for you based on LineGraph. Please have a look at the example, hope it satisfies your need!

    import javafx.animation.AnimationTimer;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.stage.Stage;
    
    import java.util.concurrent.ConcurrentLinkedQueue;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadFactory;
    
    
    public class AnimatedLineChart extends Application {
    
        private static final int MAX_DATA_POINTS = 50;
        private int xSeriesData = 0;
        private XYChart.Series<Number, Number> series1 = new XYChart.Series<>();
        private XYChart.Series<Number, Number> series2 = new XYChart.Series<>();
        private XYChart.Series<Number, Number> series3 = new XYChart.Series<>();
        private ExecutorService executor;
        private ConcurrentLinkedQueue<Number> dataQ1 = new ConcurrentLinkedQueue<>();
        private ConcurrentLinkedQueue<Number> dataQ2 = new ConcurrentLinkedQueue<>();
        private ConcurrentLinkedQueue<Number> dataQ3 = new ConcurrentLinkedQueue<>();
    
        private NumberAxis xAxis;
    
        private void init(Stage primaryStage) {
    
            xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
            xAxis.setForceZeroInRange(false);
            xAxis.setAutoRanging(false);
            xAxis.setTickLabelsVisible(false);
            xAxis.setTickMarkVisible(false);
            xAxis.setMinorTickVisible(false);
    
            NumberAxis yAxis = new NumberAxis();
    
            // Create a LineChart
            final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis) {
                // Override to remove symbols on each data point
                @Override
                protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item) {
                }
            };
    
            lineChart.setAnimated(false);
            lineChart.setTitle("Animated Line Chart");
            lineChart.setHorizontalGridLinesVisible(true);
    
            // Set Name for Series
            series1.setName("Series 1");
            series2.setName("Series 2");
            series3.setName("Series 3");
    
            // Add Chart Series
            lineChart.getData().addAll(series1, series2, series3);
    
            primaryStage.setScene(new Scene(lineChart));
        }
    
    
        @Override
        public void start(Stage stage) {
            stage.setTitle("Animated Line Chart Sample");
            init(stage);
            stage.show();
    
    
            executor = Executors.newCachedThreadPool(new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r);
                    thread.setDaemon(true);
                    return thread;
                }
            });
    
            AddToQueue addToQueue = new AddToQueue();
            executor.execute(addToQueue);
            //-- Prepare Timeline
            prepareTimeline();
        }
    
        private class AddToQueue implements Runnable {
            public void run() {
                try {
                    // add a item of random data to queue
                    dataQ1.add(Math.random());
                    dataQ2.add(Math.random());
                    dataQ3.add(Math.random());
    
                    Thread.sleep(500);
                    executor.execute(this);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    
        //-- Timeline gets called in the JavaFX Main thread
        private void prepareTimeline() {
            // Every frame to take any data from queue and add to chart
            new AnimationTimer() {
                @Override
                public void handle(long now) {
                    addDataToSeries();
                }
            }.start();
        }
    
        private void addDataToSeries() {
            for (int i = 0; i < 20; i++) { //-- add 20 numbers to the plot+
                if (dataQ1.isEmpty()) break;
                series1.getData().add(new XYChart.Data<>(xSeriesData++, dataQ1.remove()));
                series2.getData().add(new XYChart.Data<>(xSeriesData++, dataQ2.remove()));
                series3.getData().add(new XYChart.Data<>(xSeriesData++, dataQ3.remove()));
            }
            // remove points to keep us at no more than MAX_DATA_POINTS
            if (series1.getData().size() > MAX_DATA_POINTS) {
                series1.getData().remove(0, series1.getData().size() - MAX_DATA_POINTS);
            }
            if (series2.getData().size() > MAX_DATA_POINTS) {
                series2.getData().remove(0, series2.getData().size() - MAX_DATA_POINTS);
            }
            if (series3.getData().size() > MAX_DATA_POINTS) {
                series3.getData().remove(0, series3.getData().size() - MAX_DATA_POINTS);
            }
            // update
            xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
            xAxis.setUpperBound(xSeriesData - 1);
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    N.B. I haven't taken care of updating the values on the X-axis, you can do that !

    0 讨论(0)
  • 2020-12-03 19:57

    Here is an example:

    public class AnimatedLineChart extends Application {
    
    private LineChart<Number, Number> chart;
    
    private XYChart.Series<Number, Number> dataSeries;
    
    private NumberAxis xAxis;
    
    private Timeline animation;
    
    private double sequence = 0;
    
    private double y = 10;
    
    private final int MAX_DATA_POINTS = 25, MAX = 10, MIN = 5;;
    
    public AnimatedLineChart() {
    
        // create timeline to add new data every 60th of second
        animation = new Timeline();
        animation.getKeyFrames()
                .add(new KeyFrame(Duration.millis(1000), 
                        (ActionEvent actionEvent) -> plotTime()));
        animation.setCycleCount(Animation.INDEFINITE);
    }
    
    public Parent createContent() {
    
        xAxis = new NumberAxis(0, MAX_DATA_POINTS + 1, 2);
        final NumberAxis yAxis = new NumberAxis(MIN - 1, MAX + 1, 1);
        chart = new LineChart<>(xAxis, yAxis);
    
        // setup chart
        chart.setAnimated(false);
        chart.setLegendVisible(false);
        chart.setTitle("Animated Line Chart");
        xAxis.setLabel("X Axis");
        xAxis.setForceZeroInRange(false);
    
        yAxis.setLabel("Y Axis");
        yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis, "$", null));
    
        // add starting data
        dataSeries = new XYChart.Series<>();
        dataSeries.setName("Data");
    
        // create some starting data
        dataSeries.getData()
                .add(new XYChart.Data<Number, Number>(++sequence, y));
    
        chart.getData().add(dataSeries);
    
        return chart;
    }
    
    private void plotTime() {
        dataSeries.getData().add(new XYChart.Data<Number, Number>(++sequence, getNextValue()));
    
        // after 25hours delete old data
        if (sequence > MAX_DATA_POINTS) {
            dataSeries.getData().remove(0);
        }
    
        // every hour after 24 move range 1 hour
        if (sequence > MAX_DATA_POINTS - 1) {
            xAxis.setLowerBound(xAxis.getLowerBound() + 1);
            xAxis.setUpperBound(xAxis.getUpperBound() + 1);
        }
    }
    
    private int getNextValue(){     
        Random rand = new Random();
        return rand.nextInt((MAX - MIN) + 1) + MIN;     
    }
    
    public void play() {
        animation.play();
    }
    
    @Override
    public void stop() {
        animation.pause();
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(createContent()));
        primaryStage.setTitle("Animated Line Chart");
        primaryStage.show();
        play();
    }
    
    /**
     * 
     * Java main for when running without JavaFX launcher
     * 
     */
    public static void main(String[] args) {
        launch(args);
    }
    
    }
    

    You can find more examples in here.

    Hope this helps! :)

    0 讨论(0)
提交回复
热议问题