• home > webfront > ECMAS > javascript >

    echarts矢量地图自定义图标数据展示—echarts地图图表三种方案

    Author:zhoulujun@live.cn Date:

    地图数据展示,最先开始是想用百度地图,自定义覆盖物的形式展现,但是无法要做到区域选择高亮,还是比较麻烦。echarts可以实现矢量地图,

    地图数据展示,最先开始是想用百度地图,自定义覆盖物的形式展现,但是无法要做到区域选择高亮,还是比较麻烦。echarts可以实现矢量地图,地图图表并配上大数据。但是,需要把数据自定义形式覆盖到 地图上去。地图的formatter需要手工定义。

    echarts地图图表三种方案

    第一种方案,直接用地图图表形式展现

    import echarts from 'echarts'
    import shenZhenArea from 'shenZhen-area' //区域gis数据,区域 properties 属性里面没有cp 属性(lable),自动计算,可有手动补上。
    import shenZhenBorder from 'shenZhen-border.json'边界gis数据,方便实现自定义外边框
    //地图展示数据
    let mapData2ShowValue = [
      {"name": "光明区", "value": [2121, 1800]},
      {"name": "南山区", "value": [2121, 1800]},
      {"name": "盐田区", "value": [2121, 1800]},
      {"name": "罗湖区", "value": [2121, 1800]},
      {"name": "福田区", "value": [2121, 1800]},
      {"name": "大鹏新区", "value": [2121, 1800]},
      {"name": "龙岗区", "value": [2121, 1800]},
      {"name": "坪山区", "value": [2121, 1800]},
      {"name": "宝安区", "value": [2121, 1800]},
      {"name": "龙华区", "value": [2121, 1800]}]
    echarts.registerMap('shenZhenBorder', shenZhenBorder)
    echarts.registerMap('shenZhenArea', shenZhenArea)
    let chart1 = echarts.init(document.getElementById('map1'))
    chart1.setOption({
      geo: {
        type: 'map',
        map: 'shenZhenBorder',
        itemStyle: {
          areaColor: '#f0f',
          borderColor: '0ff', //省市边界线
          borderWidth: 4,
        },
        label: {
          show: false,
        },
        emphasis: {
          itemStyle: {
            areaColor: "rgba(0,193,255,0)",
          },
        }
      },
      series: [
        {
          name: 'name4',
          type: 'map',
          mapType: 'shenZhenArea',
          data: mapData2ShowValue,
          // nameMap: nameMap,//label 用了 formatter ,所以需要注释
          selectedMode: 'false', //是否允许选中多个区域
          itemStyle: {
            areaColor: "rgba(0,51,100,.4)",
            borderColor: "rgba(0,150,236,1)",
          },
          label: {
            show: true,
            width: 110,
            height: 110,
            align: 'left',
            position: [0, 0],
            backgroundColor: {
              image: require('../../../public/maps/map-icon2.png'),
              width: 110,
              height: 110
            },
            formatter: function (val) {
              // console.log('_______-formatter')
              // console.log(val)
              let str= '{a|' + (nameMap&&nameMap[val.name]||val.name) + '}' + '\n'
                + '{hr|}\n'
              // + '{num|' + val.data.value[0] + '}\n'
              // + '{num|' + val.data.value[1] + '}'
              //可能有多个数值
              let numArr=val.data.value.map(num=>{
                return '{num|' + num + '}'
              })
              str+=numArr.join('\n')
              return str;
            },
            rich: {
              a: {
                color: '#000',
                fontSize: 14,
                padding: [0, 0, 15, 10],
                align: 'left',
              },
              hr: {
                width: 110,
                height: 30,
              },
              num: {
                padding: [8, 0, 0, 35],
                color: '#fff',
                fontSize: 14,
              }
    
            },
          },
          emphasis: {
            itemStyle: {
              areaColor: "rgba(0,193,255,.6)",
            },
    
          },
        },
    
      ]
    })

    如果需要改动标注点的位置,需要改变cp坐标

     //设置区域 标注地点,默认echarts自动计算
    shenZhenArea.features.forEach((area, index) => {
      area.properties['cp'] = scatterData[index].value.slice(0,2)
    })
    //地图名字区域实际名字 和 自定义地区的名称映射
    let nameMap = {}
    mapData2ShowValue.forEach((item, index) => {
      nameMap[item.name]=scatterData[index].name
    })

    第二方案,通过散点,添加上去

    import echarts from 'echarts'
    import shenZhenArea from 'shenZhen-area' 
    import shenZhenBorder from 'shenZhen-border.json'边界gis数据,方便实现自定义外边框
    echarts.registerMap('shenZhenBorder', shenZhenBorder)
    echarts.registerMap('shenZhenArea', shenZhenArea)
    let chart2 = echarts.init(document.getElementById('map2'))
    //散点 添加标注到地图 series   data 数据
    let scatterData = [
      {
        "name": "光明",
        "value": [113.92635602317334, 22.77565238823337, 2121, 1800]
      },
      {
        "name": "南山",
        "value": [113.90793997084684, 22.49941161039266, 2121, 1800]
      },
      {
        "name": "盐田",
        "value": [114.26956427107639, 22.59860716243546, 2121, 1800]
      },
      {
        "name": "罗湖",
        "value": [114.14902283766655, 22.56721616495356, 2121, 1800]
      },
      {
        "name": "福田",
        "value": [114.04857164315834, 22.547125926565144, 2121, 1800]
      },
      {
        "name": "大鹏",
        "value": [114.48218596611878, 22.607396641730393, 2121, 1800]
      },
      {
        "name": "龙岗",
        "value": [114.25617077847531, 22.73296063165799, 2121, 1800]
      },
      {
        "name": "坪山",
        "value": [114.35829615955865, 22.677712476089848, 2121, 1800]
      },
      {
        "name": "宝安",
        "value": [113.85938856016787, 22.64632147860795, 2121, 1800]
      },
      {
        "name": "龙华",
        "value": [114.04187489685779, 22.7116147533703, 2121, 1800]
      }];
    chart2.setOption({
      geo: {
        map: 'shenZhenBorder',
        itemStyle: {
          areaColor: "rgba(0,139,255,0)",
          borderColor: "rgba(0,150,236,1)", //省市边界线
          borderWidth: 4,
        },
        emphasis: {
          itemStyle: {
            areaColor: "rgba(0,193,255,0)",
          },
        }
      },
      series: [
        {
          tooltip: {
            show: false,
          },
          type: 'map',
          map: 'shenZhenArea',
          itemStyle: {
            areaColor: "rgba(0,51,100,.4)",
            borderColor: "rgba(0,150,236,1)",
          },
          label: {
            show: false,
          },
          emphasis: {
            itemStyle: {
              areaColor: "rgba(0,193,255,.6)",
            },
            label: {
              show: false,
            },
    
          }
        },
        {
          name: 'ShowData',
          type: 'scatter',
          coordinateSystem: 'geo',
          // symbol:'none',
          symbol: `image://${require('../../../public/maps/map-icon2.png')}`,
          symbolSize: [110, 110],
          encode: {
            value: 2
          },
    
          label: {
            show: true,
            width: 110,
            height: 110,
            align: 'left',
            position: [0, 0],
            formatter: function (val) {
              // console.log('_______-formatter')
              // console.log(val)
              let str= '{a|' + (nameMap&&nameMap[val.name]||val.name) + '}' + '\n'
                + '{hr|}\n'
              // + '{num|' + val.data.value[0] + '}\n'
              // + '{num|' + val.data.value[1] + '}'
              //可能有多个数值
              let temArr=val.data.value.slice(2)
              let numArr=temArr.map(num=>{
                return '{num|' + num + '}'
              })
              str+=numArr.join('\n')
              return str;
            },
            rich: {
              a: {
                color: '#000',
                fontSize: 14,
                padding: [0, 0, 15, 10],
                align: 'left',
              },
              hr: {
                width: 110,
                height: 30,
              },
              num: {
                padding: [8, 0, 0, 60],
                color: '#fff',
                fontSize: 14,
              },
              num2: {
                fontSize: 14,
              }
            }, //富文本样式,就是上面的formatter中'{a|'和'{b|'
    
          },
          /*label: {
            show: true,
            position: ['0', '15%'],
            formatter: function(val) {
              // console.log('val')
             /!* let dom=
                ''+
                  ''+
                    ''+val.name+''+
                  ''+
                  ''+
                    ''+val.data.value[2]+''+
                    ''+val.data.value[3]+''+
                  ''+
                ''
              return dom;*!/
              // console.log(val)
              return  '{name|' + val.name + '}' + '\n'
                +'{hr|}\n'
    
                + '{yellow|}{b|' + val.data.value[2] +'}\n'
                + '{blue|}{b|' + val.data.value[3]+ '}';
            }, //让series 中的文字进行换行
            rich: {
              name: {
                color: '#000',
                fontSize: 14,
              },
              hr:{
                width:80,
                height:30
              },
              yellow:{
                verticalAlign:'middle',
                offset:[-30,0],
                width:8,
                height:8,
                backgroundColor:'#fff22a',
                borderRadius:8,
              },
              blue:{
                verticalAlign:'middle',
                // offset:[30,0],
                width:8,
                height:8,
                backgroundColor:'#2813ff',
                borderRadius:8,
              },
              abg: {
                backgroundColor: '#033',
                width: '100%',
                align: 'right',
                height: 25,
                padding:[0,10],
                borderRadius: [4, 4, 0, 0]
              },
              b: {
                color: '#fff',
                fontFamily: 'Microsoft YaHei',
                fontSize: 14,
                width: '100%',
                height: 24,
                padding:[0,10],
                backgroundColor: 'rgba(4,4,4,0.5)',
                borderRadius: 4,
                // borderWidth: 1,
                // borderColor: '#f00',
                textAlign: 'center',
              }
            }, //富文本样式,就是上面的formatter中'{a|'和'{b|'
    
    
    
          },*/
          itemStyle: {
            normal: {
              color: '#f4e925',
              shadowBlur: 10,
              shadowColor: '#333'
            }
          },
          data: scatterData,
        }
    
      ]
    })

    第三种方案,通过获取标注点的经纬度转像素坐标,绝对定位dom到地图上,通过css 鼠标事件穿透,pointer-events: none。等等手段达到目的

    import echarts from 'echarts'
    import shenZhenArea from 'shenZhen-area' 
    import shenZhenBorder from 'shenZhen-border.json'
    echarts.registerMap('shenZhenBorder', shenZhenBorder)
    echarts.registerMap('shenZhenArea', shenZhenArea)
    let chart3 = echarts.init(document.getElementById('map3'))
    let scatterData = [
      {
        "name": "光明",
        "value": [113.92635602317334, 22.77565238823337, 2121, 1800]
      },
      {
        "name": "南山",
        "value": [113.90793997084684, 22.49941161039266, 2121, 1800]
      },
      {
        "name": "盐田",
        "value": [114.26956427107639, 22.59860716243546, 2121, 1800]
      },
      {
        "name": "罗湖",
        "value": [114.14902283766655, 22.56721616495356, 2121, 1800]
      },
      {
        "name": "福田",
        "value": [114.04857164315834, 22.547125926565144, 2121, 1800]
      },
      {
        "name": "大鹏",
        "value": [114.48218596611878, 22.607396641730393, 2121, 1800]
      },
      {
        "name": "龙岗",
        "value": [114.25617077847531, 22.73296063165799, 2121, 1800]
      },
      {
        "name": "坪山",
        "value": [114.35829615955865, 22.677712476089848, 2121, 1800]
      },
      {
        "name": "宝安",
        "value": [113.85938856016787, 22.64632147860795, 2121, 1800]
      },
      {
        "name": "龙华",
        "value": [114.04187489685779, 22.7116147533703, 2121, 1800]
      }];
      chart3.setOption({
      geo: {
        map: 'shenZhenBorder',
        itemStyle: {
          areaColor: "rgba(0,139,255,0)",
          borderColor: "rgba(0,150,236,1)", //省市边界线
          borderWidth: 4,
        },
        emphasis: {
          itemStyle: {
            areaColor: "rgba(0,193,255,0)",
          },
    
        }
      },
      series: [
        {
          tooltip: {
            show: false,
          },
          type: 'map',
          map: 'shenZhenArea',
          itemStyle: {
            areaColor: "rgba(0,51,100,.4)",
            borderColor: "rgba(0,150,236,1)",
          },
          label: {
            show: false,
          },
          // data:shenZhenArea.features.map((area)=>{
          //   return  area.properties.name
          // }),
          emphasis: {
            itemStyle: {
              areaColor: "rgba(0,193,255,.6)",
            },
            label: {
              show: false,
            },
    
          }
        },
      ]
    })
    let chartBox3 = this.$refs.chartBox3
    setMapMark(chartBox3)
    
    function setMapMark(box) {
      let domList = scatterData.map((item) => {
        let arrPx = chart3.convertToPixel('geo', item.value.slice(0, 2))
        let temArr=item.value.slice(2)
        // console.log(arrPx)
        let dom = `
                  ${item.name}                ${temArr.map((num)=>{
          //可能有多个数值
          return `
                                      ${num}                    `
        }).join('')}
                      `
        return dom
      })
      box.innerHTML = domList.join('')
    }

    dom样式

    .map-item-show {
      z-index: 99999;
      position: absolute;
      width: 109px;
      height: 110px;
      font-size: 14px;
      background: url('../../../public/maps/map-icon.png') no-repeat;
      background-size: 44px 100px;
      line-height: 1;
      pointer-events: none;
    }
    
    .map-name-box {
      color: #000;
      padding: 14px 8px;
    }
    .map-data-box {
      width: 56px;
      background: rgba(0, 0, 0, .4);
      border-radius: 4px;
      color: #fff;
      padding :2px 8px;
      margin :10px 0 0 30px;
      >div{
        line-height :18px;
        display :flex;
        justify-content :start;
        align-items :center;
      }
      .map-data-icon{
        width :8px;
        height :8px;
        background :#2813ff;
        border-radius :100%;
        margin-right :6px;
      }
      .icon-yellow{
        background #fff22a;
      }
    
    }

    三面三种方案都可以实现各有优劣,第一实现最简单,第二种实现map 于散点复合图表,可以做出效果更佳

    第三种dom实现,免得写坑爹的formatter(rich没有css3来的顺手)

    搞完也累了,给个美女,看看



    转载本站文章《echarts矢量地图自定义图标数据展示—echarts地图图表三种方案》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/js/2016_0219_7633.html