vueCli-封装Echarts图表组件

写在前面


最近好长时间一直在做可视化项目,我采用的是echarts可视化图表工具画图,一开始由于时间的仓促,还有没有去研究,各方面原因吧,以前每次做图表之类的都没有封装,每次做图表都要从新去配置之类的,写了好多重复代码,感觉很累啊,所以自己把图表封装成子组件使用,代码工作量减轻了很多,而且子组件使用了数据进行监听和图表自适应屏幕大小,这样以后会方便很多了!简直帅到爆,不多说了,上思路和代码。

我用的是vue-cli全家桶+echarts,做的封装,先将代码贴出来,以便于学习以及帮助到小伙伴

首先用的脚手架需要先安装echarts,然后全局引入

npm install echarts --save
全局引入,main.js里边配置
// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
这样在每个页面就可以使用了

之前一开始都是每个页面配置,现在将其封装好,方便开发以及维护。下边为思路以及代码

StepOne: 在项目的components下新建一个文件夹Echarts,在其下边新建一个index.vue,里边存放公共的echarts组件。里边的注释我已经写的很全面了,还有不理解的评论。原理就是正常的父子组件传值。

由于Echarts/index.vue子组件在初始化就会加载,后期不会更新,再加上由于echarts采用的数据驱动,所以需要监听数据的变化来重绘图表

<template>
每一个图表都有自己唯一的id,所有需要动态传入。
  <div class="echartsLine"
       :id="id"
       :style="style"></div>
</template>
<script>
export default {
  props: {
    id: {
      type: String
    },
    width: {
      type: String,
      default: "100%"
    },
    height: {
      type: String
    },
    option: {
      type: Object
    }
  },
  data() {
    return {
      MyEcharts: "" //echarts实例
    };
  },
  computed: {
    style() {
      return {
        height: this.height,
        width: this.width
      };
    }
  },
  watch: {
    //要监听的对象 option
    //由于echarts采用的数据驱动,所以需要监听数据的变化来重绘图表
    option: {
      handler(newVal, oldVal) {
        if (this.MyEcharts) {
          if (newVal) {
            console.log(newVal);
           第一种方法:
           this.MyEcharts.setOption(newVal, true);
           第二种方法:
            let publicCharts = this.MyEchartsOption(newVal);
            console.log(publicCharts);
            this.MyEcharts.setOption(publicCharts, true);
          } else {
           第一种方法:
           this.MyEcharts.setOption(oldVal, true);
          第二种方法:
            let publicCharts = this.MyEchartsOption(oldVal);
            this.MyEcharts.setOption(publicCharts, true);
          }
        } else {
          this.InitCharts();
        }
      },
      deep: true //对象内部属性的监听,关键。
    }
  },
  mounted() {
    this.InitCharts();
  },
  methods: {
    //所设计的图表公共组件,不论第一种方法还是第二种方法都按照官网的格式来写数据,这样方便维护
    InitCharts() {
      this.MyEcharts = this.$echarts.init(document.getElementById(this.id));
      /**
       * Author  HaoYanFeng
       * 第一种
       * 此方法适用于所有项目的图表,但是每个配置都需要在父组件传进来,相当于每个图表的配置都需要写一遍,不是特别的省代码,主要是灵活度高
       * echarts的配置项,你可以直接在外边配置好,直接扔进来一个this.option
       */
       this.MyEcharts.clear(); //适用于大数据量的切换时图表绘制错误,先清空在重绘
      this.MyEcharts.setOption(this.option, true); //设置为true可以是图表切换数据时重新渲染
      /**
       * Author  HaoYanFeng
       * 第二种
       * 此方法不适用于所有项目,只适用于本项目,但是可以省好多代码,维护性高
       * 在这你还可以根据需求将你的配置项中公共的提取出来,这样就可以省很多代码
       */
      console.log(this.option);
      if (this.option.tooltip != undefined) {
        let publicCharts = this.MyEchartsOption(this.option);
        console.log(publicCharts);
        this.MyEcharts.clear(); //适用于大数据量的切换时图表绘制错误,先清空在重绘
        this.MyEcharts.setOption(publicCharts, true); //设置为true可以是图表切换数据时重新渲染
      }
   以下这种方法,当一个页面有多个图表时,会有一个bug那就是只有一个图表会随着窗口大小变化而变化,经过小编的努力,终于找到解决办法。
      window.onresize = () => {
        this.MyEcharts.resize();
      }; //当窗口变化时随浏览器大小而改变
以下为上边的bug的解决方案。以后用这种方案,放弃上一种。
      let _this = this;
      window.addEventListener("resize", function() {
        _this.MyEcharts.resize();
      });
    },
    /**
     * Author  HaoYanFeng
     * 第二种  公共的配置,省代码
     * 此方法不适用于所有项目,只适用于本项目,但是可以省好多代码,维护性高
     * 在这你还可以根据需求将你的配置项中公共的提取出来,这样就可以省很多代码
     */
    MyEchartsOption(configures) {
      if (configures.tooltip != undefined) {
        let MyOption = {
       //图标的标题   本项目暂未使用
          title: {
            // text: configures.title.text
          },
          //鼠标悬浮提示框
          tooltip: {
            trigger: "axis",
            confine: true, //是否将 tooltip 框限制在图表的区域内。  true为是
            axisPointer: {
              // 坐标轴指示器,坐标轴触发有效
              type: configures.tooltip.axisPointer.type // 默认为直线,可选为:'line' | 'shadow'
            },
            formatter: configures.tooltip.formatter
          },
          //图例
          legend: {
            //图例的数据数组
            // data: configures.legend.data, //图例的数据数组   一般不设置,自动根据数据匹配
            top: configures.legend.top, //图例组件离容器上侧的距离
            right: configures.legend.right, //图例组件离容器右侧的距离
            bottom: configures.legend.bottom, //图例组件离容器下侧的距离
            left: configures.legend.left, //图例组件离容器左侧的距离
            textStyle: {
              color: this.echartsXYcolor //在本项目中涉及到主题色切换,所以采用动态颜色,黑白两色,下边相同
            }
          },
          //工具栏。内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具。
          // toolbox: {
          //   feature: {
          //     saveAsImage: {}
          //   }
          // },
          //直角坐标系内绘图网格
          grid: {
            top: configures.grid.top, //grid 组件离容器上侧的距离。也就是图表距离容器
            //在本项目中每个图表都是距左右下100px,这样的话就有一个缺点不灵活,但是适用于本项目,不需要每一个都修改,若要做灵活了就是如top写法,每个图表都要配置
            left: "100px",
            right: "100px",
            bottom: "100px"
          },
          //x轴的数据以及配置
          xAxis: {
            type: configures.xAxis.type, //坐标轴类型。具体参考官方文档
            boundaryGap: configures.xAxis.boundaryGap, //类目轴中 boundaryGap 可以配置为 true 和 false。默认为 true,这时候刻度只是作为分隔线,标签和数据点都会在两个刻度之间的带(band)中间。
            data: configures.xAxis.data, //x轴的数据
            axisLine: {
              lineStyle: {
                color: this.echartsXYcolor
              }
            },
            axisLabel: {
              textStyle: {
                color: this.echartsXYcolor
              }
            }
          },
          //y轴的数据配置
          yAxis: {
            axisLine: {
              lineStyle: {
                color: this.echartsXYcolor
              }
            },
            axisLabel: {
              textStyle: {
                color: this.echartsXYcolor
              },
              formatter: configures.yAxis.axisLabel.formatter
            }
          },
          // dataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。
          dataZoom: [
            {
              type: "inside"
            },
            {
              type: "slider",
              top: configures.dataZoom[1].top, //距离容器上边的距离
              textStyle: {
                color: this.echartsXYcolor
              }
            }
          ],
          //图表的数据
          series: configures.series //由于数据的灵活度大,所以完全采用传入的方式
        };
        return MyOption;
      }
    }
  }
};
</script>
<style lang="scss" scoped>
</style>
StepTwo:在使用页面例如有一个mycharts.vue文件,引用直接引入并传值就好了。
<template>
    <!-- 业绩表现 -->
    <div class="index">
            <MyEcharts :id="'exampleId'"
                       :style="{width: '100%', height: '380px'}"
                       :option="chartOption">
            </MyEcharts>
    </div>
