我现在要展示的代码是用 vaadin 和 ApexChart 插件制作的,我只是想实时更新线型图,我@Push
在 MainView 中有注释和每秒运行的 ScheduledExecutorService
Vaadin 版本是14.1.27
Apexcharts 插件
<dependency>
<groupId> com.github.appreciated </groupId>
<artifactId> apexcharts </artifactId>
<version> 2.0.0.beta9 </version>
</dependency>
Apache Tomcat/9.0.27
我做了一个简单的请求,然后在access(()-> )
方法中,最后调用chart.updateSeries()
代码
public void updateChar() {
final ApexCharts chart = ApexChartsBuilder.get().withChart(ChartBuilder.get()
.withType(Type.line)
.withAnimations(AnimationsBuilder.get()
.withEnabled(true)
.withEasing(Easing.linear)
.withDynamicAnimation(DynamicAnimationBuilder.get()
.withSpeed(1000)
.build())
.build())
.build())
.withDataLabels(DataLabelsBuilder.get()
.withEnabled(false)
.build())
.withSeries(new Series<>(0))
.withXaxis(XAxisBuilder.get()
.withCategories()
.withMax(10.0)
.build())
.build();
chart.setHeight("400px");
chart.setWidth("400px");
schedule.scheduleAtFixedRate(() -> {
try {
final CompletableFuture<String> cf = HttpClient
.newBuilder()
.build()
.sendAsync(HttpRequest
.newBuilder(new URI(HUMIDITY))
.GET()
.version(HttpClient.Version.HTTP_2)
.build(),
HttpResponse.BodyHandlers.ofString())
.thenApplyAsync(HttpResponse::body);
cf.whenCompleteAsync((data, error) -> {
if (getUI().isEmpty()) return;
if (Objects.nonNull(error)) {
cf.completeExceptionally(error);
getUI().get().access(() -> {
Notification.show("Error: " + error);
});
} else {
if (getUI().isEmpty()) return;
getUI().get().access(() -> {
final SecureRandom random = new SecureRandom();
final Series<Double> series = new Series<>(25.2, 30.2, 25.77, 45.66, 60.00, 55.5);
final Series<Double> serie1 = new Series<>(30.3, 34.10, 20.11, 12.15, 55.66, 82.5, 64.35, 100.4, 77.66, 14.32, 25.77);
final Series<Double> serie2 = new Series<>(25.5, 55.3, 44.5, 99.6, 10.3, 44.6, 36.6);
final Series[] randomSeries = new Series[]{series, serie1, serie2, series};
//chart.updateSeries(radomSeries[SECURE_RANDOM.nextInt(randomSeries .length)]);
chart.updateSeries(new Series<>(data));
});
}
}, EXEC)
.join();
} catch (URISyntaxException e) {
throw new RuntimeException();
}
}, 1, 1, TimeUnit.SECONDS);
}
不幸的是结果不符合预期,使用相同的代码,我可以更新TextFields
更新
我目前的解决方案是使用 list 来存储传感器的时间戳和双精度值。
这个常数对于以秒为单位的分辨率非常重要。
同样在后台我使用并更改了reactor-nettyWebClient
的默认配置以每 2 秒重试一次。
@Bean
public WebClient sensorWebClientBuilder(final WebClient.Builder webClient) {
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000)
.doOnConnected((Connection connection) ->
connection.addHandlerLast(new ReadTimeoutHandler(2000, TimeUnit.MILLISECONDS)));
return webClient
.clientConnector(new ReactorClientHttpConnector(httpClient))
.baseUrl(BASE_URL)
.build();
}