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、交通流量、传感器数据流等场景


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

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

相关推荐
欧阳天风几秒前
js实现鼠标横向滚动
开发语言·前端·javascript
局i32 分钟前
Vue 指令详解:v-for、v-if、v-show 与 {{}} 的妙用
前端·javascript·vue.js
码界奇点1 小时前
Java Web学习 第15篇jQuery从入门到精通的万字深度解析
java·前端·学习·jquery
小鑫同学1 小时前
Alias Assistant:新一代 macOS Shell 别名管理解决方案
前端·前端工程化
꒰ঌ小武໒꒱1 小时前
RuoYi-Vue 前端环境搭建与部署完整教程
前端·javascript·vue.js·nginx
名字越长技术越强2 小时前
前端之相对路径
前端
望道同学2 小时前
PMP/信息系统项目管理师 9 张 思维导图【考试必备】
前端·后端·程序员
局i3 小时前
Vue 中 v-text 与 v-html 的区别:文本渲染与 HTML 解析的抉择
前端·javascript·vue.js
fruge3 小时前
接口 Mock 工具对比:Mock.js、Easy Mock、Apifox 的使用场景与配置
开发语言·javascript·ecmascript