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


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

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

相关推荐
fruge4 小时前
前端三驾马车(HTML/CSS/JS)核心概念深度解析
前端·css·html
百锦再4 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
烛阴4 小时前
Lua 模块的完整入门指南
前端·lua
浪里行舟5 小时前
国产OCR双雄对决?PaddleOCR-VL与DeepSeek-OCR全面解析
前端·后端
znhy@1235 小时前
CSS易忘属性
前端·css
瓜瓜怪兽亚5 小时前
前端基础知识---Ajax
前端·javascript·ajax
AI智能研究院5 小时前
(四)从零学 React Props:数据传递 + 实战案例 + 避坑指南
前端·javascript·react.js
qq7798233405 小时前
React组件完全指南
前端·javascript·react.js
EndingCoder5 小时前
MongoDB基础与Mongoose ODM
服务器·javascript·数据库·mongodb·中间件·node.js