☼ 注:笔者的文章是根据自己当前项目做的笔记,具体应用请参照自己实际项目情况
1、渲染地图的方法
import echarts from 'echarts/lib/echarts'
import { province } from './province'
import { cityMap } from '@/assets/citys/city-code'
/**
* 渲染地图
* @param {} mapBox echarts初始化容器
* @param {Array} mapData 散点数据
* @param {String} map 地图名称,用于显示全国,省份或城市地图
* @param {Number} zoom 地图放大倍数
*/
renderMap = (mapBox, mapData, map = 'china', zoom = 1.1) => {
let option = ({
geo: {
map,
zoom,
roam: true,
itemStyle: {
color: '#3EFFFE',
opacity: 1,
borderWidth: .4,
borderColor: '#000',
},
label: {
show: false,
textStyle: {
color: '#fff', //地图初始化区域字体颜色
fontSize: '60%',
opacity: 1,
backgroundColor: 'rgba(0,23,11,0)'
},
},
emphasis: { //当鼠标放上去 地区区域是否显示名称
label: {
show: true,
textStyle: {
color: '#000',
fontSize: '70%',
backgroundColor: 'rgba(0,23,11,0)'
}
}
}
},
tooltip: {
trigger: 'item',
formatter: data => {
if (typeof (data.value) == 'object') {
const { name, area, building, house, owner, occupancyRate, device, online, offline, status } = data.data
return `<p><span>${name}</span><p>
<p class="panel"><span>面积:${area}</span><span>楼栋数:${building}</span><span>房屋数:${house}</span></p>
<p class="panel"><span>业主数量:${owner}</span><span>入住率:${occupancyRate}</span><span>设备总数:${device}</span></p>
<p class="panel"><span>在线设备数:${online}</span><span>离线设备数:${offline}</span><span>总体运行状态:${status}</span></p>`
}
}
},
series: [
{
name: '项目',
type: 'effectScatter',
coordinateSystem: 'geo',
// symbol: 'pin',
showEffectOn: 'render',
// rippleEffect: {
// brushType: 'stroke'
// },
hoverAnimation: true,
// symbolSize: function (val) {
// return val[2] / 200
// },
symbolSize: 10,
opacity: 1,
label: {
show: false,
formatter: '{b}'
},
itemStyle: {
normal: {
color: '#ddb926',
borderWidth: 1,
borderColor: '#fff',
}
},
data: this.convertData(mapData),
zlevel: 1
},
{
name: '项目',
type: 'map',
geoIndex: 0,
// mapType: 'china',
// zoom: 1.1,
// roam: false,
itemStyle: {
normal: {
label: {
show: false,
textStyle: {
color: '#fff', //地图初始化区域字体颜色
fontSize: '90%',
opacity: 1,
backgroundColor: 'rgba(0,23,11,0)'
},
},
areaColor: '#276b75',
borderWidth: .4,
borderColor: '#000',
},
emphasis: {
label: {
show: true,
textStyle: {
color: '#000',
fontSize: '60%',
backgroundColor: 'rgba(0,23,11,0)'
}
}
}
}
}
]
})
mapBox.setOption(option, true)
}
/**
* 处理地图上散点数据的方法
* @param {Array} data 原散点数据
*/
convertData = data => {
let res = []
for (let i = 0; i < data.length; i++) {
let geoCoord = this.state.geoCoordMap[data[i].name]
if (geoCoord) {
res.push({
...data[i],
value: geoCoord.concat(data[i].area)
})
}
}
return res
}
2、地图数据
// 散点数据
mapData: {
'深圳市': [
{ name: 'aaa', area: 16969, building: 11, house: 301, owner: 903, occupancyRate: '90%', device: 1123, online: 977, offline: 146, status: '正常' },
{ name: 'bbb', area: 13000, building: 5, house: 160, owner: 480, occupancyRate: '95%', device: 513, online: 446, offline: 67, status: '正常' },
{ name: 'ccc', area: 11502, building: 3, house: 474, owner: 1422, occupancyRate: '96%', device: 369, online: 321, offline: 48, status: '正常' },
{ name: 'ddd', area: 10347, building: 1, house: 442, owner: 1326, occupancyRate: '93%', device: 246, online: 214, offline: 32, status: '正常' },
{ name: 'eee', area: 18987, building: 5, house: 569, owner: 1707, occupancyRate: '86%', device: 556, online: 483, offline: 73, status: '正常' }
],
'东莞市': [
{ name: 'fff', area: 143508, building: 96, house: 6432, owner: 19296, occupancyRate: '88%', device: 9644, online: 8390, offline: 1254, status: '正常' },
],
'北京': [
{ name: 'ggg', area: 11465, building: 3, house: 407, owner: 1221, occupancyRate: '91%', device: 378, online: 328, offline: 50, status: '正常' },
{ name: 'hhh', area: 12853.87, building: 4, house: 647, owner: 1941, occupancyRate: '93%', device: 498, online: 433, offline: 65, status: '正常' }
],
'长春市': [
{ name: 'iii', area: 173068, building: 79, house: 761, owner: 2283, occupancyRate: '93%', device: 7911, online: 6882, offline: 1029, status: '正常' },
{ name: 'jjj', area: 28793, building: 31, house: 1578, owner: 4734, occupancyRate: '89%', device: 3112, online: 2707, offline: 405, status: '正常' },
{ name: 'kkk', area: 16415, building: 1, house: 811, owner: 2433, occupancyRate: '89%', device: 241, online: 209, offline: 32, status: '正常' },
{ name: 'xxx', area: 207711, building: 35, house: 3840, owner: 11520, occupancyRate: '94%', device: 3523, online: 3065, offline: 458, status: '正常' },
{ name: 'yyy', area: 36110, building: 3, house: 669, owner: 2007, occupancyRate: '90%', device: 398, online: 346, offline: 52, status: '正常' }
]
},
// 散点在地图上的经纬度
geoCoordMap: {
'aaa': [114.063793, 22.519725],
'bbb': [114.057559, 22.523336],
'ccc': [113.98418, 22.545543],
'ddd': [114.128104, 22.547884],
'eee': [114.21198, 22.726553],
'fff': [113.910017, 22.772971],
'ggg': [116.682622, 40.296563],
'hhh': [116.682582, 40.28984],
'iii': [125.440426, 43.770484],
'jjj': [125.27213, 43.802139],
'kkk': [125.244618, 43.806959],
'xxx': [125.243071, 43.797708],
'yyy': [125.246228, 43.80221]
}
3、province.js(用来映射地名和json文件名)
export const province = {
'安徽': 'anhui',
'澳门': 'aomen',
'北京': 'beijing',
'重庆': 'chongqing',
'福建': 'fujian',
'甘肃': 'gansu',
'广东': 'guangdong',
'广西': 'guangxi',
'贵州': 'guizhou',
'海南': 'hainan',
'河北': 'hebei',
'黑龙江': 'heilongjiang',
'河南': 'henan',
'湖北': 'hubei',
'湖南': 'hunan',
'江苏': 'jiangsu',
'江西': 'jiangxi',
'吉林': 'jilin',
'辽宁': 'liaoning',
'内蒙古': 'neimenggu',
'宁夏': 'ningxia',
'青海': 'qinghai',
'山东': 'shandong',
'上海': 'shanghai',
'山西': 'shanxi',
'陕西': 'shanxi1',
'四川': 'sichuan',
'台湾': 'taiwan',
'天津': 'tianjin',
'香港': 'xianggang',
'新疆': 'xinjiang',
'西藏': 'xizang',
'云南': 'yunnan',
'浙江': 'zhejiang'
}
4、地图初始化
this.myMapInstance = echarts.init(this.myMap)
this.myMapData = []
Object.values(this.state.mapData).map(item => item.map(o => this.myMapData.push(o)))
this.renderMap(this.myMapInstance, this.myMapData)
5、地图点击事件
this.myMapInstance.on('click', param => {
if (param.componentSubType === 'effectScatter') {
// 点击散点的相关交互处理
} else {
// 省份
if (province[param.name]) {
// 记录当前展示的是哪个等级的地图(全国,省份,城市),用于逐级返回
this.level = 'province'
// 记录当前展示的省份名称
this.provName = param.name
this.provCode = province[param.name]
// 依赖包里的province文件夹下的json数据
import(`echarts/map/js/province/${this.provCode}`).then(() => {
// 获取当前省份散点数据的方法
this.getMapDataWithPro(param.name)
this.renderMap(this.myMapInstance, this.myMapData, param.name, 0.8)
})
// 城市
} else if (cityMap[param.name]) {
this.level = 'city'
this.cityCode = cityMap[param.name]
this.myMapData = this.state.mapData[param.name] || []
// 城市json数据下载链接在文章最后
import(`@/assets/citys/${this.cityCode}`).then(data => {
echarts.registerMap(param.name, data.default)
this.renderMap(this.myMapInstance, this.myMapData, param.name, 0.8)
})
}
}
})
// 点击地图空白处逐级返回上一级地图
this.myMapInstance.getZr().on('click', param => {
if (!param.target) {
switch (this.level) {
case 'province':
this.level = 'china'
Object.values(this.state.mapData).map(item => item.map(o => this.myMapData.push(o)))
this.renderMap(this.myMapInstance, this.myMapData)
break
case 'city':
this.level = 'province'
// 获取当前省份散点数据的方法
this.getMapDataWithPro(this.provName)
this.renderMap(this.myMapInstance, this.myMapData, this.provName, 0.8)
break
default:
break
}
}
})
6、tooltip自动轮播的方法
autoShowTip = () => {
this.index = 0
this.timer = setInterval(() => {
this.myMapInstance.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: this.index
})
this.index ++
if (this.index > this.myMapData.length-1) {
this.index = 0
}
}, 2000)
}
7、tooltip轮播的事件处理
this.autoShowTip()
// 鼠标移入暂停轮播
this.myMapInstance.on('mouseover', () => {
clearInterval(this.timer)
this.timer = null
})
// 鼠标移入开启轮播
this.myMapInstance.on('mouseout', () => {
if (this.timer) return
this.autoShowTip()
})