package harika;
import javafx.animation.AnimationTimer;
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.stage.Stage;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class ChartWork extends Application {
private static final int MAX_DATA_POINTS = 50;
private int xSeriesData = 0;
private XYChart.Series<Number, Number> series1 = new XYChart.Series<>();
private XYChart.Series<Number, Number> series2 = new XYChart.Series<>();
private XYChart.Series<Number, Number> series3 = new XYChart.Series<>();
private ExecutorService executor;
private ConcurrentLinkedQueue<Number> dataQ1 = new ConcurrentLinkedQueue<>();
private ConcurrentLinkedQueue<Number> dataQ2 = new ConcurrentLinkedQueue<>();
private ConcurrentLinkedQueue<Number> dataQ3 = new ConcurrentLinkedQueue<>();
private NumberAxis xAxis;
private void init(Stage primaryStage) {
xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);
xAxis.setTickLabelsVisible(false);
xAxis.setTickMarkVisible(false);
xAxis.setMinorTickVisible(false);
NumberAxis yAxis = new NumberAxis();
// Create a LineChart
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis) {
// Override to remove symbols on each data point
@Override
protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item) {
}
};
lineChart.setAnimated(false);
lineChart.setTitle("Animated Line Chart");
lineChart.setHorizontalGridLinesVisible(true);
// Set Name for Series
series1.setName("Series 1");
series2.setName("Series 2");
series3.setName("Series 3");
// Add Chart Series
lineChart.getData().addAll(series1, series2, series3);
primaryStage.setScene(new Scene(lineChart));
}
@Override
public void start(Stage stage) {
stage.setTitle("Animated Line Chart Sample");
init(stage);
stage.show();
executor = Executors.newCachedThreadPool(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
AddToQueue addToQueue = new AddToQueue();
executor.execute(addToQueue);
//-- Prepare Timeline
prepareTimeline();
}
private class AddToQueue implements Runnable {
public void run() {
try {
// add a item of random data to queue
dataQ1.add(Math.random());
dataQ2.add(Math.random());
dataQ3.add(Math.random());
Thread.sleep(500);
executor.execute(this);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
//-- Timeline gets called in the JavaFX Main thread
private void prepareTimeline() {
// Every frame to take any data from queue and add to chart
new AnimationTimer() {
@Override
public void handle(long now) {
addDataToSeries();
}
}.start();
}
private void addDataToSeries() {
for (int i = 0; i < 20; i++) { //-- add 20 numbers to the plot+
if (dataQ1.isEmpty()) break;
series1.getData().add(new XYChart.Data<>(xSeriesData++, dataQ1.remove()));
series2.getData().add(new XYChart.Data<>(xSeriesData++, dataQ2.remove()));
series3.getData().add(new XYChart.Data<>(xSeriesData++, dataQ3.remove()));
}
// remove points to keep us at no more than MAX_DATA_POINTS
if (series1.getData().size() > MAX_DATA_POINTS) {
series1.getData().remove(0, series1.getData().size() - MAX_DATA_POINTS);
}
if (series2.getData().size() > MAX_DATA_POINTS) {
series2.getData().remove(0, series2.getData().size() - MAX_DATA_POINTS);
}
if (series3.getData().size() > MAX_DATA_POINTS) {
series3.getData().remove(0, series3.getData().size() - MAX_DATA_POINTS);
}
// update
xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData - 1);
}
public static void main(String[] args) {
launch(args);
}
}
所以我有这个代码,我已经在网上找到了。我正在尝试阅读这段代码并了解它的作用。我知道javaFX并了解它的这一部分,但我还不知道其他部分。但在我需要之前确保我可以使这个动画更顺畅。然后我可以详细介绍..
我无法找到如何做到这一点。我该怎么办才能让它更顺畅?
答案 0 :(得分:1)
要从样本中获得平滑的动画效果:
MAX_DATA_POINTS
从50
更改为2_500
。 Thread.sleep(500)
更改为Thread.sleep(10)
。 如果您每秒只更新一次图表两次(如您发布的示例中所示),则动画将会跳动。
如果每秒更新30次以上,动画将会流畅。人眼通常将小帧到帧的变化记录为每秒30帧以上作为平滑动画。请参阅wikipedia on "Frame rate and human vision"。
一般情况下,如果您无法通过查看其代码来了解其工作原理和工作原理,请注意不要使用您在互联网上找到的此类代码示例。特别是,您提供的示例代码在多个线程上执行。如果您的要求不需要在多个线程上执行,那么您可能不应该使用这样的解决方案。