Newer
Older
CloudBrainNew / src / components / barChart / stackHorizontalBarChart.vue
StephanieGitHub on 4 Feb 2021 5 KB first commit
<template>
  <div
    :id="id"
    :style="`width:${curWidth};height:${curHeight}`"
  >
  </div>
</template>
<script>
/**
   * @author 王晓颖
   * @date 2020/08/18
   * @Description 堆叠水平柱状图
   * @props 数据格式:{
   *    id: '',
      width: 0,
      height: 0,
      xAxisData:['周一','周二','周三','周四','周五','周六','周日'],
      seriesData:
      [{name: '空闲数', data: [45, 45, 45, 45, 45, 45], color: '#d5384d', zlevel: 10},
       {name: '占用数', data: [34, 34, 34, 34, 34, 34], color: '#ff9e00', zlevel: 5},
       {name: '总数量', data: [100, 80, 100, 90, 140, 100], color: '#0468f1', zlevel: 0}
      ]
    }
   *
   */
import { countSize } from '@/utils/utils'
export default {
  name: 'StackHorizontalBarChart',
  props: {
    id: { // id
      type: String,
      default: 'stackHorizontalBarChart'
    },
    width: { // 宽
      type: Number | String,
      default: '100%'
    },
    height: { // 高
      type: Number | String,
      default: '100%'
    },
    unit: { // 单位
      type: String,
      default: ''
    },
    axisLineColor: { // 轴线颜色
      type: String,
      default: '#101d5d'
    },
    fontColor: { // 轴线上文字颜色
      type: String,
      default: '#ffffff'
    },
    labelColor: { // 图形上文本标签颜色
      type: String,
      default: '#47c8b2'
    },
    seriesData: { // 数据
      type: Array,
      default: () => { return [] }
    },
    xAxisData: { // X轴数据
      type: Array,
      default: () => { return [] }
    },
    colors: {
      type: Array,
      default: () => {
        return ['#0281de', '#fed700', '#68dfe3', '#fd9a19', '#fed700']
      }
    } // 颜色列表
  },
  data () {
    return {
      curWidth: this.width,
      curHeight: this.height,
      option: {
        tooltip: {
          trigger: 'axis', // 触发类型
          axisPointer: { // 坐标轴指示器,坐标轴触发有效
            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
          }
        },
        legend: {
          align: 'left',
          left: countSize(0.07),
          top: 0,
          right: 0,
          itemWidth: 8,
          itemHeight: 8,
          icon: 'rect',
          textStyle: {
            color: '#fff',
            fontSize: 11
          }
        },
        grid: {
          top: '10',
          left: '20',
          right: '5',
          bottom: '5',
          containLabel: true
        }, // 网格
        xAxis: {
          name: '', // 坐标轴名称
          nameTextStyle: { // 坐标轴名称的文字样式
            color: this.fontColor,
            fontSize: '50%',
            verticalAlign: 'middle'
          },
          type: 'value', // 数值轴
          // color: this.fontColor, //
          splitLine: { // 在grid区域中的分隔线
            lineStyle: {
              color: ['#101641'],
              type: 'dashed'
            }
          },
          axisLine: {
            lineStyle: {
              color: this.axisLineColor // y轴线的颜色
            }
          },
          axisLabel: {
            color: this.fontColor, // Y轴单位颜色
            fontSize: '40%'
          }
        },
        yAxis: {
          type: 'category', // 类目轴
          data: [
            // '周一','周二','周三','周四','周五','周六','周日'
          ],
          axisTick: {
            alignWithLabel: true
          },
          axisLine: {
            lineStyle: {
              color: this.axisLineColor // 轴线的颜色
            }
          },
          axisLabel: {
            color: this.fontColor, // X轴名称颜色
            fontSize: 8
          }
        },
        series: []
      }
    }
  },
  watch: {
    width (newVal, oldVal) {
      this.curWidth = newVal
      this.refreshEchart()
    },
    height (newVal, oldVal) {
      this.curHeight = newVal
      this.refreshEchart()
    },
    seriesData (newVal, oldVal) {
      this.option.series[0].data = newVal
      this.refreshEchart()
    },
    xAxisData (newVal, oldVal) {
      this.option.xAxis.data = newVal
      this.refreshEchart()
    }
  },
  mounted () {
    if (this.seriesData.length) {
      this.option.yAxis.data = this.xAxisData
      this.unit && (this.option.xAxis.name = this.unit)
      let newSeries = []
      const colors = this.colors
      for (let index in this.seriesData) {
        const item = this.seriesData[index]
        let series = {
          name: item.name,
          type: 'bar',
          stack: '总量',
          barWidth: countSize(0.06),
          itemStyle: {
            normal: {
              color: item.color ? item.color : colors[index],
              shadowBlur: [0, 0, 0, 10],
              shadowColor: item.color ? item.color : colors[index],
              barBorderRadius: [countSize(0.1), countSize(0.1), countSize(0.1), countSize(0.1)],
              shadowOffsetX: -3
            }
          },
          label: {
            normal: {
              show: true,
              position: 'insideRight',
              offset: [0, -countSize(0.09)],
              fontSize: '50%',
              color: item.color
            }
          },
          z: item.zlevel,
          data: item.data
        }
        newSeries.push(series)
      }
      this.$set(this.option, 'series', newSeries)
      this.initEchart()
    }
  },
  methods: {
    refreshEchart () {
      if (this.curWidth && this.curHeight && this.seriesData.length && this.xAxisData.length) {
        this.initEchart()
      }
    },
    initEchart () {
      const _div = document.getElementById(this.id)
      setTimeout(() => {
        let myChart = this.$echarts.init(_div)
        myChart.setOption(this.option, true)
        window.onresize = myChart.resize
      }, 500)
    }
  }
}
</script>

<style scoped>
</style>