JFreeChart动态时间序列图表如何与真实时间同步推进
核心问题成因
DynamicTimeSeriesCollection的时间推进逻辑和内置步长强绑定,不会自动匹配系统真实墙钟时间- 原参考示例的定时器触发间隔为1000ms,和数据集预设的
Second(秒级)时间粒度完全匹配:每1秒触发一次回调,调用一次advanceTime()推进1秒时间片,时间轴走速和真实时间一致 - 当前实现将定时器间隔设为100ms,若保留
advanceTime()调用,1秒内会触发10次回调,每次都会推进1秒时间片,最终时间轴走速为真实时间的10倍,和实际时间完全脱节 - 若注释掉
advanceTime(),数据集内部的时间游标将永远停留在初始化时设置的时间基位置,新追加的数据会被堆叠在同一个时间节点上,图表自然呈现完全静止的状态
修复步骤
- 匹配定时器间隔和数据集时间粒度
当前数据集采用秒级粒度,单个数据点对应1秒的CPU使用率统计值,需要将定时器触发间隔从100ms调整为1000ms,保证数据采集频率和时间粒度一致。如果需要更高精度的毫秒级采集,需将数据集的时间粒度参数从Second替换为Millisecond,再匹配对应的定时器间隔。 - 对齐真实时间戳
移除硬编码的步长推进逻辑,每次数据采集时直接读取系统当前真实时间作为数据集的时间基准,从根源上消除时间轴走速偏差。 - 关键代码修改
调整定时器初始化参数:
修改定时器回调内的数据追加逻辑:// 原代码为 timer = new Timer(100, ...) timer = new Timer(1000, new ActionListener() { // 原有CPU采集逻辑保持不变 });@Override public void actionPerformed(ActionEvent e) { newData[0] = cpu(); // 删除原dataset.advanceTime()调用 // 直接将当前真实时间作为时间基准 dataset.setTimeBase(new Second(new Date())); dataset.appendData(newData); }
注意事项
- 初始化时填充的占位测试数据,会基于启动时的时间基排列,第一次追加真实数据时会自动对齐到当前真实时间,无需手动清空
- 不要将时间基固定在程序启动时刻,否则长时间运行后会出现累计的时间偏移
- 不要用秒级粒度的数据集承载毫秒级频率的采集数据,否则会出现数据点时间戳错位、图表显示异常的问题
内容的提问来源于stack exchange,提问作者BaaDe
相关产品推荐
相关产品推荐

