echarts 动态图表

动态图表实现的主题思路是通过 setOption 方法更新数据, echarts 会根据数据的更新动态修改图表内容

初始化图标

 this.racingChart = echarts.init(this.$refs.charts);

初始化 options

    initOptions() {
      this.options = {
        xAxis: {
          max: "dataMax", //用数据的最大值作为 X 轴最大值,视觉效果更好
        },
        yAxis: {
          type: "category",
          data: provinces,
          axisLabel: { fontSize: 20 },
          inverse: true, //设为 true,表示 Y 轴从下往上是从小到大的排列
          animationDuration: 300, //表示第一次柱条排序动画的时长
          animationDurationUpdate: 300, //表示第一次后柱条排序动画的时长
          max: 6, // only the largest 3 bars will be displayed
        },
        series: [
          {
            realtimeSort: true,
            seriesLayoutBy: "column",
            type: "bar",
            itemStyle: {    // 为bar设置颜色
              color: params => {
                return provinceColor[params.name] || "#5470c6";
              },
            },
            data: baseData,
            label: {
              show: true,
              position: "right",
              fontSize: 32,
              valueAnimation: true, //实时改变标签
            },
          },
        ],
        legend: {
          show: true,
        },
        textStyle: {
          fontSize: 32,
        },
        animationDuration: 1500, //第一份数据不需要从 0 开始动画(如果希望从 0 开始则设为和 animationDurationUpdate 相同的值)
        animationDurationUpdate: 1500, // 动画时长为1.5秒,比更新间隔短,避免动画被打断
        animationEasing: "line", 
        animationEasingUpdate: "line",
      };
      this.start();
    },

series 数组中data 数据可以是对应的值也可以是 [...,{name:"",value:""},...]的对象数组 . value 值是必须要有的

更新数据(实现动态排序的主要逻辑)

    updateData() {
      console.log(this.count);
      if (this.count > 2025 - 1949 - 1) {
        return;
      }
      // 增量更新数据 - 只修改数据值而不创建新数组
      const seriesData = this.options.series[0].data;

      if (!seriesData || !Array.isArray(seriesData)) return;

      seriesData.forEach(item => {
        if (!item) return;
        // 随机增长或减少(-5%到15%之间)
        const changeRate = Math.random() * 0.2 - 0.05;
        item.value = Math.max(100, Math.round(item.value * (1 + changeRate)));
      });

      try {
        // 使用notMerge:true和lazyUpdate:true优化性能
        this.racingChart.setOption(this.options, {
          notMerge: false,
          lazyUpdate: true,
          silent: true,
        });
      } catch (e) {
        console.error("ECharts update error:", e);
      }
      this.count++;
    },

主要思路就是,通过修seriesdata 数据,重setOption echarts 更新视图 . 由于这里是模拟数据,所以直接循环随机变更. 实际业务中需要对数据源进行格式限制,方便操作

优化:

1. notMerge: false

  • 作用:控制是否 合并新旧配置

    • false默认值,将新旧配置深度合并,保留未被覆盖的原有配置

    • true:完全替换配置(不推荐常规使用),可能导致图表状态丢失

  • 优化逻辑
    增量更新时,合并配置可以避免重新初始化全部属性(如动画状态、高亮状态),减少计算量


2. lazyUpdate: true

  • 作用:控制是否启用 延迟更新机制

    • true:将更新放入异步队列,在浏览器空闲时批量处理渲染(类似 requestIdleCallback

    • false:同步立即重渲染(默认行为)

  • 优化逻辑
    在频繁调用 setOption() 时(如实时数据推送),避免连续重绘导致的性能抖动,利用浏览器空闲时间合并计算


3. silent: true

  • 作用:控制是否 触发图表事件/生命周期钩子

    • true:静默更新,不触发 renderedfinished 等事件

    • false:触发常规事件处理(默认行为)

  • 优化逻辑
    跳过事件处理逻辑可以减少不必要的回调执行,适用于无交互反馈的纯数据更新场景

附:官方配置参考

参数名

类型

默认值

说明

notMerge

boolean

false

是否不与之前设置的 option 合并

lazyUpdate

boolean

false

在设置完 option 后是否不立即更新图表

silent

boolean

false

阻止触发事件,值为 true 时不触发事件

合理搭配这些参数可以显著提升大数据量或高频更新场景下的图表性能表现。

开启动态表单

    start() {
      // 改用requestAnimationFrame实现更流畅的动画循环
      let lastTime = 0;
      const interval = 1510; // 调整为*秒更新一次数据

      const animate = time => {
        if (time - lastTime > interval) {
          this.updateData();
          lastTime = time;
        }
        this.animationId = requestAnimationFrame(animate);
      };

      this.animationId = requestAnimationFrame(animate);
    },

开启循环设置数据时,如果直setInterval 会出现动画卡顿的情况,因此使requesetAnimationFrame API , 高效执行动画或高频视觉更新,

settimeout/setInterval 它能:

  1. 自动同步浏览器刷新率(通常 60 FPS)

  2. 后台标签页自动暂停渲染,减少资源消耗

  3. 避免过度渲染导致的帧丢失

  4. 精准控制渲染时机,与 GPU 渲染周期对齐


echarts 动态图表
https://halo.jiangling.site/archives/echarts-dong-tai-tu-biao
作者
你的降灵
发布于
2025年07月13日
许可协议