Line Chart Live update

前端 未结 2 1355
说谎
说谎 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 series1 = new XYChart.Series<>();
        private XYChart.Series series2 = new XYChart.Series<>();
        private XYChart.Series series3 = new XYChart.Series<>();
        private ExecutorService executor;
        private ConcurrentLinkedQueue dataQ1 = new ConcurrentLinkedQueue<>();
        private ConcurrentLinkedQueue dataQ2 = new ConcurrentLinkedQueue<>();
        private ConcurrentLinkedQueue 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 lineChart = new LineChart(xAxis, yAxis) {
                // Override to remove symbols on each data point
                @Override
                protected void dataItemAdded(Series series, int itemIndex, Data 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 !

提交回复
热议问题