echarts组件封装及使用

Echarts
封装echarts组件

<!-- 自适应布局放大缩小 -->
<template>
  <div class="echart-con" :id="echartId" v-if="!showEmpty"></div>
  <OccupyMap description="暂无数据..." v-else></OccupyMap>
</template>
<script>
  import * as echarts from 'echarts'
  import { extension } from '@/utils/methods'
  export default {
    props: {
      option: {
        type: Object,
        default: () => {},
      },
      config: {
        type: String,
        default: () => 'svg',
      },
      showEmpty: {
        type: Boolean,
        default: () => false,
      },
      textToop: {
        type: String,
        default: () => '',
      },
    },
    data() {
      return {
        echartId: 'myChart-' + Math.random() * 10,
        mychart: null,
      }
    },
    methods: {
      initEchart() {
        let { mychart } = this
        if (mychart !== null && mychart !== '' && mychart !== undefined) {
          mychart.dispose()
        }
        let chartDom = document.getElementById(this.echartId)
        this.mychart = echarts.init(chartDom, null, {
          renderer: 'canvas', // 设置渲染方式为 SVG
          ...this.config,
        })
        this.mychart.setOption(this.option, { lazyMode: true })
        if (this.textToop) {
          extension(this.mychart, this.textToop)
        }
        this.$emit('getChart', this.mychart)
        setTimeout(() => {
          this.mychart && this.mychart.resize()
        }, 300)
      },
      debounce(fn, delay = 500) {
        let timer = null
        return function () {
          if (timer) {
            clearTimeout(timer)
          }
          timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
          }, delay)
        }
      },
      addResize() {
        this.mychart && this.mychart.resize()
      },
    },
    watch: {
      option: {
        handler: function () {
          this.$nextTick(() => {
            this.initEchart()
          })
        },
        deep: true,
      },
      fold() {
        this.$nextTick(() => {
          this.mychart && this.mychart.resize()
        })
      },
      showEmpty() {},
    },

    computed: {
      fold() {
        return this.$store.getters.getFold
      },
    },
    mounted() {
      // 提示框中的点击事件
      function getDetails(data) {
        window.$ehl.bus.emit('chartTotable', data)
        //获取到点击查看的提示框的值
      }
      window.getDetails = getDetails
      window.addEventListener('resize', this.debounce(this.addResize), false)
    },
    beforeMount() {
      window.removeEventListener('resize', this.debounce(this.addResize), false)
    },
  }
</script>
<style lang="less" scoped>
  .echart-con {
    width: 100%;
    height: 100%;
  }
</style>

组件使用

<template>
  <div class="earlyWarning-container">
    <div class="chart_con" v-ehlLoading="isLoading1">
      <div class="module-title">
        <img :src="TitleIcon" alt="" />行为分布情况
      </div>
      <comEchartV1 :option="Option1" :showEmpty="showEmpty1" />
    </div>
    <div class="chart_con" v-ehlLoading="isLoading2">
      <div class="module-title">
        <img :src="TitleIcon" alt="" />地点分布情况
      </div>
      <comEchartV1 :option="Option2" :showEmpty="showEmpty2" />
    </div>
    <div class="chart_con" v-ehlLoading="isLoading3">
      <div class="module-title">
        <img :src="TitleIcon" alt="" />车辆分布情况
      </div>
      <comEchartV1 :option="Option3" :showEmpty="showEmpty3" />
    </div>
    <div class="chart_con" v-ehlLoading="isLoading4">
      <div class="module-title">
        <img :src="TitleIcon" alt="" />时段分布情况
      </div>
      <comEchartV1 :option="Option4" :showEmpty="showEmpty4" />
    </div>
  </div>
