最近做项目遇到一个需求,需要显示广东省各个地级市的地图,并且鼠标移入高亮显示,鼠标点击可以选中某个地级市。在网上查阅了大量资料之后,最后选择了使用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>)
}