我有javaFX LineChart的这个例子。我想将数据重置到图表中。
public class MainApp extends Application
{
private static final int MAX_DATA_POINTS = 50;
private Series series;
private int xSeriesData = 0;
private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<>();
private ExecutorService executor;
private AddToQueue addToQueue;
private Timeline timeline2;
private NumberAxis xAxis;
private NumberAxis yAxis;
private AreaChart<Number, Number> sc;
private void init(Stage primaryStage)
{
xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);
yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
sc = new AreaChart<Number, Number>(xAxis, yAxis);
sc.setAnimated(false);
sc.setId("liveAreaChart");
series = new AreaChart.Series<Number, Number>();
series.setName("Area Chart Series");
sc.getData().add(series);
primaryStage.setScene(new Scene(sc));
}
@Override
public void start(Stage primaryStage) throws Exception
{
init(primaryStage);
primaryStage.show();
executor = Executors.newCachedThreadPool(new ThreadFactory()
{
@Override
public Thread newThread(Runnable r)
{
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
addToQueue = new AddToQueue();
executor.execute(addToQueue);
prepareTimeline();
}
public static void main(String[] args)
{
launch(args);
}
private class AddToQueue implements Runnable
{
@Override
public void run()
{
try
{
dataQ.add(Math.random());
Thread.sleep(50);
executor.execute(this);
}
catch (InterruptedException ex)
{
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void prepareTimeline()
{
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 (dataQ.isEmpty())
break;
series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
}
if (series.getData().size() > MAX_DATA_POINTS)
{
series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
}
xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData - 1);
}
}
实现这个的正确方法是什么?
我想我必须清除图表的缓冲区,但我找不到合适的解决方案。
我测试过使用sc.getData().clear();
,但此代码会清除所有数据。我想只清除可见数据。
答案 0 :(得分:1)
您只需使用一个标志即可表示您希望清除数据。在线程中,您可以根据该标志更新数据,也可以清除它们。
带有“清除”按钮和上述标志的快速示例:
public class MainApp extends Application
{
private static final int MAX_DATA_POINTS = 50;
private Series series;
private int xSeriesData = 0;
private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<>();
private ExecutorService executor;
private AddToQueue addToQueue;
private Timeline timeline2;
private NumberAxis xAxis;
private NumberAxis yAxis;
private AreaChart<Number, Number> sc;
private boolean clearFlag = false;
private void init(Stage primaryStage)
{
BorderPane bp = new BorderPane();
xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 10);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);
yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
sc = new AreaChart<Number, Number>(xAxis, yAxis);
sc.setAnimated(false);
sc.setId("liveAreaChart");
series = new AreaChart.Series<Number, Number>();
series.setName("Area Chart Series");
sc.getData().add(series);
bp.setCenter(sc);
HBox toolbar = new HBox();
Button clearButton = new Button( "Clear");
clearButton.setOnAction(e -> {
clearFlag = true;
});
toolbar.getChildren().add( clearButton);
bp.setTop(toolbar);
Scene scene = new Scene(bp, 800, 600);
primaryStage.setScene( scene);
}
@Override
public void start(Stage primaryStage) throws Exception
{
init(primaryStage);
primaryStage.show();
executor = Executors.newCachedThreadPool(new ThreadFactory()
{
@Override
public Thread newThread(Runnable r)
{
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
addToQueue = new AddToQueue();
executor.execute(addToQueue);
prepareTimeline();
}
public static void main(String[] args)
{
launch(args);
}
private class AddToQueue implements Runnable
{
@Override
public void run()
{
try
{
dataQ.add(Math.random());
Thread.sleep(50);
executor.execute(this);
}
catch (InterruptedException ex)
{
// Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void prepareTimeline()
{
new AnimationTimer()
{
@Override
public void handle(long now)
{
if( clearFlag) {
clearChart();
clearFlag = false;
} else {
addDataToSeries();
}
}
}.start();
}
private void clearChart() {
dataQ.clear();
series.getData().clear();
}
private void addDataToSeries()
{
for (int i = 0; i < 20; i++)
{ //-- add 20 numbers to the plot+
if (dataQ.isEmpty())
break;
series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
}
if (series.getData().size() > MAX_DATA_POINTS)
{
series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
}
xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData - 1);
}
}
如果您只想清除选定的数据范围,只需修改clearChart()并从dataQ而不是所有数据中删除该范围,然后让正常的图表填充进度。