</template>
<script>
  import * as echarts from 'echarts'
  // import moment from 'moment'
  // import { Input } from 'element-ui'
  import TitleIcon from '@/views/sub_title_icon.png'
  // import { illegalHighChartList } from './config.js'
  import {
    postillegalAnalysisillegalAnalysisBehavior,
    postillegalAnalysisillegalAnalysisPlace,
    postillegalAnalysisillegalAnalysisVehicle,
    postillegalAnalysisillegalAnalysisTime,
    getalarmRulequeryRulesByAlarmCode,
  } from '@/utils/ajaxApi.js'
  // import { extension } from '@/utils/methods'
  import comEchartV1 from '@/common/echarts/comEchartV1.vue'
  export default {
    data() {
      return {
        TitleIcon,
        isLoading1: false,
        isLoading2: false,
        isLoading3: false,
        isLoading4: false,
        Option1: {},
        Option2: {},
        Option3: {},
        Option4: {},
        showEmpty1: false,
        showEmpty2: false,
        showEmpty3: false,
        showEmpty4: false,
        BehaviorAlarmValue: 0,
        PlaceAlarmValue: 0,
        CarAlarmValue: 0,
        BehaviorEchartData: [],
        placeEchartData: [],
        carEchartData: [],
        TimeEchartData: [],
      }
    },
    components: {
      comEchartV1,
    },
    props: {
      queryForm: {
        type: Object,
        default: () => {},
      },
      analysisHighIncidenceRules: {
        type: Object,
        default: () => {},
      },
    },
    methods: {
      getList(param) {
        this.gerCarData(param)
      },
      async gerCarData(param) {
        this.isLoading1 = true
        this.isLoading2 = true
        this.isLoading3 = true
        this.isLoading4 = true
        this.carParamInfo = {
          ...param,
        }
        try {
          let resBehavior = await postillegalAnalysisillegalAnalysisBehavior(
            this.carParamInfo
          )
          let resPlace = await postillegalAnalysisillegalAnalysisPlace(
            this.carParamInfo
          )
          let resCar = await postillegalAnalysisillegalAnalysisVehicle(
            this.carParamInfo
          )
          let resTime = await postillegalAnalysisillegalAnalysisTime(
            this.carParamInfo
          )

          let resCodeBehavior = await getalarmRulequeryRulesByAlarmCode({
            alarmCode: 'C03A04A01A01',
          })
          let resCodePlace = await getalarmRulequeryRulesByAlarmCode({
            alarmCode: 'C03A04A01A02',
          })
          let resCodeCar = await getalarmRulequeryRulesByAlarmCode({
            alarmCode: 'C03A04A01A03',
          })

          if (resCodeBehavior.status == 0 && resCodeBehavior.data) {
            this.BehaviorAlarmValue =
              Number(resCodeBehavior.data[0]?.alarmNum) || 0
          }
          if (resCodePlace.status == 0 && resCodePlace.data) {
            this.PlaceAlarmValue = Number(resCodePlace.data[0]?.alarmNum) || 0
          }
          if (resCodeCar.status == 0 && resCodeCar.data) {
            this.CarAlarmValue = Number(resCodeCar.data[0]?.alarmNum) || 0
          }
          if (resBehavior.status == 0 && resBehavior.data) {
            // this.BehaviorEchartData = resBehavior.data
            this.BehaviorEchartData = resBehavior.data.map(v => {
              return {
                name: v.wfxwmc,
                value: v.sl,
              }
            })
            this.render('behavior', this.BehaviorAlarmValue)
          }
          if (resPlace.status == 0 && resPlace.data) {
            this.placeEchartData = resPlace.data.map(v => {
              return {
                name: v.wfdz,
                value: v.sl,
              }
            })
            this.render('place', this.PlaceAlarmValue)
          }
          if (resCar.status == 0 && resCar.data) {
            this.carEchartData = resCar.data.map(v => {
              return {
                name: v.hphm,
                value: v.sl,
              }
            })
            this.render('car', this.CarAlarmValue)
          }
          if (resTime.status == 0 && resTime.data) {
            this.TimeEchartData = resTime.data.map(v => {
              return {
                name: v.name,
                value: v.num,
              }
            })
            this.render('time')
          }
          this.isLoading1 = false
          this.isLoading2 = false
          this.isLoading3 = false
          this.isLoading4 = false
        } catch (error) {
          this.isLoading1 = false
          this.isLoading2 = false
          this.isLoading3 = false
          this.isLoading4 = false
        }
      },
      render(str, threshold) {
        console.log(888)
        if (str === 'behavior') {
          this.showEmpty1 = this.BehaviorEchartData.length > 0 ? false : true
          if (this.BehaviorEchartData.length == 0) return
          this.Option1 = this.setOption(this.BehaviorEchartData, str, threshold)
        } else if (str === 'place') {
          this.showEmpty2 = this.placeEchartData.length > 0 ? false : true
          if (this.placeEchartData.length == 0) return
          this.Option2 = this.setOption(this.placeEchartData, str, threshold)
        } else if (str === 'car') {
          this.showEmpty3 = this.carEchartData.length > 0 ? false : true
          if (this.carEchartData.length == 0) return
          this.Option3 = this.setOption(this.carEchartData, str, threshold)
        } else if (str === 'time') {
          this.showEmpty4 = this.TimeEchartData.length > 0 ? false : true
          if (this.TimeEchartData.length == 0) return
          this.Option4 = this.setOption(this.TimeEchartData, str, threshold)
        }
      },
      setOption(data, str, threshold) {
        if (str === 'behavior' || str === 'place' || str === 'car') {
          let dataZoom = [
            {
              show: true,
              // 设置类型
              type: 'slider',
              // 设置背景颜色
              backgroundColor: 'transparent',
              // 设置选中范围的填充颜色
              fillerColor: '#64B1FF',
              // 设置边框颜色
              borderColor: 'transparent',
              // 是否显示detail,即拖拽时候显示详细数值信息
              showDetail: false,
              // 数据窗口范围的起始数值
              startValue: 0,
              // 数据窗口范围的结束数值(一页显示多少条数据)
              endValue: 9,
              // 控制哪个轴,如果是number表示控制一个轴,
              // 如果是Array表示控制多个轴。此处控制第二根轴
              xAxisIndex: [0],
              // empty:当前数据窗口外的数据,被设置为空。
              // 即不会影响其他轴的数据范围
              // filterMode: "empty",
              // 滚动条高度
              // width: 6,
              // 滚动条显示位置
              height: '3%',
              // 距离右边
              right: 20,
              // 如果top的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐
              bottom: 20,
              // left: "center",
              // 控制手柄的尺寸
              handleSize: 0,
              // 是否锁定选择区域(或叫做数据窗口)的大小
              zoomLoxk: true,
              // 组件离容器上侧的距离
              showDataShadow: false, //是否显示数据阴影 默认auto
              // showDetail: false, //即拖拽时候是否显示详细数值信息 默认true
              moveHandleSize: 0, //两侧滑块宽度
              handleStyle: {
                borderColor: '#cacaca',
                borderWidth: '5',
                shadowBlur: 2,
                background: '#ddd',
                shadowColor: '#ddd',
                borderRadius: 40,
              },
              // borderRadius: 40,
            },
            {
              // 没有下面这块的话,只能拖动滚动条,
              // 鼠标滚轮在区域内不能控制外部滚动条
              type: 'inside',
              // 控制哪个轴,如果是number表示控制一个轴,
              // 如果是Array表示控制多个轴。此处控制第二根轴
              xAxisIndex: [0],
              // 滚轮是否触发缩放
              zoomOnMouseWheel: false,
              // 鼠标移动能否触发平移
              moveOnMouseMove: true,
              // 鼠标滚轮能否触发平移
              moveOnMouseWheel: true,
              start: 0,
            },
          ]

          let option = {
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow',
              },
              enterable: true,
              confine: true,
              // position: point => {
              //   return [...point]
              // },
              borderColor: 'rgba(251, 249, 249, 0)',
              padding: 10,
              // formatter: p => {
              //   return `<span style="font-size:14px;color:#666;font-weight:400;margin-left:2px">${p[0].data}次</span>`
              // },
            },
            legend: {
              show: false,
            },
            grid: {
              left: '1%',
              right: '1%',
              bottom: '13%',
              top: '18%',
              containLabel: true,
            },
            xAxis: {
              type: 'category',

              axisTick: {
                show: false,
              },
              grid: {
                bottom: 0,
              },
              axisLine: {
                show: false,
              },
              splitLine: {
                show: false,
              },
              axisLabel: {
                //x轴字体颜色
                show: true, //是否显示刻度标签
                interval: '0', // 刻度标签的显示间隔,在x轴中有效.0显示所有
                inside: false, // 刻度标签是否朝内,默认朝外
                // rotate: 50, // 刻度标签旋转的角度,旋转的角度从-90度到90度
                width: 80,
                overflow: 'truncate',
                ellipsis: '...',
              },
              data: data.map(item => item.name),
            },
            yAxis: {
              type: 'value',
              position: 'left',
              axisLine: {
                show: false,
              },
              axisTick: {
                show: false,
              },
              axisLabel: {
                color: '#999',
              },
              splitLine: {
                show: false,
              },
            },
            dataZoom: [],
            series: [
              {
                name: 'Fake Data',
                type: 'line',
                showSymbol: false,
                data: [threshold],
                tooltip: {
                  show: false,
                },
                markLine: {
                  symbol: ['none', 'none'], // 去掉箭头
                  label: {
                    show: false,
                    position: 'start',
                    formatter: '{b}',
                  },
                  data: [
                    {
                      name: '阈值',
                      yAxis: threshold,
                    },
                  ],
                  lineStyle: {
                    type: 'dashed',
                    color: '#f82020',
                    width: 1,
                  },
                },
              },
              {
                name: '违法数量',
                type: 'bar',
                data: data.map(item => {
                  if (threshold && item.value > threshold) {
                    return {
                      value: item.value,
                      itemStyle: {
                        borderRadius: [9, 9, 0, 0],
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                          { offset: 0, color: '#FF8D64' },
                          { offset: 1, color: '#FE5E39' },
                        ]),
                      },
                    }
                  } else {
                    return {
                      value: item.value,
                      itemStyle: {
                        borderRadius: [9, 9, 0, 0],
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                          { offset: 0, color: '#64B1FF' },
                          { offset: 1, color: '#3986FE' },
                        ]),
                      },
                    }
                  }
                }),
                barWidth: 11,

                tooltip: {
                  valueFormatter: function (value) {
                    return value
                  },
                },
                // markLine: {
                //   symbol: ['none', 'none'],
                //   label: {
                //     show: false,
                //   },
                //   lineStyle: { color: '#FE5E39' },
                //   data: [
                //     {
                //       yAxis: threshold,
                //     },
                //   ],
                // },
              },
            ],
          }
          if (data.length > 10) {
            option.dataZoom = dataZoom
          } else {
            option.dataZoom = []
          }
          return option
        } else {
          let option2 = {
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow',
              },
              enterable: true,
              confine: true,
              position: point => {
                return [...point]
              },
              formatter: param => {
                let p = param[0]
                // let info = data.find(item => item.name == p.name)
                // let perNum = info.zb
                // let total = info.total
                // let clickPobj = {
                //   apiId: '3',
                //   data: {
                //     // wflx: this.mainRadio,
                //     name: p.name,
                //   },
                // }
                // let clickP = JSON.stringify(clickPobj).replace(/\"/g, "'") // eslint-disable-line
                // let perNum = ((p.value / total) * 100).toFixed(2)
                let str1 = `<span style="font-size:14px;color:#666;font-weight:400;margin-left:2px">${p.name}<span style="margin-left:20px;font-size:14px;font-weight:900;color:#409EFF;cursor:pointer">${p.value}</span>`

                return str1
              },
            },
            color: ['#0798FF'],
            grid: {
              left: '1%',
              right: '1%',
              bottom: '3%',
              top: '18%',
              containLabel: true,
            },
            xAxis: {
              type: 'category',
              data: data.map(item => item.name),
              axisTick: {
                show: false,
              },
              grid: {
                bottom: 0,
              },
              axisLine: {
                show: false,
              },
              splitLine: {
                show: false,
              },
              axisLabel: {
                //x轴字体颜色
                show: true, //是否显示刻度标签
                interval: '0', // 刻度标签的显示间隔,在x轴中有效.0显示所有
                inside: false, // 刻度标签是否朝内,默认朝外
                // rotate: 50, // 刻度标签旋转的角度,旋转的角度从-90度到90度
                width: 100,
                overflow: 'truncate',
                ellipsis: '...',
              },
            },
            yAxis: [
              {
                type: 'value',
                name: '起',
                position: 'left',
                axisLine: {
                  show: false,
                },
                axisTick: {
                  show: false,
                },
                axisLabel: {
                  color: '#999',
                },
                splitLine: {
                  show: false,
                },
              },
            ],
            series: [
              {
                name: '违法数量',
                type: 'line',
                showSymbol: false,
                data: data.map(item => item.value),
                smooth: true,
                areaStyle: {
                  color: {
                    type: 'linear',
                    x: 0,
                    y: 0,
                    x2: 0,
                    y2: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: 'rgba(7, 152, 255, 0.16)', // 0% 处的颜色
                      },
                      {
                        offset: 1,
                        color: 'rgba(0,131,255,0)', // 100% 处的颜色
                      },
                    ],
                    global: false, // 缺省为 false
                  },
                },
              },
            ],
          }
          return option2
        }
      },
    },
    mounted() {},
  }
</script>
<style lang="less" scoped>
  .chart_con {
    position: relative;
    width: 100%;
    height: 380px;
    padding: 16px 23px;
    margin-bottom: 13px;
    background: #fff;
    border-radius: 5px;
    box-shadow: 0 5px 20px 0 rgb(179 182 185 / 40%);
  }

  .module-title {
    display: flex;
    align-items: center;
    font-size: 16px;
    font-weight: bolder;
    line-height: 22px;
    color: #222b45;

    img {
      width: 24px;
      height: 24px;
      margin-right: 3px;
    }
  }

  .earlyWarning-container {
    width: 100%;
  }
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值