echarts 封装节省代码

<!--  
  @description: 二次封装echarts组件
  @Modifier:
  @routerPath:
  @date:  2020/12/29
-->
<template>
  <!-- 每一个图表都有自己唯一的id,所有需要动态传入。 -->
  <div :id="id" class="echartsLine" :style="style" />
</template>
<script>
import 'echarts/map/js/china.js'
export default {
  props: {
    id: {
      type: String,
      default: function() {
        return ''
      }
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    option: {
      type: Object,
      default: function() {
        return {}
      }
    }
  },
  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)
          } else {
            // 第一种方法:
            this.MyEcharts.setOption(oldVal, true)
            // 第二种方法:
            const 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))
      /**
       * 第一种
       * 此方法适用于所有项目的图表,但是每个配置都需要在父组件传进来,相当于每个图表的配置都需要写一遍,不是特别的省代码,主要是灵活度高
       * echarts的配置项,你可以直接在外边配置好,直接扔进来一个this.option
       */
      this.MyEcharts.clear() // 适用于大数据量的切换时图表绘制错误,先清空在重绘
      this.MyEcharts.setOption(this.option, true) // 设置为true可以是图表切换数据时重新渲染
      /**
       * 第二种
       * 此方法不适用于所有项目,只适用于本项目,但是可以省好多代码,维护性高
       * 在这你还可以根据需求将你的配置项中公共的提取出来,这样就可以省很多代码
       */
      // console.log(this.option)
      if (this.option.tooltip !== undefined) {
        const publicCharts = this.MyEchartsOption(this.option)
        console.log(publicCharts)
        this.MyEcharts.clear() // 适用于大数据量的切换时图表绘制错误,先清空在重绘
        this.MyEcharts.setOption(publicCharts, true) // 设置为true可以是图表切换数据时重新渲染
      }
      // 以下这种方法,当一个页面有多个图表时,会有一个bug那就是只有一个图表会随着窗口大小变化而变化,经过小编的努力,终于找到解决办法。
      window.onresize = () => {
        this.MyEcharts.resize()
      } // 当窗口变化时随浏览器大小而改变
      // 以下为上边的bug的解决方案。以后用这种方案,放弃上一种。
      const _this = this
      window.addEventListener('resize', function() {
        _this.MyEcharts.resize()
      })
    },
    /**
     * 第二种  公共的配置,省代码
     * 此方法不适用于所有项目,只适用于本项目,但是可以省好多代码,维护性高
     * 在这你还可以根据需求将你的配置项中公共的提取出来,这样就可以省很多代码
     */
    MyEchartsOption(configures) {
      if (configures.tooltip !== undefined) {
        const 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 // 在本项目中涉及到主题色切换,所以采用动态颜色,黑白两色,下边相同
            }
          },
          grid: {
            top: configures.grid.top, // grid 组件离容器上侧的距离。也就是图表距离容器
            // 在本项目中每个图表都是距左右下100px,这样的话就有一个缺点不灵活,但是适用于本项目,不需要每一个都修改,若要做灵活了就是如top写法,每个图表都要配置
            left: '3%',
            right: '3%',
            bottom: '3%'
          },
          // 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>

  

// 只需传入chartOption即可 
<template>
  <div>
    <MyEcharts
      :id="'MonthOrderOneChart'"
      :style="{width: '100%', height: '24vh'}"
      :option="chartOption"
    />
  </div>
</template>

<script>
import MyEcharts from './myEcharts'
// import echarts from 'echarts'
import 'echarts-liquidfill/src/liquidFill.js' // 在这里引入
export default {
  name: 'MonthOrderOneChart',
  components: {
    MyEcharts
  },
  data() {
    return {
      chartOption: {}
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      // var value = 0.4
      var data = [0.6, 0.6, 0.6]
      this.chartOption = {
        tooltip: {
          show: true
        },
        title: {
          // text: (value * 100).toFixed(0) + '{a|%}',
          textStyle: {
            fontSize: 50,
            fontFamily: 'Microsoft Yahei',
            fontWeight: 'normal',
            color: '#bcb8fb',
            rich: {
              a: {
                fontSize: 22
              }
            }
          },
          x: 'center',
          y: '35%'
        },
        graphic: [{
          type: 'group',
          left: 'center',
          top: '70%',
          children: [{
            type: 'text',
            z: 100,
            left: '10',
            top: 'middle',
            style: {
              fill: '#aab2fa',
              text: '招标',
              font: '18px Microsoft YaHei'
            }
          }]
        }],
        series: [{
          type: 'liquidFill',
          radius: '90%',
          data: data,
          label: {
            normal: {
              color: '#27e5f1',
              insideColor: '#aab2fa',
              textStyle: {
                fontSize: 30,
                fontWeight: 'bold'
              }
            }
          },
          backgroundStyle: {
            color: {
              type: 'linear',
              x: 1,
              y: 0,
              x2: 0.5,
              y2: 1,
              colorStops: [{
                offset: 1,
                color: 'rgba(68, 145, 253, 0)'
              }, {
                offset: 0.5,
                color: 'rgba(68, 145, 253, .25)'
              }, {
                offset: 0,
                color: 'rgba(68, 145, 253, 1)'
              }],
              globalCoord: false
            }
          },
          color: [{
            type: 'linear',
            x: 0,
            y: 1,
            x2: 0,
            y2: 0,
            colorStops: [{
              offset: 1,
              color: ['#9400D3'] // 0% 处的颜色
            }, {
              offset: 0,
              color: ['#00BFFF'] // 100% 处的颜色
            }],
            global: false // 缺省为 false
          }],
          outline: {
            borderDistance: 0,
            itemStyle: {
              borderWidth: 10,
              borderColor: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [{
                  offset: 0,
                  color: 'rgba(69, 73, 240, 0)'
                }, {
                  offset: 0.5,
                  color: 'rgba(69, 73, 240, .25)'
                }, {
                  offset: 1,
                  color: 'rgba(69, 73, 240, 1)'
                }],
                globalCoord: false
              },
              shadowBlur: 10,
              shadowColor: '#000'
            }
          }
        }]
      }
    }
  }
}
</script>
<style lang="less" scoped>
</style>

  

posted @ 2020-12-29 14:05  我自是年少  阅读(539)  评论(0编辑  收藏  举报