Я пытаюсь улучшить производительность LineChart в JavaFX, но без особого успеха. Я также обнаружил, что это, по-видимому, общая проблема, которую некоторые программисты обнаружили при попытке отобразить большие данные (здесь большой объем данных составляет 10 000). Например, такие данные довольно распространены в науке и технике, и было бы здорово, если бы мы смогли выяснить, как ускорить работу LineChart в JavaFX.
Ну, я нашел две записи здесь в stackoverflow с аналогичным вопросом Проблема производительности с JavaFX LineChart с 65000 точками данных и JavaFX LineChart - рисовать массив. Тема Проблема производительности с JavaFX LineChart с 65000 точками данных дает предложение (от Адама) использовать алгоритм Рамера-Дугласа-Пьюкера! для уменьшения количества точек данных в LineChart для ускорения.
Однако в научных и технических данных нам обычно нужно увидеть форму сюжета, а затем увеличить масштаб, чтобы увидеть детали в определенных частях сюжета. Следовательно, если мы будем использовать алгоритм Рамера-Дугласа-Пьюкера, нам потребуется перерисовать LineChart каждый раз, когда пользователь будет увеличивать/уменьшать масштаб, что, я думаю, будет стоить много обработки.
Поэтому я хотел бы знать, есть ли у кого-нибудь советы по ускорению LineChart в JavaFX. Вот пример кода, содержащий то, что я узнал до сих пор.
import java.util.ArrayList;
import java.util.List;
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.scene.layout.StackPane;
import javafx.stage.Stage;
public class TestingLineChart extends Application {
@Override
public void start(Stage primaryStage) {
long startTime, endTime;
startTime = System.nanoTime();
StackPane root = new StackPane();
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
LineChart<Number, Number> lineChartPlot = new LineChart<>(xAxis, yAxis);
// set them false to make the plot faster
lineChartPlot.setAnimated(false);
lineChartPlot.setCreateSymbols(false);
List<XYChart.Data<Double, Double>> data = new ArrayList<>();
Scene scene = new Scene(root, 300, 250);
endTime = System.nanoTime();
System.out.println("Time (ms) for creation: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
for (int n = 0; n < 1e5; n++) {
data.add(new XYChart.Data(n, Math.random()));
}
endTime = System.nanoTime();
System.out.println("Time (ms) for adding data: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
XYChart.Series dataSeries = new XYChart.Series<>();
dataSeries.setName("data"); // taking the data
dataSeries.getData().addAll(data); // taking the data
endTime = System.nanoTime();
System.out.println("Time (ms) for adding data to series: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
lineChartPlot.getData().add(dataSeries);
endTime = System.nanoTime();
System.out.println("Time (ms) for adding data to LineChart: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
root.getChildren().add(lineChartPlot);
endTime = System.nanoTime();
System.out.println("Time (ms) for adding LineChart StackPane: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
endTime = System.nanoTime();
System.out.println("Time (ms) for showing: " + (endTime - startTime)/1e6);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Как вы можете видеть, запускаете ли вы этот код, наибольшая стоимость заключается в рендеринге, который я не мог захватить с помощью этих таймингов. Тогда, на мой взгляд, улучшение должно быть сосредоточено там, но я не знаю, как это сделать.
Спасибо.