美文网首页
前端vue下使用echarts显示中国地图的坑

前端vue下使用echarts显示中国地图的坑

作者: 青岛大桥_Android到后端 | 来源:发表于2021-04-07 20:22 被阅读0次

先説需求:要想把设备在全国的分布在地图上画出来,以zoom in/out鼠标缩放

相信很多网友都在找china.js 劝你别找了。
那个不能鼠标缩放,

现在我以在jeecg-boot项目(前端vue)来实验的,

  1. 先看效果

数据点造了2个:
[{"name":"合肥","value":[120.99,36.99]},{"name":"大庆","value":[120.01,36.01]}]
(地名随便起的,勿对号入座)

  1. 去百度地图开发者平台去申请一个key

现在开发者平台统一了,无论是APP,还是WEB,都是在一个地方申请。
去里面建一个应用,它会给你生成一个key

  1. 声明引用百度地图

jeecg-boot有框架,在建一个map.js中我们添加如下代码

export function loadBMap(ak) {
    return new Promise(function(resolve, reject) {
        if (typeof BMap !== 'undefined') {
            resolve(BMap)
            return true
        }
        window.onBMapCallback = function() {
            resolve(BMap)
        }
        let script = document.createElement('script')
        script.type = 'text/javascript'
        script.src =
            'http://api.map.baidu.com/api?v=2.0&ak='+ ak +'&__ec_v__=20190126&callback=onBMapCallback'
        script.onerror = reject
        document.head.appendChild(script)
    })
}
  1. 业务模块vue

代码如下,注意几点
1)刚一进界面,可以延时再调入数据及刷新地图
具体招数: .nextTick() 或 setTimeout()
2)动态刷新数据方法
没找到什么好方法,只以重新init,重新加载option
为了避免提示重复创建对象,用
if (this.chart != null && this.chart != '' && this.chart != undefined) {
this.chart.dispose()
}
判断一下

<template>
  <div class="mapContent">
    <div id="china_map" :style="{ width: '1280px', height: '800px' }"></div>
  </div>
</template>

<script>
//import axios from 'axios'
//import { axios } from '@/utils/request'
import { getDeviceList } from '@/api/manage'
import { loadBMap } from './map.js'

let echarts = require('echarts')
// 如果是 webpack 打包,也可以 require 引入
//require('echarts');
require('echarts/extension/bmap/bmap')
var that

