一、最终效果
鼠标未在地图区域时,会循环上海市下所有区,通过tooltip展示区详情(每个区展示两秒);鼠标位于某区时,tooltip展示该区详情;鼠标移出地图区域时,再开始循环上海市下所有区。
我没有附上CSS代码,所以样式会与图上有所不同
二、数据格式
三、前端代码
<template>
<chart-map-shanghai ref="chartMap" height="675" :axis="mapAxis"></chart-map-shanghai>
<template>
<script>
import chartMapShanghai from './chart-map-shanghai.vue' //根据自己存放的路径动态更改
export default {
components: {
chartMapShanghai
},
data () {
return {
mapAxis: []
}
}
}
</script>
<template>
<div class="chart-box">
<chart style="height: 100%; width: 100%;" ref="chartShanghai" :options="options" autoresize></chart>
</div>
</template>
<script>
import Chart from "vue-echarts";
export default {
components: {
chart: Chart
},
props : {
axis: {
type: Array,
required: true,
default () {
return [];
}
}
},
data() {
return {
timer: null,
index: -1,
geoCoordMap: {
'静安区': [121.448224,31.229003],
'杨浦区': [121.522797, 31.270755],
'长宁区': [121.4222, 31.218123],
'虹口区': [121.491832, 31.26097],
'普陀区': [121.392499, 31.241701],
'黄浦区': [121.490317,31.222771],
'徐汇区':[121.43752,31.179973],
'闵行区': [121.375972, 31.111658],
'宝山区': [121.489934, 31.398896],
'嘉定区': [121.250333, 31.383524],
'浦东新区': [121.567706, 31.245944],
'金山区': [121.330736, 30.724697],
'松江区': [121.223543, 31.03047],
'青浦区': [121.113021, 31.151209],
'奉贤区': [121.458472, 30.912345],
'崇明区': [121.397516, 31.626946],
}
}
},
computed : {
mapJson() {
return require(`./310000.json`);
},
data () {
return this.convertData();
},
effectScatterData () {
return this.index===-1?[]:[this.data[this.index]];
},
options () {
return {
tooltip: {
backgroundColor: 'rgba(0,0,0,0)',
trigger: 'item'
},
geo: {
map: 'shanghai',
aspectScale: 0.85,
layoutCenter: ["50%", "50%"],
layoutSize: '100%',
label: {
emphasis: {
show: false,
},
},
roam: false, //是否允许缩放
itemStyle: {
normal: {
shadowColor: '#1E3A75',
shadowOffsetX: 0,
shadowOffsetY: 15,
opacity: 0.5,
},
emphasis: {
areaColor: '#276fce',
}
},
tooltip: {
show: true
}
},
series: [
{
type: 'map',
mapType: 'shanghai',
tooltip: {
padding: 0,
enterable: true,
transitionDuration: 1,
extraCssText: 'z-index: 2000',
textStyle: {
color: '#000',
decoration: 'none',
},
className: 'custom-tooltip-box',
formatter: function(params) {
let data = Boolean(params.data)?{
name: params.data.name,
num1: 'num1' in params.data?params.data.num1:'--',
num2: 'num2' in params.data?params.data.num2:'--'
}:{
name: params.name,
num1: '--',
num2: '--'
};
return '<div class="custom-tooltip-box">'
+ '<div class="tooltip_tit">'
+ '<div class="tit">'+ data.name +'</div>'
+ '<div class="line"></div>'
+ '</div>'
+ '<div class="tooltip_cont">'
+ '<div class="list1">'
+ '<div class="text">医保码激活数</div>'
+ '<div class="num">'+ data.num1 + '</div>'
+ '</div>'
+ '<div class="list2">'
+ '<div class="text">医保码激活率</div>'
+ '<div class="num">'+ data.num2 +'</div>'
+ '</div>'
+ '</div>'
+ '</div>';
}
},
aspectScale: 0.85,
layoutCenter: ["50%", "50%"], //地图位置
layoutSize: '100%',
zoom: 1, //当前视角的缩放比例
scaleLimit: {
min: 1,
max: 2
},
itemStyle: {
normal: {
areaColor: '#18418C',
borderColor: '#4F9EF0',
borderWidth: 1
},
emphasis: {
areaColor: '#96DAFF',
borderColor: '#4F9EF0',
borderWidth: 2,
label: {
color: "#fff"
}
}
},
labelLine: {
show: true
},
data: this.data
},
{
type: 'effectScatter',
left: '10',
coordinateSystem: 'geo',
data: this.effectScatterData,
symbolSize: 15,
showEffectOn: "render",
rippleEffect: {
brushType: "stroke"
},
hoverAnimation: true,
itemStyle: {
normal: {
color: "#FDFF12",
shadowBlur: 8,
shadowColor: "#9BF9FF"
}
},
tooltip: {
show: false
},
zlevel: 2
},
{
type: 'scatter',
coordinateSystem: 'geo',
data: this.data,
symbolSize: 5,
emphasis: {
disabled: true
},
lable: {
normal: {
show: false
},
emphasis: {
disabled: true,
show: false
}
},
itemStyle: {
normal: {
color: '#FDFF12',
shadowBlur: 8,
shadowColor: "#57B7FF"
}
},
tooltip: {
show: false
}
}
]
};
},
mapHaveData () {
return this.data.length>0;
},
maxIndex () {
return this.data.length-1;
}
},
watch: {
mapHaveData (val, old) { //处理好地图数据后,再init,不然循环展示的tooltip,会一直停留在第一项数据的详情
val&&!old?this.init():'';
},
effectScatterData: {
handler: function (val) {
this.$nextTick(() => {
if(val.length>0) {
this.$refs.chartShanghai.dispatchAction({
type: 'downplay',
seriesIndex: 0
});
this.$refs.chartShanghai.chart.setOption(this.options); //一定要在this.$nextTick中setOption,不然地图不会更新,下面高亮区域与展示区域详情也不会生效
this.$refs.chartShanghai.dispatchAction({ //一定要在setOption后执行才会生效
type: 'highlight',
seriesIndex: 0,
dataIndex: this.index
});
this.$refs.chartShanghai.dispatchAction({ //一定要在setOption后执行才会生效
type: 'showTip',
seriesIndex: 0,
dataIndex: this.index
});
}
});
},
deep: true
}
},
methods: {
convertData() {
let res = [];
this.axis.forEach(x => {
this.geoCoordMap[x.name]?res.push({
name: x.name,
value: this.geoCoordMap[x.name],
num1: x.value1,
num2: x.value2
}):'';
})
return res;
},
init() {
this.mouseEvents()
this.mapActive()
},
mouseEvents() {
this.$refs.chartShanghai.chart.on("mouseover", params => {
clearInterval(this.timer)
this.timer = null
this.$refs.chartShanghai.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: this.index
})
});
this.$refs.chartShanghai.chart.on("mouseout", params => {
this.mapActive()
});
},
mapActive() {
clearInterval(this.timer)
this.timer = null
this.timer = setInterval(() => {
this.index++;
this.index>this.maxIndex?this.index=0:'';
}, 2000);
}
},
created() {
Chart.registerMap('shanghai', this.mapJson);
},
destroyed() {
clearInterval(this.timer);
}
}
</script>
四、310000.json 资源地址 https://download.csdn.net/download/hrcsdn13/89570096