Vue(2) + Echarts realizes the drill-down function of the secondary map (the novice Xiaobai belt notes are super detailed)

The new requirements of the company's new project require that, for example, when you log in with a city-level account, the city-level map will be displayed, and the district-level (county-level) account will display the current district/county map, and the city-level account can be drilled down. Go to the districts and counties, click on the districts and counties to display the data of each district and county (the histogram displayed on the pop-up layer), click on the districts and counties to display the data of the districts and counties (the histogram)

The function to be realized has been finished, let me not talk nonsense, let me talk about how to achieve it

  • How to display a map with echarts

First of all, I declared a method named getMap () in methods ( )

html part:

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

js part

<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>

Guess you like

Origin blog.csdn.net/Guanchong333/article/details/128694793