在做业务的时候,有一个数据大屏的需求,这里总结一下遇到绘制地图时遇到的问题以及解决方法,包括:
中国地图的引入;
外边框和内边框(每个省边框细,而整体中国地图外边框粗);
阴影的实现;
轮播每个省份,并显示图注 tooltip
;
在 package.json
文件中发现 echarts
版本为 5.2.2,该版本的 echarts
库已经暂停了中国地图的提供(低版本的 echarts
在 node_modules
中会注册好中国地图的 json
文件)。
因此,我们要自己下好地图的 js
或 json
文件,这里提供一下我的数据文件(提取码:4h1e)。
在引入地图数据包后,我们要在入口文件注册地图。
// 这里我是按需引入
import china from '@/map/json/china.json'
// 引入 echarts
import * as echarts from 'echarts'
// 注册
Vue.prototype.$echarts = echarts
echarts.registerMap('china', china)
到这里就完成了中国地图的注册,直接在组件中使用就可以了。
地图的绘制非常简单,在 echarts
的中文文档中有详细描述,具体而言使用 geo
配置项,这里不做过多赘述,直接贴上我的配置代码。
geo: {
map: 'china',
roam: false, // 不开启缩放和平移
// zoom: 1.23, // 视角缩放比例
data: this.chinaMapData,
itemStyle: {
borderColor: 'rgb(249, 214, 90)', // 设置外层边框
areaColor: 'rgb(45, 59, 130)',
borderWidth: 3,
shadowColor: '#01273F', // 设置阴影
shadowOffsetX: 0,
shadowOffsetY: 25
},
emphasis: { // 鼠标悬停外边框时什么都不显示也不改变
focus: 'none',
borderColor: 'rgb(249, 214, 90)',
areaColor: 'rgb(45, 59, 130)',
borderWidth: 3,
label: {
show: false
}
},
tooltip: {
trigger: 'item',
formatter() { // 当鼠标悬停到边框时不展示数据
return null
}
},
select: false
}
这个实现网上也有很多详细的教程,总而言之便是写两个图层,分别为 geo
(下图层)和 series
(上图层),也就是说在 series
配置项里再加一个 map
图层即可,代码如下:
series: [
{
type: 'map',
map: 'china', // 必须设置此属性,不然不显示,找了很久才找到这个坑,网上的教程都没有!!
data: this.chinaMapData,
select: false,
roam: false, // 很重要
itemStyle: {
normal: {
areaColor: 'rgb(45, 59, 130)',
borderColor: 'rgb(249, 214, 90)',
borderWidth: 1
}
},
emphasis: {
itemStyle: {
areaColor: '#F3B329', // 鼠标选择区域颜色
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
label: { // 鼠标悬停时显不显示省名
show: false
}
},
tooltip: {
trigger: 'item',
formatter(params) { // 展示当前省份的合作企业数量
const res = `
${params.name}省合作企业数量:
${params.value || 0}
`
return res // 自行定义formatter格式
},
backgroundColor: 'rgba(26, 49, 122, 0.8)', // 提示标签背景颜色
padding: 50,
borderWidth: 0
}
}
]
需要注意的是,如果不想鼠标悬停在外边框出现 tooltip
或者发生样式的改变,那么一定要在上面的 geo
配置项中设置相应的配置,代码已经贴过在上面了,具体大家可以根据注释理解。
到这里就实现了内外边框。
直接在下图层,即 geo
配置项中设置如下配置:
itemStyle: {
shadowColor: '#01273F', // 设置阴影
shadowOffsetX: 0,
shadowOffsetY: 25
},
具体数值可以根据要求修改。
根据 echarts
的 dispatchAction
和 on
实例方法实现,具体代码如下:
const mychart = this.$echarts.init(this.$refs.chinaMap)
mychart.setOption(option)
let hourIndex = 0
let fhourTime = null
fhourTime = setInterval(() => {
mychart.dispatchAction({
type: 'downplay',
seriesIndex: 0
})
mychart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: hourIndex
})
mychart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: hourIndex
})
hourIndex++
if (hourIndex > this.chinaMapData.length) {
hourIndex = 0
}
}, 3000)
// 鼠标移入停止轮播
mychart.on('mousemove', e => {
clearInterval(fhourTime)
mychart.dispatchAction({
type: 'downplay',
seriesIndex: 0
})
mychart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: e.dataIndex || ''
// 这个非空判定很重要,因为 geo 中没有 dataIndex,
// 而鼠标移入一定会先触到 geo,会使得整个地图都被高亮。
})
mychart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: e.dataIndex || ''
})
})
// 鼠标移出恢复轮播
mychart.on('mouseout', () => {
fhourTime = setInterval(() => {
mychart.dispatchAction({
type: 'downplay',
seriesIndex: 0
})
mychart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: hourIndex
})
mychart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: hourIndex
})
hourIndex++
// 这里根据需求显示多少省份,我这里的需求只需要轮播有数据的省份
if (hourIndex > this.chinaMapData.length) {
hourIndex = 0
}
}, 3000)
})
以上便是这次需求中对 chinaMap
的实现。