ECharts 实时数据平滑更新实践(含 WebSocket 模拟)

在可视化项目中,常常需要实时展示动态数据,比如流量监控、设备状态、传感器数据等。

很多同学直接使用 setOption 全量更新数据,会导致 图表闪烁、重绘、动画不连贯

本文介绍一种更平滑的更新方案:通过监听数据流变化,实现折线图平移更新

示例中我们使用 模拟 WebSocket 推送 的方式,每秒更新一次数据,图表平滑移动。


🎬 实现效果

折线图每秒新增一个点,曲线平滑向左移动,旧数据自动移除。

复制代码
<template>
  <div class="chart-container">
    <div ref="chartRef" class="chart"></div>
  </div>
</template>

<script setup>
import * as echarts from "echarts";
import { ref, onMounted, onBeforeUnmount, watch } from "vue";

const chartRef = ref(null);
let chartInstance = null;

// 模拟 WebSocket 推送的数据数组
const chartData = ref([]);
const maxPoints = 30; // 显示的点数上限
let timer = null;

// ===================== 初始化 ECharts =====================
const initChart = () => {
  chartInstance = echarts.init(chartRef.value);
  const option = {
    title: {
      text: "实时数据曲线(平滑移动)",
      left: "center",
      textStyle: { fontSize: 14 },
    },
    tooltip: { trigger: "axis" },
    grid: { top: 40, left: 40, right: 20, bottom: 40 },
    xAxis: {
      type: "category",
      boundaryGap: false,
      data: [],
    },
    yAxis: {
      type: "value",
      min: 0,
      max: 100,
      splitLine: { lineStyle: { color: "#eee" } },
    },
    series: [
      {
        name: "数据流",
        type: "line",
        smooth: true,
        showSymbol: false,
        data: [],
        lineStyle: { color: "#4fc3f7" },
        areaStyle: { color: "rgba(79,195,247,0.2)" },
      },
    ],
    animationDurationUpdate: 300,
  };
  chartInstance.setOption(option);
};

// ===================== 模拟 WebSocket 推送 =====================
const startMockWS = () => {
  timer = setInterval(() => {
    const now = new Date().toLocaleTimeString().split(" ")[0];
    const value = +(Math.random() * 100).toFixed(2);
    chartData.value.push({ time: now, value });
    if (chartData.value.length > maxPoints) chartData.value.shift();
  }, 1000);
};

// ===================== 数据监听(核心逻辑) =====================
watch(
  chartData,
  (val) => {
    if (!chartInstance) return;
    const xData = val.map((item) => item.time);
    const yData = val.map((item) => item.value);

    // ✅ 平滑更新:不重绘,只更新数据
    chartInstance.setOption({
      xAxis: { data: xData },
      series: [{ data: yData }],
    });
  },
  { deep: true }
);

// ===================== 生命周期 =====================
onMounted(() => {
  initChart();
  startMockWS();
});

onBeforeUnmount(() => {
  clearInterval(timer);
  chartInstance?.dispose();
});
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 400px;
}
.chart {
  width: 100%;
  height: 100%;
}
</style>

🔍 技术要点总结

技术点 说明
watch(chartData) 深度监听数据变化,即使数值没变也触发更新
setOption 仅更新 xAxisseries 数据,不重建图表实例
smooth: true 平滑曲线过渡
showSymbol: false 去掉节点圆点,避免闪烁
animationDurationUpdate 更新动画时长,控制平滑效果
shift() 限制点数上限,模拟数据流滚动

🧠 延伸思路

  • 如果使用真实 WebSocket,可在 onmessage 中替换 startMockWS 部分;

  • 也可以使用 appendData 提升大数据性能;

  • 若需要断线重连,可封装成 useRealtimeChart composable 逻辑复用。


✅ 最终效果

每秒新增一个点,曲线持续向左平滑移动,无闪烁、不卡顿、无全量重绘。

这种方式非常适合用于 实时监控类大屏、IoT、交通流量、传感器数据流等场景


如果这篇文章对你有帮助,
欢迎点赞 + 收藏 + 关注我 ❤️

后续我会继续更新更多前端实时可视化相关实践。

相关推荐
LaughingZhu5 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫5 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux6 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水6 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger7 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)7 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态7 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态7 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart7 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter
放下华子我只抽RuiKe57 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架