LightningChart向现有图表系列添加数据:React下Socket实时数据绑定实现
解决方案
1. 持久化图表实例引用
首先在React组件中使用useRef存储后续需要操作的实例,避免组件重渲染时丢失引用:
import { useRef, useEffect } from 'react' // 保持原有LightningChart相关导入不变 const YourChartComponent = () => { // 存储核心实例和全局常量 const seriesRef = useRef(null) const xAxisRef = useRef(null) // 存储起始日期保证前后计算x值逻辑一致 const startingDateRef = useRef(new Date(/* 替换为你的实际起始日期 */)) const containerId = "你的图表容器ID" useEffect(() => { // 原有初始化逻辑放到这里 const dateOrigin = new Date(startingDateRef.current); const chart = lightningChart() .ChartXY({ container: containerId, theme: Themes.lightNew, columnIndex: 0, columnSpan: 1, rowIndex: 0, rowSpan: 1 }) .setTitle(containerId.split(" ")[1]); const originDate = new Date(moment().subtract(1, 'days')) const xAxis = chart.getDefaultAxisX().setTickStrategy( AxisTickStrategies.DateTime, (tickStrategy) => tickStrategy.setDateOrigin(originDate) ); // 开启X轴渐进滚动策略,实现新数据进入时自动从左到右滚动 xAxis.setScrollStrategy(AxisScrollStrategies.progressive) // 设定X轴视口保留的时间范围,示例为保留最近24小时数据(单位和你的x值保持一致,为毫秒) xAxis.setInterval(0, 24 * 60 * 60 * 1000) xAxisRef.current = xAxis const yAxis = chart .getDefaultAxisY() .fit(true) .setScrollStrategy(undefined) .setInterval(-20, 20) .setTitle(""); const series = chart .addPointSeries({ xAxis: xAxis, yAxis: yAxis, pointShape: PointShape.Circle }) .setName("Actual"); seriesRef.current = series // 原有初始数据添加逻辑保持不变 series.add( sensorData.map((point) => ({ x: new Date(point.x).getTime() - startingDateRef.current.getTime(), y: point.y })) ) // 组件卸载时销毁图表 return () => chart.dispose() }, [])
2. 追加Socket新数据
LightningChart的series.add()方法默认是增量追加数据,不会覆盖已有数据,直接在Socket的消息回调中按照相同的格式处理新数据后调用即可:
useEffect(() => { // 初始化Socket连接 const socket = new WebSocket('替换为你的Socket服务地址') socket.onmessage = (event) => { // 若实例未初始化完成直接跳过 if (!seriesRef.current) return // 解析Socket返回的新数据 const newRawPoints = JSON.parse(event.data) // 格式和初始数据保持完全一致 const formattedNewPoints = newRawPoints.map(point => ({ x: new Date(point.x).getTime() - startingDateRef.current.getTime(), y: point.y })) // 直接追加数据,总点数会自动累加 seriesRef.current.add(formattedNewPoints) } // 组件卸载时关闭Socket连接 return () => socket.close() }, []) }
补充说明
- 不需要手动维护全局数据数组,PointSeries内部会自动存储所有已添加的数据
- 如果需要限制总数据量避免内存占用过高,可以调用
seriesRef.current.splice(0, 要删除的旧数据数量)移除最早的旧数据 - 如果不需要自动滚动,只需要在追加数据后手动调用
xAxisRef.current.setInterval(新的起始x值, 新的结束x值)自定义视口范围即可
内容的提问来源于stack exchange,提问作者user3211705
相关产品推荐
相关产品推荐

