react使用Echarts绘制高亮可点击选中的省市地图

  最近做项目遇到一个需求,需要显示广东省各个地级市的地图,并且鼠标移入高亮显示,鼠标点击可以选中某个地级市。在网上查阅了大量资料之后,最后选择了使用echarts实现该需求。在此记录一下,希望可以帮到有需求的小伙伴。本人初次使用,有不足之处希望大家可以指出,先看看效果图:

  

 

 

该需求主要有以下几个关键点:

  首先我们需要初始化一个地图坐标系,可以在网上下载一个地图的json文件。

  

import GDJson from '../../../../statics/cdn/guangdong.json';

echarts.registerMap('GD', GDJson);

  然后就是通过配置option绘制出具体的地图,此处我是通过绘制一个散点图,实现的各个地级市名字的显示,需要知道各个市的经纬度,这个可以在网上查到。然后通过dataRange设置了不同的value值所显示的颜色。具体配置如下所示:

  

var provienceData = [
      { name: '广州', type: 'areaCenterCity', value: 0, departId: '001021' },
      { name: '深圳', type: 'areaCenterCity', value: 0, departId: '001020' },
      { name: '佛山', type: 'areaCenterCity', value: 0, departId: '001004' },
      { name: '东莞', type: 'areaCenterCity', value: 0, departId: '001008' },
      { name: '中山', type: 'areaCenterCity', value: 0, departId: '001019' },
      { name: '珠海', type: 'areaCenterCity', value: 0, departId: '001011' },
      { name: '江门', type: 'areaCenterCity', value: 0, departId: '001015' },
      { name: '肇庆', type: 'areaCenterCity', value: 0, departId: '001005' },
      { name: '惠州', type: 'areaCenterCity', value: 0, departId: '001010' },
      { name: '汕头', type: 'areaCenterCity', value: 0, departId: '001007' },
      { name: '潮州', type: 'areaCenterCity', value: 0, departId: '001009' },
      { name: '揭阳', type: 'areaCenterCity', value: 0, departId: '001006' },
      { name: '汕尾', type: 'areaCenterCity', value: 0, departId: '001001' },
      { name: '湛江', type: 'areaCenterCity', value: 0, departId: '001018' },
      { name: '茂名', type: 'areaCenterCity', value: 0, departId: '001003' },
      { name: '阳江', type: 'areaCenterCity', value: 0, departId: '001016' },
      { name: '韶关', type: 'areaCenterCity', value: 0, departId: '001013' },
      { name: '清远', type: 'areaCenterCity', value: 0, departId: '001017' },
      { name: '云浮', type: 'areaCenterCity', value: 0, departId: '001002' },
      { name: '梅州', type: 'areaCenterCity', value: 0, departId: '001014' },
      { name: '河源', type: 'areaCenterCity', value: 0, departId: '001012' },
    ];
let option = {
      dataRange: {
        show: false,
        x: 'left',
        y: 'bottom',
        splitList: [
          { start: 0, end: 0, color: '#13667e' },//当值为5时,区域背景
          { start: 5, end: 5, color: '#187fed' },//当值为5时,区域背景
        ],
      },
      geo: {
        map: 'GD',
        roam: false,
        zoom: 0.94,
        tooltip: {
          show: false,       //不显示提示标签
        },
        center: [113.122717, 22.900762],
        label: {
          normal: {
            show: false,//显示省份标签
            textStyle: { color: "#333333" }//省份标签字体颜色
          },
          emphasis: {//对应的鼠标悬浮效果
            show: false,
            textStyle: { color: "#333333" }
          }
        },
        itemStyle: {
          normal: {
            borderWidth: 1,//区域边框宽度
            borderColor: '#ffffff',//区域边框颜色
            areaColor: "#fff",//区域颜色
            label: { show: false }
          },
          emphasis: {
            areaColor: "#187fed",
          }
        },
      },
      series: [
        {
          type: 'scatter',  //'line'(折线图) | 'bar'(柱状图) | 'scatter'(散点图) | 'k'(K线图)
          //'pie'(饼图) | 'radar'(雷达图) | 'chord'(和弦图) | 'force'(力导向布局图) | 'map'(地图)
          coordinateSystem: 'geo',
          data: this.convertData(provienceData),
          symbolSize: 10,
          symbolRotate: 40,
          geoIndex: 0,
          label: {
            normal: {
              formatter: '{b}',
              position: 'bottom',
              show: true,
              color: '#fff',
            },
            emphasis: {
              show: false
            }
          },
          tooltip: {
            show: false,       //不显示提示标签
            formatter: '{c}',      //提示标签格式
            backgroundColor: "#fff",//提示标签背景颜色
            borderColor: '#ccc',
            borderWidth: 5,
            textStyle: { color: "#ccc" } //提示标签字体颜色
          },
          itemStyle: {
            normal: {
              color: '#fff'
            }
          }
        },
        {
          type: 'map',
          mapType: 'GD',
          geoIndex: 0,
          roam: false,
          zoom: 0.94,
          center: [113.122717, 22.900762],
          tooltip: {
            show: false,       //不显示提示标签
          },
          label: {
            normal: {
              show: false    //显示省份标签
            },
            emphasis: {
              show: false,
            }
          },
          itemStyle: {
            //正常样式
            normal: {
              borderWidth: 1,      //区域边框宽度
              borderColor: '#ffffff',  //区域边框颜色
              areaColor: "#187fed",
            },
            //鼠标事件区块样式
            emphasis: {
              areaColor: "#187fed",
            }
          },
          data: provienceData
        }
      ],
    }
    myChart.setOption(option);
