仅清除Chart中的可见数据数据

时间:2015-05-31 21:37:35

标签: javafx javafx-8

我有javaFX LineChart的这个例子。我想将数据重置到图表中。

public class MainApp extends Application
{
    private static final int MAX_DATA_POINTS = 50;

    private Series series;
    private int xSeriesData = 0;
    private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<>();
    private ExecutorService executor;
    private AddToQueue addToQueue;
    private Timeline timeline2;
    private NumberAxis xAxis;
    private NumberAxis yAxis;
    private AreaChart<Number, Number> sc;

    private void init(Stage primaryStage)
    {    
        xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
        xAxis.setForceZeroInRange(false);
        xAxis.setAutoRanging(false);

        yAxis = new NumberAxis();
        yAxis.setAutoRanging(true);

        sc = new AreaChart<Number, Number>(xAxis, yAxis);

        sc.setAnimated(false);
        sc.setId("liveAreaChart");
        series = new AreaChart.Series<Number, Number>();
        series.setName("Area Chart Series");
        sc.getData().add(series);
        primaryStage.setScene(new Scene(sc));
    }

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        init(primaryStage);
        primaryStage.show();

        executor = Executors.newCachedThreadPool(new ThreadFactory()
        {
            @Override
            public Thread newThread(Runnable r)
            {
                Thread thread = new Thread(r);
                thread.setDaemon(true);
                return thread;
            }
        });
        addToQueue = new AddToQueue();
        executor.execute(addToQueue);
        prepareTimeline();
    }

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

    private class AddToQueue implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                dataQ.add(Math.random());
                Thread.sleep(50);
                executor.execute(this);
            }
            catch (InterruptedException ex)
            {
                Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void prepareTimeline()
    {
        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 (dataQ.isEmpty())
                break;
            series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
        }

        if (series.getData().size() > MAX_DATA_POINTS)
        {
            series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
        }
        xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
        xAxis.setUpperBound(xSeriesData - 1);
    }
}

实现这个的正确方法是什么?

我想我必须清除图表的缓冲区,但我找不到合适的解决方案。

我测试过使用sc.getData().clear();,但此代码会清除所有数据。我想只清除可见数据。

1 个答案:

答案 0 :(得分:1)

您只需使用一个标志即可表示您希望清除数据。在线程中,您可以根据该标志更新数据,也可以清除它们。

带有“清除”按钮和上述标志的快速示例:

public class MainApp extends Application
{
    private static final int MAX_DATA_POINTS = 50;

    private Series series;
    private int xSeriesData = 0;
    private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<>();
    private ExecutorService executor;
    private AddToQueue addToQueue;
    private Timeline timeline2;
    private NumberAxis xAxis;
    private NumberAxis yAxis;
    private AreaChart<Number, Number> sc;
    private boolean clearFlag = false;

    private void init(Stage primaryStage)
    {    
        BorderPane bp = new BorderPane();

        xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
        xAxis.setForceZeroInRange(false);
        xAxis.setAutoRanging(false);

        yAxis = new NumberAxis();
        yAxis.setAutoRanging(true);

        sc = new AreaChart<Number, Number>(xAxis, yAxis);

        sc.setAnimated(false);
        sc.setId("liveAreaChart");
        series = new AreaChart.Series<Number, Number>();
        series.setName("Area Chart Series");
        sc.getData().add(series);

        bp.setCenter(sc);

        HBox toolbar = new HBox();
        Button clearButton = new Button( "Clear");
        clearButton.setOnAction(e -> {
            clearFlag = true;
        });
        toolbar.getChildren().add( clearButton);

        bp.setTop(toolbar);

        Scene scene = new Scene(bp, 800, 600);
        primaryStage.setScene( scene);
    }

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        init(primaryStage);
        primaryStage.show();

        executor = Executors.newCachedThreadPool(new ThreadFactory()
        {
            @Override
            public Thread newThread(Runnable r)
            {
                Thread thread = new Thread(r);
                thread.setDaemon(true);
                return thread;
            }
        });
        addToQueue = new AddToQueue();
        executor.execute(addToQueue);
        prepareTimeline();
    }

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

    private class AddToQueue implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                dataQ.add(Math.random());
                Thread.sleep(50);
                executor.execute(this);
            }
            catch (InterruptedException ex)
            {
//                Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void prepareTimeline()
    {
        new AnimationTimer()
        {
            @Override
            public void handle(long now)
            {
                if( clearFlag) {
                    clearChart();
                    clearFlag = false;
                } else {
                    addDataToSeries();
                }
            }
        }.start();
    }

    private void clearChart() {
        dataQ.clear();
        series.getData().clear();
    }

    private void addDataToSeries()
    {
        for (int i = 0; i < 20; i++)
        { //-- add 20 numbers to the plot+
            if (dataQ.isEmpty())
                break;
            series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
        }

        if (series.getData().size() > MAX_DATA_POINTS)
        {
            series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
        }
        xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
        xAxis.setUpperBound(xSeriesData - 1);
    }
}

如果您只想清除选定的数据范围,只需修改clearChart()并从dataQ而不是所有数据中删除该范围,然后让正常的图表填充进度。