WangEcharts使用说明

69 阅读5分钟

组件目录

 |-- components

     |-- WangEcharts                                           

         |-- index.vue                         // echarts组件 用于echarts初始化 并通过监听props触发echarts的setOption

         |-- config                            // 实现echarts组件按需引用

             |-- index.ts
             
         |-- options
         
             |-- commonConfig.js                // echarts 通用配置(grid/xAxis/yAxis/tooltip等 可根据设计的UI进行相应配置)
             
             |-- utils.js                       // options生成代码中用到的方法 如deepMerge
             
             |-- line                           // 集合所有的折线图配置
                
                 |-- baseLine.js                // 基础折线图options
                 
                 |-- index.js                   // 导出所有的折线图配置
                 
         |-- echartsOptionModules.js            // 集合所有echarts图表的options
                

使用流程

  1. 在main.ts中引入echartsOptionModules.js,并通过app.config.globalProperties.***声明定义一个应用级的全局方法;
// eChartFn
import eChartFn from "@/components/WangEcharts/echartsOptionModules.js";

app.config.globalProperties.$eChartFn = eChartFn;
  1. 在需要使用的WangEcharts的Vue文件中,先引入WangEcharts组件,接口调用获取echarts数据后,通过proxy.$eChartFn调用挂载的全局方法,传入echartData以及其他自定义配置如tooltip(自定义配置会合并或替换之前已有的配置),得到option,通过props的方式传递给WangEcharts组件。
<template>
  <div class="card content-box">
    <WangEcharts :option="singleSiteYq" />
  </div>
</template>

<script setup lang="ts" name="lineChart">
import { ref, getCurrentInstance } from "vue";
import WangEcharts from "@/components/WangEcharts/index.vue"; // 引入WangEcharts组件

// proxy相当于 vue2的this,从getCurrentInstance 实例中获取,proxy对象
const { proxy } = getCurrentInstance();

const singleSiteYq = ref({});
const baselineInstance = proxy.$eChartFn.baseLine({  // proxy.$eChartFn调用挂载的全局方法
  echartData: [ // 通过接口调用等方式获取的echarts数据
    {
      name: "2023-11-10",
      value: 1.2
    },
    {
      name: "2023-11-11",
      value: 0.2
    },
    {
      name: "2023-11-12",
      value: 2.4
    },
    {
      name: "2023-11-13",
      value: 1.2
    }
  ],
  tooltip: { // 其他自定义配置
    formatter: function (params) {
      return `<div class="formatter">${params.name}降雨量${params.value}mm</div>`;
    }
  },
  showBack: true
});
singleSiteYq.value = baselineInstance.option; // 得到option
</script>

注意事项

  1. WangEcharts通过utils.js 的deepMerge实现自定义配置的合并或替换,即配置已存在则用传入的新的配置进行替换,配置不存在则合并至options,这个合并流程是深度的。传入的自定义配置的结构要符合echarts option的结构标准
/**
 * 深度合并代码,思路来自 zepto.js 源代码
 * 切记不要对象递归引用,否则会陷入递归跳不出来,导致堆栈溢出
 * 作用是会合并 target 和 other 对应位置的值,冲突的会保留 other 的值
 */
export const deepMerge = (target, other) => {
  const isObject = source => Object.prototype.toString.call(source) === "[object Object]";
  const isArray = source => Object.prototype.toString.call(source) === "[object Array]";
  if (isObject(target) && isObject(other)) {
    for (let [key, val] of Object.entries(other)) {
      if (!target[key]) {
        target[key] = val;
      } else {
        if (isObject(target[key])) {
          target[key] = deepMerge(target[key], val);
        } else {
          target[key] = val;
        }
      }
    }
  } else if (isArray(target) && isArray(other)) {
    for (let [key, val] of Object.entries(other)) {
      if (target[key]) {
        target[key] = deepMerge(target[key], val);
      } else {
        target.push(val);
      }
    }
  }
  return target;
};

  1. WangEcharts可以监听echarts图表的点击事件,比如点击返回按钮返回至上一级,主要是通过protoman.min.js实现相关监听。相关流程包括:
  • 在index.html中引入protoman.min.js
<script src="/js/protoman.min.js"></script>
  • 在需要抛出事件的代码模块先进行初始化