</template>
import MyEcharts from "@/components/Echarts/index"; //echarts
export default {
  components: {
    MyEcharts
  },
  data() {
    return {
       chartOption: {},
     echartsXYcolor:"#fff000",
     lineColor:"#5bb1f0"
      }
},
mounted(){
   this.initCharts();
},
methods:{
   initCharts(){
        this.chartOption = {
         title: {
            text: '折线图'
          },
          tooltip: {
            trigger: "axis",
            confine: true, //是否将 tooltip 框限制在图表的区域内。  true为是
            axisPointer: {
              // 坐标轴指示器,坐标轴触发有效
              type: "line" // 默认为直线,可选为:'line' | 'shadow'
            },
            formatter: function(params) {
              return params;
            }
          },
          legend: {
            data:[],
            top: "93%",
            right:'center',
            bottom:"center",
            left:"center",
            textStyle: {
              color: this.echartsXYcolor
            }
          },
          // toolbox: {
          //   feature: {
          //     saveAsImage: {}
          //   }
          // },
          grid: {
            top: "3%",
            left: "100px",
            right: "100px",
            bottom: "100px"
          },
          xAxis: {
            type: "category",
            boundaryGap: false,
            data: data: ['周一','周二','周三','周四','周五','周六','周日'],
            axisLine: {
              lineStyle: {
                color: this.echartsXYcolor
              }
            },
            axisLabel: {
              textStyle: {
                color: this.echartsXYcolor
              }
            }
          },
          dataZoom: [
            {
              type: "inside"
            },
            {
              type: "slider",
              top: "82%",
              textStyle: {
                color: this.echartsXYcolor
              }
            }
          ],
          yAxis: {
            axisLine: {
              lineStyle: {
                color: this.echartsXYcolor
              }
            },
            axisLabel: {
              textStyle: {
                color: this.echartsXYcolor
              },
              formatter: function(val) {
                return (val * 1).toFixed(2) + "%";
              }
            }
          },
          series: [
            {
              name: '邮件营销',
              type: "line",
              lineStyle: {
                color: this.lineColor // 线的颜色
              },
              itemStyle: {
                color: this.lineColor// 图例的颜色
              },
              showSymbol: false, // 不显示symbol
             data:[120, 132, 101, 134, 90, 230, 210]
            }
          ]
        };
}
}
}
结束语

至此,一个完整的封装好的公共的vue-echarts组件就完工了,可以在项目中直接调用,里边都有公共的配置项,以及父组件完全传入配置两种方案,各有利弊,还有重绘,以及随浏览器大小而改变大小。希望简友可以提宝贵的意见在评论区评论。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值