Javascript 多个Highchart反应图的实时更新
编辑1:这似乎是因为问题来自Chromium引擎,因为该问题在Firefox上没有表现出来 某些上下文 我目前正在开发能源系统的监控应用程序(包括重型电池和逆变器)。应用程序通过CAN总线与系统上的电压传感器进行通信 目标是实时显示多个电池单元的电压值(可以从13到100) 我们正在使用一个Python后端,该后端连接到运行React的electron应用程序 (因为它是一个新的应用程序,90%的代码使用React挂钩) 问题 我们目前面临的问题是,每秒钟都会重新播放一次图表。 它会导致整个应用程序在重新加载时发生微冻结 我们认为重新渲染是罪魁祸首,因为禁用它会使应用程序平滑,即使我们保持所有通信层运行 GIF视频: 代码 现在,数据在Python后端收集并格式化为:Javascript 多个Highchart反应图的实时更新,javascript,reactjs,highcharts,electron,react-hooks,Javascript,Reactjs,Highcharts,Electron,React Hooks,编辑1:这似乎是因为问题来自Chromium引擎,因为该问题在Firefox上没有表现出来 某些上下文 我目前正在开发能源系统的监控应用程序(包括重型电池和逆变器)。应用程序通过CAN总线与系统上的电压传感器进行通信 目标是实时显示多个电池单元的电压值(可以从13到100) 我们正在使用一个Python后端,该后端连接到运行React的electron应用程序 (因为它是一个新的应用程序,90%的代码使用React挂钩) 问题 我们目前面临的问题是,每秒钟都会重新播放一次图表。 它会导致整个应用
batteryData = {
"ts": 0,
"cells": [
{'index': 0, 'voltage': 0}
],
"temperatures": [
{'index': 0, 'temp': 0}
],
"stackTemperatures": {
"temperatureMin": 0,
"temperatureMax": 0,
"temperatureAvg": 0
},
"boardTemperatures": {
"temperatureMin": 0,
"temperatureMax": 0,
"temperatureAvg": 0
},
"current": 0.0,
"soc": 0.0,
"soh": 0.0
}
它每秒通过socketIO发送到Electron应用程序。
当前,每个图都侦听一个IPC事件,该事件在electron从Python后端接收数据时立即发送数据:
电子IPC
ipc.on('page-loaded', () => {
console.log('received can data : ' + data)
win.webContents.send('can-data', data)
})
useEffect(() => {
window.ipcRenderer.send('page-loaded', "loaded")
window.ipcRenderer.on('can-data', (event, arg) => {
setTableState({tableData: JSON.parse(arg)})
})
}, []);
反应IPC
ipc.on('page-loaded', () => {
console.log('received can data : ' + data)
win.webContents.send('can-data', data)
})
useEffect(() => {
window.ipcRenderer.send('page-loaded', "loaded")
window.ipcRenderer.on('can-data', (event, arg) => {
setTableState({tableData: JSON.parse(arg)})
})
}, []);
然后Graph小部件继续并从tableState对象中检索“Cells”数据(通常每秒13个单元格对应13个不同的电压值)
数据格式设置
const updateSerie = () => {
if (tableState && tableState.tableData) {
if (!voltagesInit) {
tableState.tableData['cells'].map((cell, index) => {
if (voltagesSerie.length != tableState.tableData['cells'].length) {
voltagesSerie.push({
name: 'voltage ' + index,
data: [cell.voltage],
type: 'spline',
dataType: 'voltage',
})
}
})
setVoltagesInit(true)
chartOptions.series.push(...voltagesSerie)
}
else {
var offset = 0
chartOptions.series.map((serie, index) => {
if (serie.data.length > 300)
{
serie.data.shift()
}
switch (serie.dataType) {
case 'voltage':
serie.data.push(tableState.tableData['cells'][index - offset].voltage)
break;
default:
offset += 1
break
}
})
}
setChartOptions({
series: chartOptions.series
})
}
我们已经尝试过的东西:
- 在图形组件父级中收集一次数据并通过道具分发,以避免多次收集相同的数据(比现在更糟,因为容器必须每秒钟重新渲染一次)
- 使用highchart类组件而不是钩子在展示时使用addPoint方法(甚至更糟糕的结果)
- 收集小部件组件内部的数据(当前情况请参见GIF)以避免容器重新加载
boost
模块?我在这里创建了一个示例:我认为它与您的案例非常相似,而且似乎工作得很好。感谢您提供的提示,您的实现确实是我想要的。但是,我无法集中精力思考如何将其转换为react组件。React中的生命周期约束使此过程变得单调乏味。另外,我想知道渲染是否会受到electron(与google chrome相反)的影响,谢谢,我将同时研究如何实现此功能。请使用React检查此示例:嘿,谢谢,我已经检查了此示例。如果你尝试滚动(不使用鼠标滚轮),你会看到与我在GifOk@ppotaczek上遇到的问题相同的问题。我已经在你提供的链接上以及Highchart论坛上报告了这个问题。在第二个注意事项中,我发现Plotly也存在类似的问题。