getuuid
export function getuuid() {
  // 生成随机数
  var s = []
  var hexDigits = '0123456789abcdef'
  for (var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
  }
  s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = '-'
  var uuid = s.join('')
  return uuid
}

echart resize
import { debounce } from '@/utils'

export default {
  data() {
    return {
      $_sidebarElm: null,
      $_resizeHandler: null
    }
  },
  mounted() {
    this.$_resizeHandler = debounce(() => {
      if (this.chart) {
        this.chart.resize()
      }
    }, 100)
    this.$_initResizeEvent()
    this.$_initSidebarResizeEvent()
  },
  beforeDestroy() {
    this.$_destroyResizeEvent()
    this.$_destroySidebarResizeEvent()
  },
  // to fixed bug when cached by keep-alive
  // https://github.com/PanJiaChen/vue-element-admin/issues/2116
  activated() {
    this.$_initResizeEvent()
    this.$_initSidebarResizeEvent()
  },
  deactivated() {
    this.$_destroyResizeEvent()
    this.$_destroySidebarResizeEvent()
  },
  methods: {
    // use $_ for mixins properties
    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
    $_initResizeEvent() {
      window.addEventListener('resize', this.$_resizeHandler)
    },
    $_destroyResizeEvent() {
      window.removeEventListener('resize', this.$_resizeHandler)
    },
    $_sidebarResizeHandler(e) {
      if (e.propertyName === 'width') {
        this.$_resizeHandler()
      }
    },
    $_initSidebarResizeEvent() {
      this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
      this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
    },
    $_destroySidebarResizeEvent() {
      this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
    }
  }
}

柱状图和饼图切换
<template>
  <el-card class="box-card" shadow="never">
    <div
      :id="uuid"
      :class="className"
      :style="{ height: height, width: width }"
    />
  </el-card>
</template>

