Yêu cầu- Xây dựng một AreaChart động với dữ liệu truyền trực tuyến thời gian thực. Có thể âm mưu 300 điểm dữ liệu mỗi 1 giây.Cách ánh xạ dữ liệu phát trực tuyến theo thời gian thực bằng AreaChart trong JAVAFX 2 - Đồng thời, Hoạt ảnh, Biểu đồ
Details- Vì vậy, tôi cần phải đọc thời gian thực trực tuyến dữ liệu từ một thiết bị y tế, các mẫu hơi thở của bệnh nhân và hiển thị nó trong một thời trang dạng sóng sử dụng AreaChart trong JavaFX. Tôi mới sử dụng JavaFX và vì vậy tôi đã xây dựng một POC nhỏ, để xem cách hoạt động đồng thời và hoạt ảnh trong JavaFX.
Khái niệm này hoạt động và tôi hài lòng với bài kiểm tra cơ bản, miễn là thực hiện chức năng. Nhưng tôi không hài lòng với hiệu suất tôi nhận được từ mã bên dưới.
Trong mã hoạt động bên dưới, tôi tạo một chuỗi riêng biệt để mô phỏng việc tìm nạp dữ liệu từ thiết bị y tế. Chủ đề chỉ tạo ra một số ngẫu nhiên và thêm nó vào một ConcurrentLinkedQueue.
Chuỗi ứng dụng JavaFX kéo dữ liệu này ra khỏi hàng đợi, thông qua Dòng thời gian và thêm nó vào một chuỗi AreaChart.
Loại này cung cấp cho tôi hoạt ảnh tôi cần và dữ liệu đang được thêm vào trong thời gian chạy. Bạn có thể sao chép và dán mã này và kiểm tra nó .. Nó sẽ hoạt động.
NHƯNG hiệu suất không ấn tượng - CPU sử dụng 56% - Tôi có Intel Core 2 Duo @ 2.53 GHZ và 4GB ram trên máy tính xách tay của mình. Card đồ họa của tôi là Mobile Intel 4 Series thể hiện bằng trình điều khiển mới nhất.
Làm cách nào để cải thiện hoạt ảnh này hoặc vẽ dữ liệu thời gian thực, để có được hiệu suất tốt hơn?
LƯU Ý: Tôi sẵn sàng thỏa hiệp về hoạt ảnh, nếu cổ chai của nó. Tôi đang mở để triển khai như được hiển thị ở đây http://smoothiecharts.org/ nơi dạng sóng chỉ được dựng sẵn và chỉ phát trực tiếp từ phải sang trái.
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.SequentialTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* A chart that fills in the area between a line of data points and the axes.
* Good for comparing accumulated totals over time.
*
* @see javafx.scene.chart.Chart
* @see javafx.scene.chart.Axis
* @see javafx.scene.chart.NumberAxis
* @related charts/line/LineChart
* @related charts/scatter/ScatterChart
*/
public class AreaChartSample extends Application {
private Series series;
private int xSeriesData=0;
private ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<Number>();
private ExecutorService executor;
private AddToQueue addToQueue;
private Timeline timeline2;
private SequentialTransition animation;
private void init(Stage primaryStage) {
Group root = new Group();
primaryStage.setScene(new Scene(root));
NumberAxis xAxis = new NumberAxis();
xAxis.setAutoRanging(true);
NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
//-- Chart
final AreaChart<Number,Number> sc = new AreaChart<Number,Number>(xAxis,yAxis);
sc.setId("liveAreaChart");
sc.setTitle("Animated Area Chart");
//-- Chart Series
series=new AreaChart.Series<Number,Number>();
series.setName("Area Chart Series");
series.getData().add(new AreaChart.Data<Number, Number>(5d, 5d));
sc.getData().add(series);
root.getChildren().add(sc);
}
@Override public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
//-- Prepare Executor Services
executor = Executors.newCachedThreadPool();
addToQueue=new AddToQueue();
executor.execute(addToQueue);
//-- Prepare Timeline
prepareTimeline();
}
public static void main(String[] args) { launch(args); }
private class AddToQueue extends Thread {
public void run(){
try {
Thread.currentThread().setName(Thread.currentThread().getId()+"-DataAdder");
//-- Add Random numbers to Q
dataQ.add(Math.random());
Thread.sleep(50);
executor.execute(addToQueue);
} catch (InterruptedException ex) {
Logger.getLogger(AreaChartSample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//-- Timeline gets called in the JavaFX Main thread
private void prepareTimeline(){
//-- Second slower timeline
timeline2 = new Timeline();
//-- This timeline is indefinite.
timeline2.setCycleCount(Animation.INDEFINITE);
timeline2.getKeyFrames().add(
new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
addDataToSeries();
}
})
);
//-- Set Animation- Timeline is created now.
animation = new SequentialTransition();
animation.getChildren().addAll(timeline2);
animation.play();
}
private void addDataToSeries(){
for(int i=0;i<20;i++){ //-- add 20 numbers to the plot
if(dataQ.isEmpty()==false) {
series.getData().add(new AreaChart.Data(xSeriesData++,dataQ.remove()));
//-- Get rid of a bunch from the chart
if (series.getData().size() > 1000) {
series.getData().remove(0,999);
}
}
else{
return;
}
}
}
}
Câu hỏi này được đăng chéo (và trả lời tốt) trên [chuỗi diễn đàn Java JavaFX] (https://forums.oracle.com/forums/thread.jspa?threadID=2411087). – jewelsea