Vue(2) + Echarts 实现二级地图下钻功能(新手小白 带注释 超详细)

公司的新项目提的新需求, 要求比如说用市级账号登录时显示的是市级的地图,区级(县级)登录的号显示的是当前区县的地图, 市级账号可以下钻到区县里, 点开区县显示每个区县的数据(弹出层显示的柱状图), 区县点击显示的是区县的数据(柱状图)

要实现什么功能已经讲完了, 废话不多说, 我来说一下怎么实现

  • 如何用echarts显示地图

首先我是在methods() 中声明了一个方法 名叫 getMap()

html 部分:

<template>
  <div id="cMap" class="subPages">
    <div id="cMap_map"></div>
    // 下面是区县点击时的弹窗
    <transition name="bounce">
      <cmapStreet v-show="cmapStreetData.visible"></cmapStreet>
    </transition>
  </div>
</template>

js 部分

<script>
import * as echarts from 'echarts'
import cmapStreet from '@/components/dataVisualization/cmap-street' // 单个街道的分类档案个数
import busEvevt from '../../assets/busEvevt' // 引入js  兄弟传值的文件

export default {
  name: 'cMap',
  components: { cmapStreet },
  data () {
    return {
      mapAreaId: '',
      area: '',
      mapData: [],
      // 地图通用配置
      tooltip: {
        formatter: '{b}:{c}册',
        textStyle: {
          fontSize: 20
        }
      },
      countAll: {
        renshi: 0,
        wenshu: 0,
        yewu: 0
      },
      quzhi: {},
      cmapStreetData: {
        visible: 0,
        streetId: 0,
        streetName: '',
        streetCategorys: []
      }
    }
  },
  async created () {
    this.totalFn()
    let res = await this.$get('/archiveuser/areagroup')
    if (res.code === 200) {
      // 全福 洪家楼 山大路 东风
      this.mapData = res.data
      this.labelLineize(this.mapData, '历下区', [-190, 0])
    }
    // 后端返回的数据保存在本地比如: (jinan)
    const area = sessionStorage.getItem('getJsonFile')
    // 每次初始化页面时 都会先从本地取出后端返回的数据, 来对地图进行渲染
    this.getMap(area, this.mapData)
  },
  mounted () {
    // 所有地区的文件都需要引入到文件夹下 
    const mapDict = {
      商河县: 'shanghexian',
      济阳区: 'jiyangqu',
      天桥区: 'tianqiaoqu',
      历城区: 'lichengqu',
      历下区: 'lixiaqu',
      章丘区: 'zhangqiuqu',
      槐荫区: 'huaimengqu',
      市中区: 'shizhongqu',
      长清区: 'changqingqu',
      平阴县: 'pingyinxian',
      莱芜区: 'laiwuqu',
      钢城区: 'gangchengqu',
      济南市: 'jinan'
    }
    let _this = this
    var cMap = echarts.init(document.getElementById('cMap_map'))
    // 注册点击事件
    cMap.on('click', function (params) {
      // 这个为了获取被点击省份的json文件名
      let area = mapDict[params.name]
      // 转换格式 JSON数据
      let mapDictList = JSON.stringify(mapDict)
      // 市级  遍历查询是否有该数据 如果有就开始下钻
      if (mapDictList.includes(area)) {
        // 获取相应的code = areaId
        let mapAreaId = params.data.code
        _this.mapAreaId = mapAreaId
        // 获取下钻时的数据 进行渲染
        _this.$get(`/archiveuser/areagroup?areaId=${mapAreaId}`).then(function (mapList) {
          // 传值给兄弟组件 (传值是为了给父组件 然后台知道用户点击的是哪一个地区 然后根据id 来获取真实的数据 然后渲染到echarts 图表中 因为我在这里封装了echarts组件 渲染的话是在父组件进行渲染的)
          busEvevt.$emit('mapAreaId', mapAreaId)
          _this.amountFn(mapAreaId)
          // 里面的数据进行定位
             _this.labelLineize(this.mapData, '历下区', [-190, 0])
          // 调用地图方法 进行渲染
          _this.getMap(area, mapList.data)
        })
        // 把被点击的json文件名传递后拼接在请求路径中
        cMap.on('click', function (params) {
          _this.$children[0].draw(params.data)
          _this.cmapStreetData.visible = 1
        })
        // 区县
      } else if (mapDictList.indexOf(area) === -1) {
        // 区县直接打开弹窗
        _this.$children[0].draw(params.data)
        // visible == 1 是打开弹窗
        _this.cmapStreetData.visible = 1
      }
    })
  },
  methods: {
    getMap (area, mapData) {
      this.axios.get(`./static/${area}.json`).then((geoJson) => {
        echarts.registerMap('cMap_map', geoJson.data)
        // 初始化echarts实例
        var cMap = echarts.init(document.getElementById('cMap_map'))
        // 绘制图表
        cMap.setOption({
          tooltip: this.tooltip,
          visualMap: {
            show: false,
            min: this.getMin(),
            max: this.getMax(),
            realtime: false,
            calculable: true,
            inRange: {
              color: ['#1E62AC', '#2E98CA', '#24CFF4']
            }
          },
          series: [{
            name: 'cMap_map',
            map: 'cMap_map',
            type: 'map',
            label: { // 地图标签
              color: '#fff',
              show: true,
              position: 'top',
              distance: 10,
              fontSize: 20
            },
            itemStyle: { // 街道、镇的图块样式
              borderColor: '#2ED1E4',
              borderWidth: '1',
              shadowBlur: 15,
              shadowColor: '#3a73c0',
              shadowOffsetX: 10,
              shadowOffsetY: 15
            },
            emphasis: {
              itemStyle: { // 指向时高亮
                areaColor: '#8dd7fc',
                color: '#8dd7fc',
                borderWidth: '3px'
              }
            },
            select: {
              disabled: true
            },
            data: mapData // 数据集
          }]
        })
      })
    },
    getMin () {
      var min = 0
      this.mapData.forEach((e) => {
        if (Number(e.value) < min) {
          min = e.value
        }
      })
      return min
    },
    getMax () {
      let max = 0
      this.mapData.forEach((e) => {
        if (Number(e.value) > max) {
          max = e.value
        }
      })
      return max
    },
    // 定位到该区域 实现地位
    labelLineize (array, name, offset) {
      for (var i = 0; i < array.length; i++) {
        if ((array[i].name).indexOf(name) > -1) {
          array[i].label = {
            offset: offset,
            backgroundColor: 'rgba(255, 255, 255, .3)',
            borderRadius: 5,
            padding: 10
          }
          array[i].labelLine = {
            show: true,
            lineStyle: {
              color: '#fff'
            },
            length2: 20,
            width: 3
          }
          array[i].emphasis = {
            label: {
              color: '#000',
              backgroundColor: '#8dd7fc'
            }
          }
        }
      }
    }
  }
}
</script>

猜你喜欢

转载自blog.csdn.net/Guanchong333/article/details/128694793