地图的基础部分
使用echarts开发中国地图,并修改地图默认颜色,以及hover效果以及背景色
可以放大缩小
以此文章记录
首先安装echarts
npm install echarts
并引入import * as echarts from 'echarts'
然后去下载中国地图的 json数据
import * as echarts from 'echarts'
import china from '@/assets/geo-json/china.json'
/**
获取对应的json地图数据,然后向echarts注册该区域的地图,最后加载地图信息
@params {String} mapData:json数据的地址
@params {String} name: 地图名称
*/
const loadMap = (mapData, name) => {
if (mapData) {
echarts.registerMap(name, mapData)
const option = {
tooltip: {
show: true,
backgroundColor: 'rgba(13, 77, 61, 0.7)',
textStyle: {
color: '#FFF', // 文字的颜色
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: '12', // 文字字体大小
},
borderColor: 'rgba(13, 77, 61, 0.7)',
enterable: true, // 鼠标可进入浮层内
extraCssText: 'box-shadow: none',
padding: 10,
formatter: (params) => {
const res = `<div style="width:156px;height:120px;display: flex;flex-direction: column;">
<h3 style="margin: 5px 10px"> ${params?.name}</h3>
<div style="display:flex;flex-direction: column;flex: 1;justify-content: space-evenly;">
<div> <span style="margin: 0px 10px">使用单位:</span>2156家</div>
<div> <span style="margin: 0px 10px">在用电梯:</span>18万台</div>
<div> <span style="margin: 0px 10px">待检测电梯:</span>1526台</div>
<div> <span style="margin: 0px 10px">待检验电梯:</span>1409台</div>
</div>
</div>
`
return res
},
},
series: [
{
name: 'MAP',
type: 'map',
geoIndex: 0,
roam: true, // 是否可缩放
zoom: 1.1,
mapType: name,
selectedMode: 'false', // 是否允许选中多个区域
itemStyle: { // 这里是默认颜色
normal: {
show: true,
areaColor: '#C2F2E6',
borderColor: 'rgb(185, 220, 227)',
borderWidth: '1',
},
},
label: {
normal: {
show: true,
fontSize: 10,
},
},
emphasis: { // 这里是hover上去时的效果
show: true,
label: {
color: 'rgba(255,255,255,1)',
},
itemStyle: {
areaColor: '#16A984',
},
},
data: [{
name: '北京',
value: 2256
}, {
name: '天津',
value: 744
}, {
name: '上海',
value: 578
}, {
name: '重庆',
value: 806
}, {
name: '河北',
value: 432
}, {
name: '河南',
value: 590
}, {
name: '云南',
value: 132
}, {
name: '辽宁',
value: 487
}, {
name: '黑龙江',
value: 336
}, {
name: '湖南',
value: 295
}, {
name: '安徽',
value: 398
}, {
name: '山东',
value: 1055
}, {
name: '新疆',
value: 201
}, {
name: '江苏',
value: 795
}, {
name: '浙江',
value: 655
}, {
name: '江西',
value: 311
}, {
name: '湖北',
value: 993
}, {
name: '广西',
value: 261
}, {
name: '甘肃',
value: 349
}, {
name: '山西',
value: 273
}, {
name: '内蒙古',
value: 343
}, {
name: '陕西',
value: 319
}, {
name: '吉林',
value: 325
}, {
name: '福建',
value: 317
}, {
name: '贵州',
value: 275
}, {
name: '广东',
value: 1000
}, {
name: '青海',
value: 97
}, {
name: '西藏',
value: 18
}, {
name: '四川',
value: 601
}, {
name: '宁夏',
value: 126
}, {
name: '海南',
value: 186
}, {
name: '台湾',
value: 0
}, {
name: '香港',
value: 11
}, {
name: '澳门',
value: 0
}]
}],
}
const myChart = echarts.init(chartRef.value)
myChart.setOption(option, true)
} else {
Message.warning('无法加载该地图')
}
}
onMounted(() => {
loadMap(china, 'china') // 初始化全国地图
})
在地图上进行标记
在地图上进行标记 ,就要使用到
geo
的配置
加上了geo
那么series
下面的配置就可以删除了,前提是你得配置geoIndex: 0
,这个相当于HTML元素里面的index层级
itemStyle: {
normal: {
show: true,
areaColor: '#C2F2E6',
borderColor: 'rgb(185, 220, 227)',
borderWidth: '1',
},
},
label: {
normal: {
show: true,
fontSize: 10,
},
},
emphasis: {
show: true,
label: {
color: 'rgba(255,255,255,1)',
},
itemStyle: {
areaColor: '#16A984',
},
},
下面是完成代码,可以直接运行
import * as echarts from 'echarts'
import china from '@/assets/geo-json/china.json'
const data = [{
name: '320000',
value: 320000,
}, {
name: '578',
value: 578,
}, {
name: '744',
value: 744,
}, {
name: '806',
value: 806,
}, {
name: '336',
value: 336,
}, {
name: '325',
value: 325,
}, {
name: '487',
value: 487,
}, {
name: '343',
value: 343,
}, {
name: '432',
value: 432,
}, {
name: '273',
value: 273,
}, {
name: '1055',
value: 1055,
}, {
name: '590',
value: 590,
}, {
name: '319',
value: 319,
}, {
name: '349',
value: 349,
}, {
name: '126',
value: 126,
}, {
name: '97',
value: 97,
}, {
name: '201',
value: 201,
}, {
name: '398',
value: 398,
}, {
name: '795',
value: 795,
}, {
name: '655',
value: 655,
}, {
name: '295',
value: 295,
}, {
name: '311',
value: 311,
}, {
name: '993',
value: 993,
}, {
name: '601',
value: 601,
}, {
name: '275',
value: 275,
}, {
name: '317',
value: 317,
}, {
name: '1000',
value: 1000,
}, {
name: '186',
value: 186,
}, {
name: '261',
value: 261,
}, {
name: '132',
value: 132,
}, {
name: '18',
value: 18,
}, {
name: '11',
value: 11,
}]
const geoCoordMap = {
320000: [116.46, 39.92],
578: [121.29, 31.14],
744: [117.2, 39.13],
806: [106.32, 29.32],
336: [126.41, 45.45],
325: [125.19, 43.52],
487: [123.24, 41.50],
343: [111.48, 40.49],
432: [114.28, 38.02],
273: [112.34, 37.52],
1055: [117, 36.38],
590: [113.42, 34.48],
319: [108.54, 34.16],
349: [103.49, 36.03],
126: [106.16, 38.20],
97: [101.45, 36.38],
201: [87.36, 43.48],
398: [117.18, 31.51],
795: [118.50, 32.02],
655: [120.09, 30.14],
295: [113, 28.11],
311: [115.52, 28.41],
993: [114.21, 30.37],
601: [104.05, 30.39],
275: [106.42, 26.35],
317: [119.18, 26.05],
1000: [113.15, 23.08],
186: [110.20, 20.02],
261: [108.20, 22.48],
132: [102.41, 25],
18: [91.10, 29.40],
11: [114.10, 22.18],
}
const convertData = (data) => {
const res = []
for (let i = 0; i < data.length; i++) {
const geoCoord = geoCoordMap[data[i].name]
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value),
})
}
}
return res
}
/**
获取对应的json地图数据,然后向echarts注册该区域的地图,最后加载地图信息
@params {String} mapData:json数据的地址
@params {String} name: 地图名称
*/
const loadMap = (mapData, name) => {
if (mapData) {
echarts.registerMap(name, mapData)
const option = {
tooltip: {
show: true,
backgroundColor: 'rgba(13, 77, 61, 0.7)',
textStyle: {
color: '#FFF', // 文字的颜色
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: '12', // 文字字体大小
},
borderColor: 'rgba(13, 77, 61, 0.7)',
enterable: true, // 鼠标可进入浮层内
extraCssText: 'box-shadow: none',
padding: 10,
formatter: (params) => {
if (params?.seriesType === 'effectScatter') {
return ''
}
const res = `<div style="width:156px;height:120px;display: flex;flex-direction: column;">
<h3 style="margin: 5px 10px"> ${params?.name}</h3>
<div style="display:flex;flex-direction: column;flex: 1;justify-content: space-evenly;">
<div> <span style="margin: 0px 10px">使用单位:</span>2156家</div>
<div> <span style="margin: 0px 10px">在用电梯:</span>18万台</div>
<div> <span style="margin: 0px 10px">待检测电梯:</span>1526台</div>
<div> <span style="margin: 0px 10px">待检验电梯:</span>1409台</div>
</div>
</div>
`
return res
},
},
geo: {
map: name,
roam: true,
label: {
normal: {
show: true,
textStyle: {
fontSize: 10,
color: '#000000',
},
},
},
itemStyle: {
normal: {
show: true,
areaColor: '#C2F2E6',
borderColor: 'rgba(255,255,255,1)',
borderWidth: '1',
},
},
emphasis: {
show: true,
label: {
color: 'rgba(255,255,255,1)',
},
itemStyle: {
areaColor: '#16A984',
},
},
},
series: [
{ // tipImage 是UI给的标记图,如果没有,可以打开我注释的部分代码运行查看
type: 'scatter',
coordinateSystem: 'geo',
data: convertData(data),
// symbolSize: 20,
// symbol: 'path://M35.025,17.608c-5.209-4.786-11.483-2.301-15.303-4.281v-1.482c0-0.41-0.333-0.743-0.743-0.743c-0.411,0-0.743,0.333-0.743,0.743v24.682c-1.855,0.104-3.261,0.59-3.261,1.175c0,0.661,1.793,1.197,4.005,1.197c2.21,0,4.003-0.536,4.003-1.197c0-0.585-1.405-1.071-3.261-1.175V26.151C24.575,24.573,28.408,17.166,35.025,17.608z',
// symbolRotate: 0,
symbolOffset: ['50%', '-100%'],
// label: { // label 是在标记下方展示当前数据,不需要展示数据 false
// normal: {
// formatter: '{b}',
// position: 'top',
// show: false,
// textStyle: {
// color: '#ffffff',
// fontSize: 10,
// },
// },
// emphasis: {
// show: false,
// },
// },
symbolSize: [40, 24],
// 自定义图片的 路径
symbol: `image://${tipImage}`,
label: {
show: false,
},
itemStyle: {
normal: {
color: '#F06C00',
},
},
},
{
name: 'MAP',
type: 'map',
geoIndex: 0,
roam: true, // 是否可缩放
zoom: 1.1,
mapType: name,
selectedMode: 'false', // 是否允许选中多个区域
data: [{
name: '北京',
value: 2256
}, {
name: '天津',
value: 744
}, {
name: '上海',
value: 578
}, {
name: '重庆',
value: 806
}, {
name: '河北',
value: 432
}, {
name: '河南',
value: 590
}, {
name: '云南',
value: 132
}, {
name: '辽宁',
value: 487
}, {
name: '黑龙江',
value: 336
}, {
name: '湖南',
value: 295
}, {
name: '安徽',
value: 398
}, {
name: '山东',
value: 1055
}, {
name: '新疆',
value: 201
}, {
name: '江苏',
value: 795
}, {
name: '浙江',
value: 655
}, {
name: '江西',
value: 311
}, {
name: '湖北',
value: 993
}, {
name: '广西',
value: 261
}, {
name: '甘肃',
value: 349
}, {
name: '山西',
value: 273
}, {
name: '内蒙古',
value: 343
}, {
name: '陕西',
value: 319
}, {
name: '吉林',
value: 325
}, {
name: '福建',
value: 317
}, {
name: '贵州',
value: 275
}, {
name: '广东',
value: 1000
}, {
name: '青海',
value: 97
}, {
name: '西藏',
value: 18
}, {
name: '四川',
value: 601
}, {
name: '宁夏',
value: 126
}, {
name: '海南',
value: 186
}, {
name: '台湾',
value: 0
}, {
name: '香港',
value: 11
}, {
name: '澳门',
value: 0
}]
}],
}
const myChart = echarts.init(chartRef.value)
myChart.setOption(option, true)
} else {
Message.warning('无法加载该地图')
}
}
onMounted(() => {
loadMap(china, 'china') // 初始化全国地图
})
与地图的交互
地图的下点击钻
地图的自适应
- 根据浏览器窗口变化自适应
window.addEventListener('resize', () => {
myChart.resize()
})
- 点击从国家级 -> 省级 -> 市 -> 县(区)
- 下钻的多少取决于你的数据
- 比如我下钻到苏州省 - 南京市 - 玄武区
myChart.on('click', ({ data }) => {
if (data) {
const { value, jsonData, name } = data
// 这个 jsonData 跟 china的数据一样的 JSON 数据结构
loadMap(jsonData, name) // 动态加载每个地区的数据
} else {
Message.warning('暂无该区域数据')
}
})