const protoevt = new protoman.sm.Evented();
for (const attr in protoevt) {
    this[attr] = protoevt[attr];
}
  • 监听点击事件,并将事件抛出来
//展示返回按钮
if (obj.showBack) {
    this.option.toolbox = commonCongif.toolbox;
    this.option.toolbox.feature.myTool1.onclick = function () {
      this.trigger("goBack");
    }.bind(this);
}
  • 在引入WangEcharts的Vue文件中进行事件监听
baselineInstance.on("goBack", () => {
  alert("clicked goBack");
});

1721697769593.jpg

  1. 在某个图表的配置js文件中,如果需要通过Object.assign对通用配置commonConfig.js里面的配置进行合并时,Object.assign方法中的目标对象一定要是空对象,而不是commonConfig.js里面的配置对象,不然会导致commonConfig.js里面的配置对象被修改,影响其他使用commonConfig.js的图表的配置option。这是因为在 ES6 中,模块系统的导入与导出采用的是引用导出与导入(非简单数据类型),也就是说,如果在一个模块中定义了一个对象并导出,在其他模块中导入使用时,导入的其实是一个变量引用,如果修改了对象中的属性,会影响到其他模块的使用
    例如在能源一体化首页中,由于之前我将Object.assign方法中的目标对象设置为commonConfig.js里面的配置对象,在打开一个y轴设置了min/max/interval配置的图表后,再打开另一个图表,会导致该图标的y轴数据会变的跟上一个图表一致。

  2. 如果将echarts设置中的notMerge设置为false,会导致当前生成的series合并之前的series,导致数据污染问题。 例如在能源一体化首页中左下的用电组成堆叠柱状图中,由于之前将notMerge设置为false,导致在进行昨日/本月切换时,本月的数据中有尖电数据,而昨日的数据中没有尖电数据,图表中却展示了本月的数据中的尖电数据。

在el-dialog中使用WangEcharts,关闭el-dialog时需要将chartOption设置为{},不然下次打开el-dialog时,新的echarts图表的option会与上一次生成的option合并,导致echarts图表展示错误。

数据动态更新

实现WangEcharts数据动态更新的步骤包括:

  1. WangEcharts/index.vue文件中,setOption 方法中传入notMerge: false 和 lazyUpdate: true 选项,以确保动画能够正常播放
const draw = () => {
  if (chartInstance.value) {
    // setOption 方法中传入notMerge: false 和 lazyUpdate: true 选项,以确保动画能够正常播放
    chartInstance.value.setOption(props.option, { notMerge: false }, { lazyUpdate: true });
  }
};
  1. WangEcharts/options目录下的js中echarts option的series中设置动画时长以及动画缓动效果或者在使用WangEcharts的Vue文件中传入自定义配置生成option时带入以下动画配置
animationDurationUpdate: 300, // 更新动画时长为 1s
nimationEasingUpdate: "quinticOutIn" // 更新动画缓动效果为'quinticInout
  1. 在使用WangEcharts的Vue文件中通过定时器实时修改x轴以及y轴的数据
// 实时修改数据
let dataIndex = 0;
setInterval(() => {
  dataIndex++;
  if (dataIndex + 6 === data.length) dataIndex = 0;
  const echartsData = data.slice(dataIndex, 6 + dataIndex);
  singleSiteYq.value = {
    xAxis: {
      data: echartsData.map(item => item.name)
    },
    series: [
      {
        data: echartsData.map(item => item.value)
      }
    ]
  };
}, 4000);

echarts配置总结

  1. 可通过textStyle对图表的字体、字体大小、字体颜色等进行全局配置,在xAxis、yAxis等配置项中无相关配置的情况下,textStyle中的配置会生效。这样一是可以缩减代码量,二是统一配置方便调整。
  2. grid中的containLabel设置为true,会导致y轴label变动(数值变化或者切换展示/隐藏)以及y轴整体展示/隐藏时,x轴以及y轴的位置发生变化。因为containLabel 为 true 的时候:grid.left grid.right grid.top grid.bottom grid.width grid.height 决定的是包括了坐标轴标签在内的所有内容所形成的矩形的位置。在能源一体化首页电力趋势分析图表中,默认不展示后六条数据对应的y轴,如果containLabel设置为true,会导致y轴展示后,图表展示区域变化,进而与上面的自定义legend不对齐,所以这种情况下,containLabel虚设置为false。

echarts通用问题