Vue实战之封装组件echarts柱形图、折线图

封装一个echarts子组件,父组件可以多次调用
封装一个柱形图。
柱形图和折线图的区别在于series数据中的type的类型不同,柱形图的type为bar,折线图的type为line,所以封装柱形图的和折线图是一样的,只是两者传入的参数不同

封装一个bar类型的echarts图
子组件:

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

<script>
// 引入基本模板
let echarts = require('echarts/lib/echarts')
// 引入柱状图组件
require('echarts/lib/chart/bar')
// 引入折线图组件
require('echarts/lib/chart/line')
// 引入提示框和title组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
export default {
  name: 'Bar',
  props: {
    textlink: {
      type: String,
      required: false,
      default: ''
    },
    xname: {
      type: String,
      required: false,
      default: ''
    },
    yname: {
      type: String,
      required: false,
      default: ''
    },
    bardata: Object
  },
  data () {
    return {
      link: this.textlink,
      title: '',
      legend_data: [],
      axis_data: [],
      series_data: [],
      x_name: this.xname,
      y_name: this.yname
    }
  },
  watch: {
    bardata (val) {
      this.title = val.title
      this.legend_data = val.legend_data
      this.axis_data = val.Axis_data
      this.series_data = val.series
      this.drawBar()
    }
  },
  mounted () {
    // this.drawBar()
  },
  methods: {
    drawBar () {
      let myCharts = echarts.init(this.$refs.barchart)
      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: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '15%',
          bottom: '30%'
        },
        legend: {
          data: this.legend_data,
          left: 'center',
          bottom: '0',
          textStyle: {
            color: '#B6B6B6'
          }
        },
        xAxis: [
          {
            type: 'category',
            position: 'bottom',
            name: this.x_name,
            nameLocation: 'center',
            nameGap: '50',
            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',
            axisLine: {
              lineStyle: {
                color: '#BFC2C8'
              }
            },
            axisTick: {
              show: false
            },
            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>

父组件:

              <bar
               :textlink='barlink'
               :xname='xname'
               :yname='yname'
               :bardata='bardata'
              ></bar>

注意点:
1.后台传过来的参数,柱形图通常包括,series,title,legend_data, axis_data四项数据,这四项数据通常来说不需要单个传给子组件,可以将其作为一个整体传递过来。上例为bardata,里面包含这四项数据,在子组件中解析使用
2.有一些图标可能有横纵坐标的值,或者title点击有跳转的路由,有的没有,这种非强制性的参数我们可以选择在子组件中不强制传参,并设置一个默认值(比如说默认不显示,跳转路由为空),这样的话就是个性化定制了,如果想要显示横纵坐标的名字或者title有跳转,就可以从父组件中传值,不传也不会报错。
3.关于图表的自适应问题,bar图和line图通常来说会数据比较多,所以需要做好自适应的问题,echarts中的resize()方法可以解决这个问题

      window.addEventListener('resize', function () {
        myCharts.resize()

4.最为重要的一点!父组件向子组件传递参数的时候,会在渲染的时候传参,也就是说此时Ajax的数据还未到,就传送完毕了,Ajax数据到了之后也不会再传递,如何解决这个问题?
有两种比较常用的方法,一是,给子组件设置一个v-if,默认是不显示的,等数据加载完成之后,再给它传值,将其设置为true可见,但是这种方法在数据多变的情况下还是不行,所以一般采用第二种方法。
第二,在子组件中监听我们接收到的来自父组件的参数,如果发生变化,就重新赋值给图表参数,并重新绘制图表
如此,一个柱形图(折线图便封装完成了)

附: 有一种堆叠的柱形图,也是控制于数据series中,我们从后获取了数据,对其添加堆叠柱形图需要有的属性即可

this.stackdata = pipelinehealth
        for (let v of this.stackdata.series) {
          this.$set(v, 'label', {
            normal: {
              show: true,
              position: 'inside'
            }
          })
          this.$set(v, 'stack', 'all')
        }

我们获取数据之后,循环遍历series,往里面添加label对象和stack,要想堆叠,所有要堆叠的数据stack值必须一样,注意修改对象除了直接该引用,还有就是使用vm.$set()方法,这里的vm指向this实例
欧克,各种柱形图折线图,以及衍生搜可以通过这个组件实现了。

猜你喜欢

转载自blog.csdn.net/hani_wen/article/details/81174649