Bootstrap

【Echarts】中国地图、堆叠图、横向柱状图

封装一个监听窗口变化,自适应图像大小的混入对象

混入对象:一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

chart_resize.js文件:

export default {
	methods: {
		// 对echart元素尺寸进行监听,当发生变化时同步更新echart视图
		chartEleResizeListener() {
			const chartInstance = ResizeListener({
				strategy: 'scroll',
				callOnAdd: true
			})
			chartInstance.listenTo(this.$el, () => {
		        if (!this.chart) return
		        this.chart.resize()
		    })
		},
		// 当窗口缩放时,echart动态调整自身大小
		windowResizeListener() {
			if(!this.chart) return
			this.chart.resize()
		}
	},
	mounted() {
		window.addEventListener('resize', this.windowResizeListener)
		this.chartEleResizeListener()
	},
	beforeDestroy() {   // 组件销毁时取消监听
		window.removeEventListener('resize', this.windowResizeListener)
	}
}

中国地图

<template>
  <div ref="chart"/>
</template>
<script>
import chartResize from '../components/chart_resize'  //引入混入对象
export default {
  name: 'ChinaChart',
  mixins: [chartResize],   //使用自适应混入对象
  data() {
    return {
      chart: null,
    }
  },
  mounted() {
    this.setOptions()
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    setOptions() {
      const chartDom = this.$refs.chart
      this.chart = this.$echarts.init(chartDom)
      const option = {
        height: '100%',
        width: '70%',
        visualMap: {
          min: 0,
          max: 100,
          top: 'bottom',
          seriesIndex: 1,
          text: ['高', '低'],
          inRange: {
            color: ['#CCDDFF', '#ADD8E6', '#BBFFEE', '#FFF0F5 ', '#F0E68C']
          },
          show: false
        },
        grid: {
          top: 0,
          bottom: 0,
          containLabel: true
        },
        tooltip: {
          trigger: 'item'
        },
        geo: {
          show: true,
          map: 'china',
          label: {
            offset: [50, 10],
            normal: {
              show: true,
              fontSize: '12',
              color: 'rgba(0,0,0,0.7)'
            },
            emphasis: {
              color: '#000000',
              fontSize: 14,
              show: true
            }
          },
          roam: 'scale',
          scaleLimit: {
            min: 1,
            max: 15
          },
          zoom: 1,
          itemStyle: {
            normal: {
              areaColor: '#FFF',
              borderColor: '#27af6b'
            },
            emphasis: {
              areaColor: '#FFFF77'
            }
          }
        },
        series: [{
          name: '标记点',
          type: 'scatter',
          coordinateSystem: 'geo',
          data: this.dataCenter.datas,
          symbol: 'circle',
          symbolSize: 12,
          label: {
            normal: {
              show: false
            },
            emphasis: {
              show: false
            }
          },
          itemStyle: {
            normal: {
              color: function(params) {
                if (params.data.dataStatus === 'health') {
                  return 'green'
                } else if (params.data.dataStatus === 'bad') {
                  return 'red'
                }
              }
            },
            emphasis: {
              color: '#f00'
            }
          },
          tooltip: {
            padding: 0,
            enterable: true,
            transitionDuration: 1,
            textStyle: {
              color: '#000',
              decoration: 'none'
            },
            backgroundColor: 'white',
            formatter: param => {
              return `<div style="${'padding: 10px;'}">
                        <span style="margin-right: 25px;">${param.data.dataCenter}</span>
                        <span>${param.data.city}</span>
                        <p style="line-height: 30px; margin: 0;">状态:${param.data.dataStatus}</p>
                      </div>`
            }
          }
        },
        {
          name: '省份',
          type: 'map',
          geoIndex: 0,
          data: this.chinaProvince.datas,
          tooltip: {
            padding: 0,
            enterable: true,
            transitionDuration: 1,
            textStyle: {
              color: '#000',
              decoration: 'none'
            },
            backgroundColor: 'white',
            formatter: param => {
              const spanStyle = 'display: block;'
              return `<div style="${'padding: 10px;'}">
                          <p style="${'font-size: 16px; font-weight: 600; line-height: 30px; margin: 0;'}">${param.name}</p>
                          <span style="${spanStyle}">总数:${param.data.alarm.total}</span>
                          <span style="${spanStyle}">紧急:${param.data.alarm.emergency}</span>
                          <span style="${spanStyle}">严重:${param.data.alarm.important}</span>
                          <span style="${spanStyle}">轻微:${param.data.alarm.slight}</span>
                      </div>`
            }
          }
        }]
      }
      this.chart.setOption(option)
      // this.$nextTick(() => {
      //   this.chart.resize()
      // })
    }
  }
}
</script>

