• 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": [21211800]},
      {"name""南山区""value": [21211800]},
      {"name""盐田区""value": [21211800]},
      {"name""罗湖区""value": [21211800]},
      {"name""福田区""value": [21211800]},
      {"name""大鹏新区""value": [21211800]},
      {"name""龙岗区""value": [21211800]},
      {"name""坪山区""value": [21211800]},
      {"name""宝安区""value": [21211800]},
      {"name""龙华区""value": [21211800]}]
    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', //省市边界线
          borderWidth4,
        },
        label: {
          showfalse,
        },
        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: {
            showtrue,
            width110,
            height110,
            align'left',
            position: [00],
            backgroundColor: {
              imagerequire('../../../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: [001510],
                align: 'left',
              },
              hr: {
                width: 110,
                height: 30,
              },
              num: {
                padding: [80035],
                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.9263560231733422.7756523882333721211800]
      },
      {
        "name""南山",
        "value": [113.9079399708468422.4994116103926621211800]
      },
      {
        "name""盐田",
        "value": [114.2695642710763922.5986071624354621211800]
      },
      {
        "name""罗湖",
        "value": [114.1490228376665522.5672161649535621211800]
      },
      {
        "name""福田",
        "value": [114.0485716431583422.54712592656514421211800]
      },
      {
        "name""大鹏",
        "value": [114.4821859661187822.60739664173039321211800]
      },
      {
        "name""龙岗",
        "value": [114.2561707784753122.7329606316579921211800]
      },
      {
        "name""坪山",
        "value": [114.3582961595586522.67771247608984821211800]
      },
      {
        "name""宝安",
        "value": [113.8593885601678722.6463214786079521211800]
      },
      {
        "name""龙华",
        "value": [114.0418748968577922.711614753370321211800]
      }];
      chart3.setOption({
      geo: {
        map'shenZhenBorder',
        itemStyle: {
          areaColor"rgba(0,139,255,0)",
          borderColor"rgba(0,150,236,1)"//省市边界线
          borderWidth4,
        },
        emphasis: {
          itemStyle: {
            areaColor"rgba(0,193,255,0)",
          },
    
        }
      },
      series: [
        {
          tooltip: {
            showfalse,
          },
          type'map',
          map'shenZhenArea',
          itemStyle: {
            areaColor"rgba(0,51,100,.4)",
            borderColor"rgba(0,150,236,1)",
          },
          label: {
            showfalse,
          },
          // data:shenZhenArea.features.map((area)=>{
          //   return  area.properties.name
          // }),
          emphasis: {
            itemStyle: {
              areaColor"rgba(0,193,255,.6)",
            },
            label: {
              showfalse,
            },
    
          }
        },
      ]
    })
    let chartBox3 = this.$refs.chartBox3
    setMapMark(chartBox3)
    
    function setMapMark(box) {
      let domList = scatterData.map((item) => {
        let arrPx = chart3.convertToPixel('geo', item.value.slice(02))
        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-index99999;
      position: absolute;
      width109px;
      height110px;
      font-size14px;
      backgroundurl('../../../public/maps/map-icon.png') no-repeat;
      background-size44px 100px;
      line-height1;
      pointer-events: none;
    }
    
    .map-name-box {
      color#000;
      padding14px 8px;
    }
    .map-data-box {
      width56px;
      backgroundrgba(000, .4);
      border-radius4px;
      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

    TOP