<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
import { getuuid } from '@/utils/index'
import { queryConserveLevelStatistics } from '@/api/bridge-file/bridge-chart'
export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '220px'
    },
    autoResize: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      chartData: null,
      uuid: null,
      chart: null
    }
  },
  watch: {
    chartData: {
      deep: true,
      handler(val) {
        if (Object.keys(val).length === 0) {
          this.chart.clear()
          this.chart.showLoading({
            text: '暂无数据',
            color: '#ffffff',
            textColor: '#8a8e91',
            maskColor: 'rgba(255, 255, 255, 0.8)'
          })
        } else {
          this.chart.hideLoading()
          this.setOption(val)
        }
      }
    }
  },
  created() {
    this.uuid = getuuid()
    this.getConserveLevelStatistics()
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    async getConserveLevelStatistics() {
      this.chartData = await queryConserveLevelStatistics()
    },
    initChart() {
      const chartDom = document.getElementById(this.uuid)
      this.chart = echarts.init(chartDom, 'macarons')
      this.chart.showLoading({
        text: '暂无数据',
        color: '#ffffff',
        textColor: '#8a8e91',
        maskColor: 'rgba(255, 255, 255, 0.8)'
      })
    },
    setOption(res) {
      const scope = this
      const data = res.map((item) => {
        const arr = Object.values(item)
        // const left = arr.shift()
        // arr.splice(1, 0, left)
        return arr
      })
      scope.option = {
        title: { text: '桥梁养护等级分类统计', left: 'left' },
        legend: {
          type: 'scroll',
          orient: 'vertical',
          left: 5,
          top: 50,
          bottom: 5,
          itemWidth: 10,
          itemHeight: 10
        },
        tooltip: {},
        dataset: {
          dimensions: ['数量', '类型', '占比'],
          source: data
        }
      }
      const opt = JSON.parse(JSON.stringify(scope.option))
      const pieOpt = scope.setPieChart()
      // const barOpt = scope.setBarChart()
      const temp = Object.assign(opt, pieOpt)
      scope.chart.setOption(temp)
    },
    setPieChart() {
      const scope = this
      const opt = JSON.parse(JSON.stringify(scope.option))
      const pieOpt = {
        toolbox: {
          show: true,
          orient: 'vertical',
          feature: {
            myToolBar: { show: false },
            myToolPie: {
              show: true,
              title: '切换为柱状图',
              icon: 'path://M512 752.16a32 32 0 0 1-32-32V350.624a32 32 0 0 1 64 0v369.536a32 32 0 0 1-32 32zM320 752.576a32 32 0 0 1-32-32V512a32 32 0 0 1 64 0v208.576a32 32 0 0 1-32 32zM896 752.672a32 32 0 0 1-32-32V163.488a32 32 0 1 1 64 0v557.184a32 32 0 0 1-32 32zM704 752.736a32 32 0 0 1-32-32V224a32 32 0 1 1 64 0v496.736a32 32 0 0 1-32 32z',
              // 点击返回事件
              onclick: function() {
                const barOpt = scope.setBarChart()
                const temp = Object.assign(opt, barOpt)
                scope.chart.clear()
                scope.chart.setOption(temp)
              }
            },
            saveAsImage: {}
          }
        },
        series: [
          {
            type: 'pie',
            radius: ['40%', '70%'],
            startAngle: 45,
            top: '30',
            left: '30%',
            encode: { itemName: 1, value: 0 },
            label: {
              show: true,
              alignTo: 'labelLine',
              verticalAlign: 'middle',
              overflow: 'truncate',
              position: 'outer',
              edgeDistance: 10,
              distanceToLabelLine: 10,
              bleedMargin: 10,
              formatter: '{d}%'
            }
          }
        ]
      }
      return pieOpt
    },
    setBarChart() {
      const scope = this
      const opt = JSON.parse(JSON.stringify(scope.option))
      const barOpt = {
        xAxis: {
          type: 'category',
          axisLabel: {
            interval: 0,
            rotate: 45,
            formatter: function(name) {
              if (name.length > 2) {
                return name.slice(0, 2) + '...'
              } else {
                return name
              }
            }
          },
          name: '养护等级',
          nameLocation: 'end',
          nameRotate: 90,
          nameTextStyle: {
            align: 'center',
            verticalAlign: 'middle'
          }
        },
        yAxis: {
          type: 'value',
          name: '数量(座)'
        },
        grid: {
          left: '10%',
          right: '20%',
          bottom: '30%'
        },
        toolbox: {
          show: true,
          orient: 'vertical',
          feature: {
            myToolPie: { show: false },
            myToolBar: {
              show: true,
              title: '切换为饼图',
              icon: 'path://M469.333333 213.333333v85.333334c-119.466667 12.8-213.333333 110.933333-213.333333 234.666666 0 128 106.666667 234.666667 234.666667 234.666667 123.733333 0 221.866667-93.866667 234.666666-213.333333h85.333334c-12.8 166.4-149.333333 298.666667-320 298.666666C315.733333 853.333333 170.666667 708.266667 170.666667 533.333333c0-170.666667 132.266667-307.2 298.666666-320z m384 298.666667h-341.333333V170.666667c187.733333 0 341.333333 153.6 341.333333 341.333333z m-256-243.2V426.666667h157.866667c-12.8-42.666667-106.666667-145.066667-157.866667-157.866667z',
              onclick: function() {
                const pieOpt = scope.setPieChart()
                const temp = Object.assign(opt, pieOpt)
                scope.chart.clear()
                scope.chart.setOption(temp)
              }
            },
            saveAsImage: {}
          }
        },
        series: [
          {
            type: 'bar',
            barMaxWidth: 40,
            encode: { x: 1, y: 0, tooltip: [0, 1, 2] },
            label: {
              show: true,
              align: 'left',
              rotate: 90,
              position: 'insideBottom',
              distance: 15,
              verticalAlign: 'middle',
              formatter: function(params) {
                if (params.value[2]) {
                  return params.value[2]
                }
              }
            }
          }
        ]
      }
      return barOpt
    }
  }
}
</script>

<style lang="scss" scoped></style>
posted on 2022-02-22 10:17  羊支甘陆  阅读(1035)  评论(0编辑  收藏  举报