堆叠图

<template>
  <div ref="chart" />
</template>
<script>
import chartResize from '../components/chart_resize'
export default {
  name: 'ChinaChart',
  mixins: [chartResize],
  data() {
    return {
      chart: null,
    }
  },
  created() {
    this.setOptions()
  },

  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    setOptions() {
      const chartDom = this.$refs.chart
      this.chart = this.$echarts.init(chartDom)
      var option = {
        color: ['#238353', '#27af6b', '#c7e9d8'],
        grid: {
          top: '10%',
          bottom: '10%',
          left: '3%',
          right: '3%'
        },
        xAxis: {
          type: 'category',
          data: this.allProvince,
          axisTick: {
            show: false
          },
          axisLine: {
            show: false
          },
          splitLine: {
            show: false
          }
        },
        yAxis: {
          type: 'value',
          axisTick: {
            show: false
          },
          axisLine: {
            show: false
          },
          splitLine: {
            show: false
          },
          axisLabel: {
            show: false
          }
        },
        series: [
          {
            name: '紧急',
            type: 'bar',
            barWidth: 20,
            stack: 'Ad',
            emphasis: {
              focus: 'series'
            },
            data: this.emergency
          },
          {
            name: '重要',
            type: 'bar',
            stack: 'Ad',
            emphasis: {
              focus: 'series'
            },
            data: this.important
          },
          {
            name: '轻微',
            type: 'bar',
            stack: 'Ad',
            emphasis: {
              focus: 'series'
            },
            data: this.slight
          },
          {
            name: '总计',
            type: 'bar',
            stack: '',
            label: {
              normal: {
                show: true,
                position: 'top',
                color: '#000'
              }
            },
            z: -1,
            barGap: '-100%',
            data: this.total,
            itemStyle: {
              normal: {
                color: 'rgba(128, 128, 128, 0)'
              }
            }
          }
        ]

      }
      this.chart.setOption(option)
    },
  }
}
</script>

横向柱状图(添加背景色效果)

<template>
  <div ref="bar_chart" :style="{ height: height, width:width}" />
</template>
<script>
import chartResize from './chart_resize'
export default {
  name: 'BarChart',
  mixins: [chartResize],
  data() {
    return {
      chart: null
    }
  },
  mounted() {
	  this.setOptions()
  },

  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    setOptions() {
      this.chart = this.$echarts.init(this.$refs.bar_chart)
      const option = Object.assign(
        {
          grid: {
            top: 0,
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
          },
          xAxis: {
            type: 'value',
            axisTick: {
              show: false
            },
            axisLine: {
              show: false
            },
            splitLine: {
              show: false
            },
            axisLabel: {
              show: false
            }
          },
          yAxis: {
            type: 'category',
            data: xAxisData,
            axisTick: {
              show: false
            },
            axisLine: {
              show: false
            },
            axisLabel: {
              align: 'right',
              margin: 50
            }
          },
          series: [
            {
              type: 'bar',
              emphasis: {
                focus: 'series'
              },
              barWidth: 7,
              data: series.data,
              itemStyle: {
                normal: {
                  barBorderRadius: 30,
                  color: function(param) {
                  	const colorList = ['#6d0909e0', '#6d0909e0', '#6d0909e0']
                    return colorList[param.dataIndex]
                  }
                }
              },
              label: {
                show: true,
                position: [660, 0],   //将柱状图的label文字标记到柱状图最后面
                formatter(params) {
                  const { value } = params
                  return `${value}`
                },
                color: '#000'
              },
              zlevel: 1,
              // barGap: '-90%',
              // barCategoryGap: '-90%',
              showBackground: true,
              fontSize: '12px',
              backgroundStyle: {
                color: 'rgba(110, 193, 244, 0.2)'
              }
            },
            {
              name: '背景',   //添加背景颜色
              type: 'bar',
              barWidth: 7,
              barGap: '-100%',
              data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
              itemStyle: {
                normal: {
                  color: 'rgba(0,0,0,0.05)',
                  barBorderRadius: 30
                }
              }
            }
          ]
        },
        this.options
      )
      this.chart.setOption(option)
      this.$nextTick(() => {
        this.chart.resize()
      })
    }
  }
}
</script
;