convertData(data) {
    const geoCoordMap = {
      '广州': [113.480637, 23.325178],
      '深圳': [114.085947, 22.597],
      '佛山': [113.022717, 23.028762],
      '东莞': [113.746262, 23.006237],
      '中山': [113.382391, 22.521113],
      '珠海': [113.353986, 22.124979],
      '江门': [112.594942, 22.290431],
      '肇庆': [112.072529, 23.651546],
      '惠州': [114.412599, 23.079404],
      '汕头': [116.708463, 23.37102],
      '潮州': [116.832301, 23.761701],
      '揭阳': [116.055733, 23.343778],
      '汕尾': [115.364238, 22.974485],
      '湛江': [110.064977, 21.274898],
      '茂名': [110.919229, 21.959751],
      '阳江': [111.805107, 22.009222],
      '韶关': [113.591544, 24.801322],
      '清远': [113.051227, 24.285022],
      '云浮': [112.044439, 22.929801],
      '梅州': [116.117582, 24.299112],
      '河源': [114.997802, 23.946266],
    }
    var res = [];
    for (var i = 0; i < data.length; i++) {
      var geoCoord = geoCoordMap[data[i].name];
      if (geoCoord) {
        res.push({
          name: data[i].name,
          value: geoCoord.concat(data[i].value),
          area: data[i].area,
          type: data[i].type,
        });
      }
    }
    return res;
  }

最后则是为地图添加点击事件,点击某个区域的时候,更改某个区域的value值,进而改变其颜色

myChart.on('click', function (params) {
      for (let i = 0; i < provienceData.length; i++) {
        provienceData[i].value = 0
        if (params.name === provienceData[i].name && _this.state.departName !== params.data.name) {
          provienceData[i].value = 5
        }
      }
     
     myChart.setOption(option);
});

最后来一波总体代码

import React from 'react'
import echarts from 'echarts';
import GDJson from '../../../../statics/cdn/guangdong.json';
componentDidMount() {
    this.initalECharts()
 }