export default {
  name: 'CnMapScatter',
  components: {},
  data() {
    return {
      deviceDataPoints: [], 
      chart: null,
      geoCoordMap: {
        青岛: [120.33, 36.07],
        日照: [119.46, 35.42],
        胶南: [119.97, 35.88],
      },
    }
  },
  mounted() {
    //vue的生命周期函数
    that = this
    this.$nextTick(() => {
      loadBMap('在百度申请的appkey我得保密').then(() => {
        //this.drawPie()
        this.initEcharts() //调用初始化图表的函数

        setTimeout(() => {
          window.console.log('下面准备调入设备点')
          this.loadDevicesDataPoints()
        }, 2000)
      })
    })
  },
  computed: {},
  methods: {
    initEcharts() {
      var data = [
        { name: '青岛', value: 18 },
        { name: '日照', value: 21 },
        { name: '胶南', value: 22 },
      ]

      const option = {
        backgroundColor: 'transparent',
        title: {
          text: '设备地图分布',
          // subtext: 'data from PM25.in',
          // sublink: 'http://www.pm25.in',
          left: 'center',
          textStyle: {
            color: '#fff',
          },
        },
        tooltip: {
          trigger: 'item',
        },
        bmap: {
          center: [129.114129, 31.550339],
          zoom: 5,
          roam: true,
          mapStyle: {
            styleJson: [
              {
                featureType: 'water',
                elementType: 'all',
                stylers: {
                  color: '#044161',
                },
              },
              {
                featureType: 'land',
                elementType: 'all',
                stylers: {
                  color: '#004981',
                },
              },
              {
                featureType: 'boundary',
                elementType: 'geometry',
                stylers: {
                  color: '#064f85',
                },
              },
              {
                featureType: 'railway',
                elementType: 'all',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'highway',
                elementType: 'geometry',
                stylers: {
                  color: '#004981',
                },
              },
              {
                featureType: 'highway',
                elementType: 'geometry.fill',
                stylers: {
                  color: '#005b96',
                  lightness: 1,
                },
              },
              {
                featureType: 'highway',
                elementType: 'labels',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'arterial',
                elementType: 'geometry',
                stylers: {
                  color: '#004981',
                },
              },
              {
                featureType: 'arterial',
                elementType: 'geometry.fill',
                stylers: {
                  color: '#00508b',
                },
              },
              {
                featureType: 'poi',
                elementType: 'all',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'green',
                elementType: 'all',
                stylers: {
                  color: '#056197',
                  visibility: 'off',
                },
              },
              {
                featureType: 'subway',
                elementType: 'all',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'manmade',
                elementType: 'all',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'local',
                elementType: 'all',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'arterial',
                elementType: 'labels',
                stylers: {
                  visibility: 'off',
                },
              },
              {
                featureType: 'boundary',
                elementType: 'geometry.fill',
                stylers: {
                  color: '#029fd4',
                },
              },
              {
                featureType: 'building',
                elementType: 'all',
                stylers: {
                  color: '#1a5787',
                },
              },
              {
                featureType: 'label',
                elementType: 'all',
                stylers: {
                  visibility: 'off',
                },
              },
            ],
          },
        },
        series: [
          // {
          //   name: 'pm2.5',
          //   type: 'scatter',
          //   coordinateSystem: 'bmap',
          //   data: that.convertData(data),
          //   encode: {
          //     value: 2,
          //   },
          //   symbolSize: function (val) {
          //     return val[2] / 10
          //   },
          //   label: {
          //     formatter: '{b}',
          //     position: 'right',
          //   },
          //   itemStyle: {
          //     color: '#ddb926',
          //   },
          //   emphasis: {
          //     label: {
          //       show: true,
          //     },
          //   },
          // },
          /*
          {
            name: 'Top 5',
            type: 'effectScatter',
            coordinateSystem: 'bmap',
            data: that.convertData(
              data
                .sort(function (a, b) {
                  return b.value - a.value
                })
                .slice(0, 6)
            ),
            encode: {
              value: 2,
            },
            symbolSize: function (val) {
              return val[2] / 10
            },
            showEffectOn: 'emphasis',
            rippleEffect: {
              brushType: 'stroke',
            },
            hoverAnimation: true,
            label: {
              formatter: '{b}',
              position: 'right',
              show: true,
            },
            itemStyle: {
              color: '#f4e925',
              shadowBlur: 10,
              shadowColor: '#333',
            },
            zlevel: 1,
          },
          */
          {
            name: 'Device',
            type: 'scatter',
            coordinateSystem: 'bmap',
            data: this.deviceDataPoints,
            encode: {
              value: 2,
            },
            symbolSize: function (val) {
              return val[2] / 10
            },
            label: {
              formatter: '{b}',
              position: 'right',
            },
            itemStyle: {
              color: '#00ff00',
            },
            emphasis: {
              label: {
                show: true,
              },
            },
          },
          /*
          {
            type: 'custom',
            coordinateSystem: 'bmap',
            renderItem: that.renderItem,
            itemStyle: {
              opacity: 0.5,
            },
            animation: false,
            silent: true,
            data: [0],
            z: -10,
          },
          */
        ],
      }

      if (this.chart != null && this.chart != '' && this.chart != undefined) {
        this.chart.dispose()
      }
      that.chart = echarts.init(document.getElementById('china_map'))
      that.chart.setOption(option)
    },

    convertData(data) {
      var res = []
      for (var i = 0; i < data.length; i++) {
        var geoCoord = this.geoCoordMap[data[i].name]
        console.log('geoCoord=', JSON.stringify(geoCoord))
        if (geoCoord) {
          res.push({
            name: data[i].name,
            value: geoCoord.concat(data[i].value),
          })
        }
      }
      console.log('calc res=', JSON.stringify(res))
      return res
    },

    loadDevicesDataPoints() {
      console.log('正在调入设备点...')
      this.deviceDataPoints = []
      getDeviceList()
        .then((res) => {
          console.log('调入设备点...返回结果')
          console.log('/roaddev/tdev/list response:', res)
          //var res2 = []
          res.result.records.map((item) => {
            var loc = []
            loc.push(item['devLng'])
            loc.push(item['devLat'])
            console.log('loc=', JSON.stringify(loc))
            if (loc) {
              this.deviceDataPoints.push({
                name: item.devSn,
                value: loc.concat(parseInt('100'))
              })
            }
          })
          console.log('deviceDataPoints =', JSON.stringify(this.deviceDataPoints))
          this.initEcharts()
          //return this.deviceDataPoints
        })
        .catch((error) => {
          // catch 指请求出错的处理
          console.log('调入设备点...出错')
          console.log(error)
          //return null
        })
    },

    /*
    renderItem(params, api) {
      var coords = [
        [116.7, 39.53],
        [103.73, 36.03],
        [112.91, 27.87],
        [120.65, 28.01],
        [119.57, 39.95],
      ]
      var points = []
      for (var i = 0; i < coords.length; i++) {
        points.push(api.coord(coords[i]))
      }
      var color = api.visual('color')

      return {
        type: 'polygon',
        shape: {
          points: echarts.graphic.clipPointsByRect(points, {
            x: params.coordSys.x,
            y: params.coordSys.y,
            width: params.coordSys.width,
            height: params.coordSys.height,
          }),
        },
        style: api.style({
          fill: color,
          stroke: echarts.color.lift(color),
        }),
      }
    },
    */
  },
}
</script>
 
<style lang="less" scoped>
.mapContent {
  width: 100%;
  height: 100%;
  .echarts {
    width: 100%;
    height: 100%;
  }

  /deep/ .showTool {
    width: 160px;
    height: auto;
    padding: 10px 0 10px 10px;
    box-sizing: border-box;
    background: rgba(255, 255, 255, 0.9);
    // box-shadow: 0px 2px 8px 0px rgba(13, 4, 8, 0.2);
    border-radius: 5px;
    .title {
      font-size: 14px;
      font-family: Microsoft YaHei;
      font-weight: bold;
      color: #333333;
      line-height: 22px;
    }
    .rate {
      font-size: 12px;
      font-family: Microsoft YaHei;
      font-weight: bold;
      color: #333333;
      line-height: 22px;
    }
  }
}
</style>

结束。点个赞再走呗。感谢啦。

相关文章

网友评论

      本文标题:前端vue下使用echarts显示中国地图的坑

      本文链接:https://www.haomeiwen.com/subject/cqxpkltx.html