import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.chart.AreaChart; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart; 
import javafx.scene.control.Button; 
import javafx.scene.control.Slider; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

import java.util.concurrent.Executors; 
import java.util.concurrent.ThreadFactory; 
import java.util.concurrent.TimeUnit; 

public class SlowCharts extends Application { 

  private int dataNum = 0; 

  private static final ThreadFactory daemonThreadFactory = r -> { 
    Thread t = new Thread(r); 
    t.setDaemon(true); 
    return t; 
  }; 

  public static void main(String[] args) { 
    launch(args); 
  } 

  @Override 
  public void start(Stage primaryStage) throws Exception { 

    final double WINDOW_SIZE = 150; // show ~5 seconds worth of data points 

    NumberAxis xAxis = new NumberAxis("", 0, WINDOW_SIZE, 30); 
    NumberAxis yAxis = new NumberAxis("", 0, 1, 0.5); 
    xAxis.lowerBoundProperty().bind(xAxis.upperBoundProperty().subtract(WINDOW_SIZE)); 

    XYChart.Series<Number, Number> series = new XYChart.Series<>(); 
    series.setName("Data"); 

    AreaChart<Number, Number> chart = new AreaChart<>(xAxis, yAxis); 
    chart.setAnimated(false); 
    chart.setCreateSymbols(false); 
    chart.getData().add(series); 

    // Add new data approximately 30 times per second 
    // This can be sped up to cause a more rapid loss of responsiveness 
    Executors.newSingleThreadScheduledExecutor(daemonThreadFactory) 
             .scheduleAtFixedRate(() -> { 
               Platform.runLater(() -> { 
                 series.getData().add(new XYChart.Data<>(dataNum++, Math.random())); 
                 xAxis.setUpperBound(dataNum); 
               }); 
             }, 100, 33, TimeUnit.MILLISECONDS); 

    // A "clear" button to confirm that the sluggishness is caused by the amount of data in the chart 
    Button clearButton = new Button("Clear"); 
    clearButton.setOnAction(e -> { 
      series.getData().clear(); 
      dataNum = 0; 
    }); 

    // Add a slider to test UI responsiveness 
    primaryStage.setScene(new Scene(new VBox(new StackPane(chart), new Slider(-1, 1, 0), clearButton))); 
    primaryStage.show(); 
  } 

} 