簡體   English   中英

JavaFX實時圖表更新

[英]JavaFX Realtime chart updates

這個問題已經被問過多次了,但是我對如何具體地幫助我還是很困惑。

我有一個簡單的JavaFX XYChart。 我想對實時數據執行FFT,並實時顯示更新。 在后台將進行更多的平均,但實際上是在圖表上查看2-3Hz的刷新率。

我知道還有其他庫和框架可以簡化此工作,但是在使用javaFX時會遇到一些困難,因此,我很想學習如何滿足我的需要。

所以我有以下幾點:

@FXML
public LineChart <Number, Number> midchart;

public void plotMidChart(){
    ArrayList freq = (ArrayList) Frequency.get(listViewIndex);
    ArrayList pha = (ArrayList) Phase.get(listViewIndex);

    for (int i=1; i<freq.size()-1; i++){
       phaseSeries.getData().add(new XYChart.Data<Number, Number>((Number) freq.get(i), (double) pha.get(i)));
    }

    phaseSeries.setName("Phase");   


    midchart.getData().addAll(phaseSeries );
}

當前,這是一種“單次通過”方法。 每次我調用plotMidChart時,都可以使用我選擇的任何數據(通過listViewIndex)來更新圖表。 但是,目前在主線程上渲染起來很慢。

閱讀更多內容,我發現與更改主JavaFX UI線程有關的所有事情都應通過'Platform.runLater())->'進行調用,因此我嘗試將方法放入以下代碼中:

Platform.runLater(() -> {
    ArrayList freq = (ArrayList) Frequency.get(listViewIndex);
    ArrayList pha = (ArrayList) Phase.get(listViewIndex);

    for (int i=1; i<(freq.size()-1); i++){
        System.out.println(i);
        phaseSeries.getData().add(new XYChart.Data<Number, Number>((Number) freq.get(i), (double) pha.get(i)));
        }
        midchart.getData().addAll(phaseSeries );
    });

頻率和相位是FFT結果的數組,因此當我選擇特定索引時,它將返回該FFT的結果。 但是我在這里感到困惑,因為肯定所有的實際渲染仍在主UI線程上完成。 難道不是要在另一個線程上完成並且只是在UI線程上調用到場景?

我已經讀過一些關於“任務”的信息,但是oracle網站仍然說這不應該鏈接到UI線程。

我也不知道如何更新當前數據。 每次調用它時,我都希望它覆蓋當前的數據系列,以便只顯示一個系列,並且每次它都是一組全新的數據(不添加到現有數據中)。

最終目標是使它處於無限循環中,每次迭代之間睡眠大約300毫秒。

我通過以下方式調用此plotMidChart()方法

measureList.setOnMouseClicked(new EventHandler<MouseEvent>(){

    @Override
    public void handle(MouseEvent event) {
        listViewIndex =  measureList.getSelectionModel().getSelectedIndex();
        plotMidChart();
        }
}

因此,您在這里提出了多個問題,我將嘗試解決所有問題。

首先, Platform.runLater()將執行您在UI線程中為其提供的代碼。 因此,您需要在自己的線程中執行繁重的操作,而影響UI的所有操作都需要在Platform.runLater()調用。

您可以做的是在自己的線程中創建數據,然后將結果提供給UI線程。

public void plotMidChart(){
    ArrayList freq = (ArrayList) Frequency.get(listViewIndex);
    ArrayList pha = (ArrayList) Phase.get(listViewIndex);

    List<XYChart.Data<Number, Number>> tempList = new ArrayList();
    for (int i=1; i<freq.size()-1; i++){
       tempList.add(.add(new XYChart.Data<Number, Number>((Number) freq.get(i), (double) pha.get(i)));
    }

    Platform.runLater(() -> {
       phaseSeries.getData().setAll(tempList);
    });
}

還要注意,您不必在每次重新創建圖表數據時都調用phaseSeries.setName("Phase")midchart.getData().addAll(phaseSeries )

如果性能仍然很差,則可能是您給圖表提供了過多的數據點,這可能需要花費相當長的時間才能呈現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM