Vue封装一个饼图、仪表盘和状态图

上一片笔记封装了柱形图和折线图
这一篇封装饼图、仪表盘和状态图
首先是饼图:

<template>
  <div>
    <div
     ref='piechart'
     class='echartbox'>
    </div>
  </div>
</template>

<script>
let echarts = require('echarts/lib/echarts')
// 引入饼图组件
require('echarts/lib/chart/pie')
// 引入提示框和title组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
require('echarts/lib/component/legend')
export default {
  name: 'Pie',
  props: {
    // texttitle: String,
    // legenddata: Array,
    // seriesdata: Array,
    textlink: {
      type: String,
      required: false,
      default: ''  
    },
    clicklink: {
      type: Boolean,
      required: false,
      default: false
    },
    piedata: Object
  },
  data () {
    return {
      link: this.textlink,
      click_link: this.clicklink,
      title: '',
      legend_data: [],
      series_data: []
    }
  },
  watch: {
    piedata (val) {
      this.title = val.title
      this.legend_data = val.legend_data
      this.series_data = val.series_data
      this.drawPie()
    }
  },
  mounted () {
    // this.drawPie()
  },
  methods: {
    drawPie () {
      let myCharts = echarts.init(this.$refs.piechart)
      myCharts.setOption({
        color: ['#83d0d5', '#f1cb48', '#188ae2', '#E8830B', '#7460ae', '#fc4b6c', '#31ce77', '#eae0bc', '#e732cb', '#9dce8a'],
        title: {
          text: this.title,
          left: '35',
          top: '20',
          link: this.link,
          textStyle: {
            color: '#B6B6B6'
          }
        },
        tooltip: {
          trigger: 'item',
          formatter: '{b} : {c} ({d}%)'
        },
        legend: {
          bottom: 10,
          left: 'center',
          data: this.legend_data,
          textStyle: {
            color: '#B6B6B6'
          }
        },
        series: [
          {
            name: this.title,
            type: 'pie',
            radius: '55%',
            center: ['50%', '45%'],
            avoidLabelOverlap: false,
            data: this.series_data,
            label: {
              normal: {
                formatter: '{c}'
              }
            }
          }
        ]
      })
      myCharts.on('click', this.clickEchats)
    },
    clickEchats (param) {
      console.log(param)
      if (this.click_link) {
        this.click_link = 'https://www.baidu.com/'
        window.location.href = this.click_link
      }
    }
  }
}
</script>

注意点:
1.饼图没有axis轴的数据,座椅后台返回的参数通常是三个,title,legend_data,series,我们将其直接一起放在piedata传递给子组件,一起传除了父组件传参的时候看不来不冗余,还有一个重要的原因,我们只需要在子组件中监听piedata的变化即可,然后会重新绘制图表,要不然需要监听三个参数
2.其他传默认值和bar图是一样的,不浪费口舌了,饼图没做自适应,因为大小差不了多少
3.饼图添加了一个点击的功能,就是点击饼图的那一部分,会跳转,但是不是所有的饼图都会跳转,所以设置了一个布尔值,默认是false,不传值默认就是false,不能点击,如果传值的话,传true的话们就可以点击。

      myCharts.on('click', this.clickEchats)
    },
    clickEchats (param) {
      console.log(param)
      if (this.click_link) {
        this.click_link = 'https://www.baidu.com/'
        window.location.href = this.click_link
      }
    }
  }

给echarts添加点击事件,如果click的值为true的话,就会实现跳转。

仪表盘组件的实现

<template>
  <div class='gaugeinfo'>
    <div
     ref='gaugechart'
     class='echartbox'
    >
    </div>
    <p class='targetnum'>Target:{{this.target_num}}</p>
  </div>
</template>

<script>
// 引入基本模板
let echarts = require('echarts/lib/echarts')
// 引入仪表图组件
require('echarts/lib/chart/gauge')
// 引入提示框和title组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
export default {
  name: 'Gauge',
  props: {
    textlink: {
      type: String,
      required: false,
      default: ''
    },
    gaugedata: Object
  },
  data () {
    return {
      link: this.textlink,
      maxnum: 0,
      target_num: 0,
      title: '',
      series_data: []
    }
  },
  watch: {
    gaugedata (val) {
      this.maxnum = val.max
      this.target_num = val.target
      this.title = val.title
      this.series_data = val.data
      this.drawGauge()
    }
  },
  mounted () {
    // this.drawGauge()
  },
  methods: {
    drawGauge () {
      let myCharts = echarts.init(this.$refs.gaugechart)
      let maxnum = this.maxnum
      let target = this.target_num
      let rate = target / maxnum
      myCharts.setOption({
        color: ['#83d0d5', '#f1cb48', '#188ae2', '#E8830B', '#7460ae', '#fc4b6c', '#31ce77', '#eae0bc', '#e732cb', '#9dce8a'],
        tooltip: {
          formatter: '{b}:{c}'
        },
        title: {
          text: this.title,
          left: '35',
          top: '20',
          link: this.link,
          textStyle: {
            color: '#B6B6B6'
          }
        },
        series: [
          {
            name: this.title,
            type: 'gauge',
            detail: {
              formatter: function (value) {
                console.log(value)
                return 'Actual : ' + value
              },
              fontSize: '14',
              offsetCenter: [0, '25%']
            },
            center: ['50%', '68%'],
            radius: '100%',
            startAngle: 160,
            endAngle: 20,
            min: 0,
            max: maxnum,
            splitNumber: 10,
            axisTick: {
              show: false
            },
            axisLine: {
              lineStyle: {
                color: [[rate, '#4E76BA'], [1, '#E8830B']]
              }
            },
            splitLine: {
              lineStyle: {
                color: '#898D95',
                width: 1
              }
            },
            axisLabel: {
              color: '#BFC2C8',
              formatter: function (value) {
                var median = maxnum / 2
                var max = maxnum
                switch (value) {
                  case 0: return '0'
                  case median: return median
                  case max: return maxnum
                }
              }
            },
            title: {
              show: false
            },
            // data: [{value: '25', name: 'Actual'}]
            data: this.series_data
          }
        ]
      })
    }
  }
}
</script>

注意点:
1.仪表盘的封装 和其他的不一样,需要有一个目标值和实际值,有两种颜色,未达标是一种颜色,达标了是一种颜色,所以需要根据数据控制仪表盘的颜色,在axisLine中实现

            axisLine: {
              lineStyle: {
                color: [[rate, '#4E76BA'], [1, '#E8830B']]
              }
            }

2.同时,我们并不希望显示所有的指针值,因为可能会出现非整数或者各种乱七八糟的显示,所以我们规定只显示三个数值,0,中间值和最大值
在axisLabel中定义
3.其余的就是父子组件中传值和其他的一样,监听一下来自父组件的传值

状态图组件的实现
状态图实际上是只显示一组数据的柱形图,但是根据内容的不同,柱形图的颜色显示不同,来代表不同的状态

<template>
  <div>
    <div
     ref='statusbarchart'
     class='echartbox'
    >
    </div>
  </div>
</template>

<script>
// 引入基本模板
let echarts = require('echarts/lib/echarts')
// 引入柱状图组件
require('echarts/lib/chart/bar')
// 引入提示框和title组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
export default {
  name: 'StatusBar',
  props: {
    // subtext: String,
    // texttitle: String,
    // axisdata: Array,
    // seriesdata: Array,
    textlink: {
      type: String,
      required: false,
      default: ''
    },
    sublink: {
      type: String,
      required: false,
      default: ''
    },
    xname: {
      type: String,
      required: false,
      default: ''
    },
    yname: {
      type: String,
      required: false,
      default: ''
    },
    statusdata: Object
  },
  data () {
    return {
      sun_link: this.sublink,
      link: this.textlink,
      x_name: this.xname,
      y_name: this.yname,
      title: '',
      subtitle: '',
      axis_data: [],
      series_data: []
    }
  },
  watch: {
    statusdata (val) {
      this.title = val.title
      this.subtitle = val.subtitle
      this.axis_data = val.Axis_data
      this.series_data = val.series_data
      this.drawBar()
    }
  },
  mounted () {
    // this.drawBar()
  },
  methods: {
    drawBar () {
      let myCharts = echarts.init(this.$refs.statusbarchart)
      myCharts.setOption({
        title: {
          text: this.title,
          left: '35',
          link: this.link,
          textStyle: {
            color: '#B6B6B6'
          },
          subtext: this.subtitle,
          sublink: this.sub_link,
          subtextStyle: {
            color: '#B6B6B6',
            fontSize: 18,
            fontWeight: 'bold'
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '15%',
          bottom: '30%',
          top: '25%'
        },
        legend: {
          show: false
        },
        xAxis: [
          {
            type: 'category',
            position: 'bottom',
            name: this.x_name,
            nameLocation: 'center',
            nameGap: '35',
            data: this.axis_data,
            axisTick: {
              show: false
            },
            axisLabel: {
              textStyle: {
                color: '#BFC2C8'
              },
              rotate: 30,
              interval: 0
            },
            axisLine: {
              lineStyle: {
                color: '#BFC2C8'
              }
            }
          }
        ],
        yAxis: [
          {
            type: 'value',
            left: '10',
            name: this.y_name,
            nameLocation: 'center',
            nameGap: '45',
            axisTick: {
              show: false
            },
            axisLine: {
              lineStyle: {
                color: '#BFC2C8'
              }
            },
            splitLine: {
              lineStyle: {
                color: '#898D95'
              }
            },
            axisLabel: {
              textStyle: {
                color: '#BFC2C8'
              },
              interval: 0,
              formatter: function (value, index) {
                if (value >= 1000 && value < 10000000) {
                  value = value / 1000 + 'K'
                } else if (value >= 1000000 && value < 1000000000) {
                  value = value / 1000000 + 'M'
                } else if (value >= 1000000000) {
                  value = value / 1000000000 + 'B'
                }
                return value
              }
            }
          }
        ],
        series: this.series_data
      })
      window.addEventListener('resize', function () {
        myCharts.resize()
      })
    }
  }
}
</script>

注意点:
如何控制柱形图颜色的显示?
在series中的seriesdata中itemStyle 的color定义柱形图的颜色

        // this.$set(this.statusdata.series_data[0], 'itemStyle', {
        //   color: function (params) {
        //     // console.log(params)
        //     var dataindex = params.dataIndex
        //     // console.log(dataindex)
        //     if (dataindex < 8) {
        //       return '#E3405C'
        //     } else if (dataindex === 8) {
        //       return '#1BBA83'
        //     } else {
        //       return '#4E76BA'
        //     }
        //   }
        // })

其余的和其他组件父子传值是一样的,注意监听来自父组件的数据变化。

猜你喜欢

转载自blog.csdn.net/hani_wen/article/details/81175411
今日推荐