home > webfront > ECMAS > js >

echarts矢量地圖自定義圖標數據展示—echarts地圖圖表三種方案

author:[email protected]    hits:

地圖數據展示,最先開始是想用百度地圖,自定義覆蓋物的形式展現,但是無法要做到區域選擇高亮,還是比較麻煩。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地圖圖表三種方案》, 請注明出處:http://www.qsexmk.tw/html/webfront/ECMAScript/js/2016_0219_7633.html