2016-01-13 2 views
7

Я пытался улучшить производительность LineChart в JavaFX, но без особого успеха. Я также обнаружил, что это, по-видимому, общая проблема, которую некоторые программисты обнаружили при попытке отобразить большие данные (здесь большой объем данных составляет 10 000). Например, такие данные довольно распространены в науке и технике, и было бы здорово, если бы мы смогли выяснить, как ускорить работу LineChart в JavaFX.JavaFX LineChart Performance

Ну, я нашел два сообщения здесь в stackoverflow с аналогичным вопросом Performance issue with JavaFX LineChart with 65000 data points и JavaFX LineChart - draw array. Тема Performance issue with JavaFX LineChart with 65000 data points заканчивается предложением (от Адама) использовать Ramer–Douglas–Peucker algorithm! для уменьшения количества точек данных в 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); 
} 
} 

Как вы можете увидеть, если вы запустите этот код, наибольшая стоимость рендеринга, который я не мог захватить с помощью этих таймингов. Тогда, на мой взгляд, улучшение должно быть сосредоточено там, но я не знаю, как это сделать.

спасибо.

+0

Поскольку рендеринг - это отнимающая много времени часть, я думаю, что предложенное вами предложение, вероятно, сработает для вашего сценария. Выполните сокращение данных на некотором «легком» представлении данных (например, 'double []'), а затем создайте уменьшенное количество объектов 'XYChart.Data'. Поведение причины медленное - каждый сегмент линии в линейной диаграмме является узлом в графе сцены; использование его предполагает раскладку и применение CSS. Обработка данных, вероятно, будет намного быстрее. Другой альтернативой (я должен был это сделать) является реализация собственной диаграммы (например, с холстом). –

+0

Спасибо, я попробую это позже. На данный момент я хотел бы знать, знает ли кто-то, как мы можем потратить время на реновацию. –

+0

Кто-нибудь знает о внедрении линейной диаграммы? –

ответ

0

Что улучшает производительность диаграмм с большим количеством точек данных, заключается в удалении «формы» точек данных.

За CSS, например:

.chart-line-symbol { 
    -fx-shape: ""; 
} 

или чтобы убедиться, что он не виден на всех:

.chart-line-symbol { 
    -fx-background-insets: 0,0; 
    -fx-background-radius: 0px; 
    -fx-padding: 0px; 
    -fx-shape: ""; 
    -fx-background-color: transparent; 
} 

Другой подход заключается в удалении некоторых точек данных из диаграммы. Так, например, используйте только 3. datapoint или вычислите среднее количество точек данных.

Смежные вопросы