这篇文章会介绍「 H5 + 原生 JS」和「 封装 React 组件」中两种实现方式。
「 H5 + 原生 JS」
参考文章(1)中的代码已经实现了展示全国地图和点击省市自治区下钻的功能,但是每个区域的颜色是一样的。于是又结合了 参考文章(2)。效果图:
---- 源码地址
参考文章:
HTML5 Canvas实现中国地图 可展开地级市子地图
echarts实现中国地图数据展示
绘制 geoJSON 地址: http://geojson.io/
封装 React 组件
绘制地图调用的 echarts.registerMap(geoJSON) 这一方法,geoJSON 的具体实现请移步至 echarts搞定各种地图(想怎么画就怎么画)。
1. 封装 geoJSON 数据,结构大致如下:
{
"anhui": {
"type": "FeatureCollection",
"features": [
{
"id": "340100",
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
"[NGHEDAHAPCFMPGTCFULUNGFELKJGDG@ECKMIGIBE@....."
],
"encodeOffsets": [[119842, 32007]]
},
"properties": {
"cp": [117.283042, 31.86119],
"name": "合肥市",
"childNum": 1
}
},
{"id": ........},
]
}
2. 创建引入 geoJSON 文件的中间文件:
import {anhui} from './province/anhui';
import {aomen} from './province/aomen';
import {beijing} from './province/beijing';
// etc.
export default [
{
anhui,
aomen,
beijing,
// etc.
},
];
3. 封装 Map 文件
import React, {Component} from 'react';
import echarts from 'echarts';
import styles from './Map.less';
import * as mapdata from './ProvinceData';
import {china} from './MapData/China';
import * as province from './MapData/province.js';
class CMap extends Component {
componentDidMount() {
this.setState({
province,
});
china(echarts);
this.initEcharts('china', '中国');
}
// 初始化echarts
initEcharts(pName, Chinese_) {
var myChart = echarts.init(document.getElementById('china-map'));
var oBack = document.getElementById('back');
var option = {
title: {
text: Chinese_ || pName,
left: 'center',
},
tooltip: {
trigger: 'item',
formatter: '{b}
{c}',
},
//左侧小导航图标
visualMap: {
show: true,
x: 'left',
y: 'top',
splitList: this.props.splitList,
color: ['#3D74CC', '#5A8EE0', '#6FA4F7', '#80B1FF', '#99C0FF', '#B3D0FF'],
},
series: [
{
name: Chinese_ || pName,
type: 'map',
mapType: pName,
roam: false, //是否开启鼠标缩放和平移漫游
data: this.props.mapData,
top: '3%', //组件距离容器的距离
zoom: 1.1,
selectedMode: 'single',
label: {
normal: {
show: true, //显示省份标签
textStyle: {color: '#585858', fontSize: 12}, //省份标签字体颜色
},
emphasis: {
//对应的鼠标悬浮效果
show: true,
textStyle: {color: '#aaa'},
},
},
itemStyle: {
normal: {
borderWidth: 0.5, //区域边框宽度
borderColor: '#A6E1FF', //区域边框颜色
areaColor: '#fff', //区域颜色
},
emphasis: {
borderWidth: 0.5,
borderColor: '#FFD1A3',
areaColor: '#FFDAA6',
},
},
},
],
};
myChart.setOption(option);
myChart.off('click');
let _this = this;
if (pName === 'china') {
// 全国时,添加click 进入省级
myChart.on('click', function(param) {
for (var i = 0; i < mapdata.provincesText.length; i++) {
if (param.name === mapdata.provincesText[i]) {
//显示对应省份的方法
const pName = mapdata.provinces[i];
echarts.registerMap(mapdata.provincesText[i], _this.state.province.default[0][pName]);
_this.initEcharts(mapdata.provincesText[i]);
break;
}
}
if (param.componentType === 'series') {
var provinceName = param.name;
}
});
} else {
// 省份,添加双击 回退到全国
myChart.on('dblclick', function() {
_this.initEcharts('china', '中国');
});
}
}
render() {
return (
);
}
}
export default CMap;
4. ProvinceData 数据:
export var provinces = [
"shanghai",
"hebei",
// etc.
];
export var provincesText = [
"上海",
"河北",
"山西",
// etc.
];
export var seriesData = [
{ name: "北京", value: "100" },
{ name: "天津", value: randomData() },
{ name: "上海", value: randomData() },
{ name: "重庆", value: randomData() },
// 其他城市数据.....
}];
function randomData() {
return Math.round(Math.random() * 500);
}
5. 引用组件
import CMap from './Map.js';
;
2020 更新升级版:
Vue 组件封装
其实 React 封装也是同理的,之前的版本是简易封装,看着就 low,这一版更新了比较多:
1. 准备 GEOJSON 数据
地图的 JSON 数据可以在这里下载
json-data/map
2. 准备 seriesData 数据
export const seriesData = [
{ name: '北京', value: '100' },
// ...
]
export const provincesdata = [
{ name: '朝阳市', value: randomData() },
//...
}
function randomData() {
return Math.round(Math.random() * 500)
}
完整代码请参考:json-data/map/emap.js
3. 封装组件
// component/Map.vue
返回全国
获取 mapPath 的完整代码请参考 js/util.js
// util.js
export const mapPath = {
中国: {
key: 'china',
name: '中国',
filePath: 'china',
registered: false
},
//...
}
4. 引用组件
// pages/Map.vue