[英]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.