// 初始化地图
  initalECharts() {
    if(!document.getElementById('map')){
      return
    }
    let _this = this
    var provienceData = [
      { name: '广州', type: 'areaCenterCity', value: 0, departId: '001021' },
      { name: '深圳', type: 'areaCenterCity', value: 0, departId: '001020' },
      { name: '佛山', type: 'areaCenterCity', value: 0, departId: '001004' },
      { name: '东莞', type: 'areaCenterCity', value: 0, departId: '001008' },
      { name: '中山', type: 'areaCenterCity', value: 0, departId: '001019' },
      { name: '珠海', type: 'areaCenterCity', value: 0, departId: '001011' },
      { name: '江门', type: 'areaCenterCity', value: 0, departId: '001015' },
      { name: '肇庆', type: 'areaCenterCity', value: 0, departId: '001005' },
      { name: '惠州', type: 'areaCenterCity', value: 0, departId: '001010' },
      { name: '汕头', type: 'areaCenterCity', value: 0, departId: '001007' },
      { name: '潮州', type: 'areaCenterCity', value: 0, departId: '001009' },
      { name: '揭阳', type: 'areaCenterCity', value: 0, departId: '001006' },
      { name: '汕尾', type: 'areaCenterCity', value: 0, departId: '001001' },
      { name: '湛江', type: 'areaCenterCity', value: 0, departId: '001018' },
      { name: '茂名', type: 'areaCenterCity', value: 0, departId: '001003' },
      { name: '阳江', type: 'areaCenterCity', value: 0, departId: '001016' },
      { name: '韶关', type: 'areaCenterCity', value: 0, departId: '001013' },
      { name: '清远', type: 'areaCenterCity', value: 0, departId: '001017' },
      { name: '云浮', type: 'areaCenterCity', value: 0, departId: '001002' },
      { name: '梅州', type: 'areaCenterCity', value: 0, departId: '001014' },
      { name: '河源', type: 'areaCenterCity', value: 0, departId: '001012' },
    ];
    echarts.registerMap('GD', GDJson);
    //初始化ECharts实例
    const myChart = echarts.init(document.getElementById('map'));
    let option = {
      dataRange: {
        show: false,
        x: 'left',
        y: 'bottom',
        splitList: [
          { start: 0, end: 0, color: '#13667e' },//当值为5时,区域背景
          { start: 5, end: 5, color: '#187fed' },//当值为5时,区域背景
        ],
      },
      geo: {
        map: 'GD',
        roam: false,
        zoom: 0.94,
        tooltip: {
          show: false,       //不显示提示标签
        },
        center: [113.122717, 22.900762],
        label: {
          normal: {
            show: false,//显示省份标签
            textStyle: { color: "#333333" }//省份标签字体颜色
          },
          emphasis: {//对应的鼠标悬浮效果
            show: false,
            textStyle: { color: "#333333" }
          }
        },
        itemStyle: {
          normal: {
            borderWidth: 1,//区域边框宽度
            borderColor: '#ffffff',//区域边框颜色
            areaColor: "#fff",//区域颜色
            label: { show: false }
          },
          emphasis: {
            areaColor: "#187fed",
          }
        },
      },
      series: [
        {
          type: 'scatter',  //'line'(折线图) | 'bar'(柱状图) | 'scatter'(散点图) | 'k'(K线图)
          //'pie'(饼图) | 'radar'(雷达图) | 'chord'(和弦图) | 'force'(力导向布局图) | 'map'(地图)
          coordinateSystem: 'geo',
          data: this.convertData(provienceData),
          symbolSize: 10,
          symbolRotate: 40,
          geoIndex: 0,
          label: {
            normal: {
              formatter: '{b}',
              position: 'bottom',
              show: true,
              color: '#fff',
            },
            emphasis: {
              show: false
            }
          },
          tooltip: {
            show: false,       //不显示提示标签
            formatter: '{c}',      //提示标签格式
            backgroundColor: "#fff",//提示标签背景颜色
            borderColor: '#ccc',
            borderWidth: 5,
            textStyle: { color: "#ccc" } //提示标签字体颜色
          },
          itemStyle: {
            normal: {
              color: '#fff'
            }
          }
        },
        {
          type: 'map',
          mapType: 'GD',
          geoIndex: 0,
          roam: false,
          zoom: 0.94,
          center: [113.122717, 22.900762],
          tooltip: {
            show: false,       //不显示提示标签
          },
          label: {
            normal: {
              show: false    //显示省份标签
            },
            emphasis: {
              show: false,
            }
          },
          itemStyle: {
            //正常样式
            normal: {
              borderWidth: 1,      //区域边框宽度
              borderColor: '#ffffff',  //区域边框颜色
              areaColor: "#187fed",
            },
            //鼠标事件区块样式
            emphasis: {
              areaColor: "#187fed",
            }
          },
          data: provienceData
        }
      ],
    }
    myChart.setOption(option);

    myChart.on('click', function (params) {
      for (let i = 0; i < provienceData.length; i++) {
        provienceData[i].value = 0
        if (params.name === provienceData[i].name && _this.state.departName !== params.data.name) {
          provienceData[i].value = 5
        }
      }
      if (_this.state.departName !== params.data.name) {
        _this.setState({ departName: params.data.name, departId: params.data.departId }, () => {
          _this.getData()
        })
      } else {
        _this.setState({ departName: '', departId: '' }, () => {
          _this.getData()
        })
      }
      myChart.setOption(option);
    });
    window.addEventListener('resize', () => {
      if (myChart && myChart.resize) {
        myChart.resize();
      }
    });

  }
  // 添加地图每个市的坐标
  convertData(data) {
    const geoCoordMap = {
      '广州': [113.480637, 23.325178],
      '深圳': [114.085947, 22.597],
      '佛山': [113.022717, 23.028762],
      '东莞': [113.746262, 23.006237],
      '中山': [113.382391, 22.521113],
      '珠海': [113.353986, 22.124979],
      '江门': [112.594942, 22.290431],
      '肇庆': [112.072529, 23.651546],
      '惠州': [114.412599, 23.079404],
      '汕头': [116.708463, 23.37102],
      '潮州': [116.832301, 23.761701],
      '揭阳': [116.055733, 23.343778],
      '汕尾': [115.364238, 22.974485],
      '湛江': [110.064977, 21.274898],
      '茂名': [110.919229, 21.959751],
      '阳江': [111.805107, 22.009222],
      '韶关': [113.591544, 24.801322],
      '清远': [113.051227, 24.285022],
      '云浮': [112.044439, 22.929801],
      '梅州': [116.117582, 24.299112],
      '河源': [114.997802, 23.946266],
    }
    var res = [];
    for (var i = 0; i < data.length; i++) {
      var geoCoord = geoCoordMap[data[i].name];
      if (geoCoord) {
        res.push({
          name: data[i].name,
          value: geoCoord.concat(data[i].value),
          area: data[i].area,
          type: data[i].type,
        });
      }
    }
    return res;
  }
render(){
  return(<div className={styles.map} id="map"></div>)
}

 

posted @ 2020-05-29 10:36  monkeySoft  阅读(2570)  评论(0编辑  收藏  举报