效果:
引入echarts后:
阿里云下载json数据:
引入数据:
import chongqing from '@/assets/js/chongqing.json'
同样需要一个放置容器:
<template>
<div>
<div style="width:100%;height:100%" id="mapid"></div>
</div>
</template>
准备两组点数据:其中value是坐标,total是点聚合数值,其他是要展示在提示框中的内容
data() {
return {
mapList1: [
{ name: 'name1', text1: '这是name1的text1', text2: '这是name1的text2', text3: '这是name1的text3', value: [106.588045, 29.556178], total: 0 },
{ name: 'name2', text1: '这是name2的text1', text2: '这是name2的text2', text3: '这是name2的text3', value: [106.767994, 29.676749], total: 0 },
{ name: 'name3', text1: '这是name3的text1', text2: '这是name3的text2', text3: '这是name3的text3', value: [106.496634, 29.608946], total: 0 },
{ name: 'name4', text1: '这是name4的text1', text2: '这是name4的text2', text3: '这是name4的text3', value: [106.644387, 29.53808], total: 0 },
{ name: 'name5', text1: '这是name5的text1', text2: '这是name5的text2', text3: '这是name5的text3', value: [107.09742, 30.236979], total: 0 },
{ name: 'name6', text1: '这是name6的text1', text2: '这是name6的text2', text3: '这是name6的text3', value: [107.17742, 30.236979], total: 0 },
],
mapList2: [
{ name: 'maplistname1', text1: '这是name1的text1', text2: '这是name1的text2', text3: '这是name1的text3', value: [108.776174, 30.951213], total: 0 },
{ name: 'maplistname2', text1: '这是name2的text1', text2: '这是name2的text2', text3: '这是name2的text3', value: [108.196659, 30.589787], total: 0 },
{ name: 'maplistname3', text1: '这是name3的text1', text2: '这是name3的text2', text3: '这是name3的text3', value: [107.414774, 29.577791], total: 0 },
{ name: 'maplistname4', text1: '这是name4的text1', text2: '这是name4的text2', text3: '这是name4的text3', value: [107.046828, 29.526098], total: 0 },
{ name: 'maplistname5', text1: '这是name5的text1', text2: '这是name5的text2', text3: '这是name5的text3', value: [105.818808, 29.497347], total: 0 },
],
}
},
配置数据:
// 地图
showMap(id) {
let chongqingChart = this.$echarts.init(document.getElementById(id))
chongqingChart.clear()
this.$echarts.registerMap('chongqing', chongqing)
let option = {
tooltip: {
triggerOn: 'click',
trigger: 'item',
borderWidth: 0,
backgroundColor: "rgba(255, 255, 255, 0.8)",
formatter: function (params) {
if (params.data.total > 0) {
// 点击聚合点 放大地图,复原数据
option.geo.center = params.data.value;
option.series[0].data = JSON.parse(sessionStorage.getItem('mapList1'))
option.series[1].data = JSON.parse(sessionStorage.getItem('mapList2'))
option.geo.zoom = 4;
chongqingChart.setOption(option);
return
}
let str = `<div class='map-tooltips'>
<span class='tooltips-img'></span>
<span class='dot'></span> <span class='tooltips-title'>${params.seriesName} </span>
<ul>
<li><p class='tooltips-text1'>name</p> <p class='tooltips-text2'>${params.data.name}</p></li>
<li><p class='tooltips-text1'>内容1</p> <p class='tooltips-text2'>${params.data.text1}</p></li>
<li><p class='tooltips-text1'>内容2</p> <p class='tooltips-text2'>${params.data.text2}</p></li>
<li><p class='tooltips-text1'>内容3</p><p class='tooltips-text2' >${params.data.text3}</p></li>
</ul>
</div>`;
return str
}
},
// 图例
legend: {
data: [{ name: 'tag', icon: 'image://' + require('@/assets/img/tag.png') }, { name: 'mapList2', icon: 'image://' + require('@/assets/img/tag1.png') }],
itemWidth: 20,
itemHeight: 20,
orient: 'vertical', // 竖向排列 horizontal横向
y: 'bottom',
x: 'left',
textStyle: {
color: '#fff',
fontSize: 16,
},
selected: {
'tag': true,
'mapList2': true,
// 不想显示的都设置成false
},
padding: [0, 10, 20, 20],
},
geo: {
show: true,
map: "chongqing",
roam: true, // roam: 'scale', 只能缩放
scaleLimit: {
min: 1.2,
max: 10
},
zoom: 1.2,
aspectScale: 1,
top: 50, // 改变大小
center: [107.789305, 30.127088], //地图中心点经纬度坐标
itemStyle: {
borderColor: "#71fd6c", // 边界颜色
areaColor: "#eaf8c9", // 区域颜色
borderWidth: 1,
shadowBlur: 10,
shadowColor: "rgba(63, 218, 255, 0.4)",
emphasis: {
show: false, // 鼠标移入样式
areaColor: "#f8e0c9"
}
},
label: {
// 文字样式
normal: {
show: true,
fontSize: "10",
color: "#16eb0f"
},
emphasis: {
show: false
}
}
},
series: [
{
name: 'tag',
type: "scatter",
coordinateSystem: "geo",
data: this.mapList1,
showAllSymbol: true,
symbolSize: [15, 30],
symbol: 'image://' + require('@/assets/img/tag.png'),
// 聚合标签样式
label: {
show: true,
position: 'outside',
color: '#fff',
lineHeight: 8,
backgroundColor: '#e7642f',
borderColor: '#e7642f',
borderRadius: 20,
borderWidth: 15,
formatter(params) {
let data = params.data
let total = data.total ? data.total + 1 : ''
return `${total}`;
},
},
},
{
name: 'mapList2',
type: "scatter",
coordinateSystem: "geo",
data: this.mapList2,
showAllSymbol: true,
symbolSize: [15, 30],
symbol: 'image://' + require('@/assets/img/tag1.png'),
label: {
show: true,
position: 'outside',
color: '#fff',
lineHeight: 8,
backgroundColor: '#e7642f',
borderColor: '#e7642f',
borderRadius: 20,
borderWidth: 15,
formatter(params) {
let data = params.data
let total = data.total ? data.total + 1 : ''
return `${total}`;
},
},
}
]
};
chongqingChart.setOption(option)
// 监听地图缩放事件
chongqingChart.on("georoam", params => {
if (params.dy || params.dx) return; //如果是拖拽事件则退出
let _option = chongqingChart.getOption(); //获取最新的option配制
let _zoom = _option.geo[0].zoom; //获取当前缩放比例zoom
_option.series[0].data = JSON.parse(sessionStorage.getItem('mapList1'))
_option.series[1].data = JSON.parse(sessionStorage.getItem('mapList2'))
// _option.geo.center = [107.789305, 30.127088]
if (_zoom >= 1.5) {
_option.series[0].data = _option.series[0].data ? this.mapData(_option.series[0].data, 0.01) : ''
_option.series[1].data = _option.series[1].data ? this.mapData(_option.series[1].data, 0.01) : ''
} else if (_zoom < 1.5) {
_option.series[0].data = _option.series[0].data ? this.mapData(_option.series[0].data, 0.1) : ''
_option.series[1].data = _option.series[1].data ? this.mapData(_option.series[1].data, 0.1) : ''
}
//清空
chongqingChart.clear();
chongqingChart.setOption(_option); //更新修改后的option配制
});
window.addEventListener('resize', function () {
chongqingChart.resize()
})
},
计算聚合点方法:
// 地图数据点聚合
mapData(list, distance) {
// distance 判断聚合点数值 可以自行定义
let arrMaplist = [], lngIndex = true, latIndex = 1;
// 声明一个数组,包含与原始数据一样长度的n个数组
for (let i = 0; i < list.length; i++) {
arrMaplist.push([])
}
// 遍历原始数据
for (let i = 0; i < list.length; i++) {
// 存储内层遍历起始数据
latIndex = latIndex == i ? i + 1 : latIndex
for (let j = latIndex; j < list.length; j++) {
// 对比当前数据与下一个数据 是否属于同一个点聚合
if (Math.abs(list[i].value[0] - list[j].value[0]) <= distance && Math.abs(list[i].value[1] - list[j].value[1]) <= distance) {
// 遍历查看是否存在已有聚合点
arrMaplist.forEach((ele) => {
if (ele.length > 0) { // 有数据
ele.forEach(val => { // 且数据中包含当前元素 将下一元素放进去
if (val.value[0] == list[i].value[0]&&val.value[1] == list[i].value[1]) {
ele.push(list[j])
lngIndex = true
} else {
lngIndex = false // 不包含
}
})
} else {
lngIndex = false // 不包含
}
})
if (!lngIndex) {
arrMaplist[i].push(list[j]) // 新增聚合点
}
latIndex = j + 1
}
}
}
// 聚合点总数
arrMaplist.forEach((item, index) => {
if (item.length != 0) {
list[index].total = item.length
}
})
// 删除list 里面的对应的多余数据,只保留第一条
arrMaplist.forEach((item) => {
item.forEach(ele => {
let inde = list.indexOf(ele)
list.splice(inde, 1)
})
})
return list
},
初始化点聚合:
mounted() {
sessionStorage.setItem('mapList1', JSON.stringify(this.mapList1))
sessionStorage.setItem('mapList2', JSON.stringify(this.mapList2))
// 初始化处理点聚合
this.mapList1 = this.mapData(this.mapList1, 0.1)
this.mapList2 = this.mapData(this.mapList2, 0.1)
},
提示框样式写在css里面:
<style lang="scss" scoped>
// 地图点击提示框样式
/deep/ .map-tooltips {
width: 255px;
height: 218px;
// background: url('') left top,
// url('') left top;
color: #16eb0f;
background-size: 100% 100%;
padding: 18px 14px 0 14px;
font-size: 12px;
text-align: left;
.tooltips-img {
// background: url('~@/assets/img/') no-repeat;
width: 22px;
height: 22px;
margin-top: -18px;
margin-right: -14px;
float: right;
}
.dot {
display: inline-block;
width: 5px;
height: 5px;
background: #f02b2b;
border-radius: 50%;
margin-right: 4px;
}
.tooltips-title {
color: #f02b2b;
}
& > ul > li {
color: #276299;
display: flex;
justify-content: flex-start;
margin-top: 10px;
.tooltips-text1 {
text-align: right;
width: 50px;
margin-right: 8px;
color: rgba(28, 196, 255, 0.8);
}
.tooltips-text2 {
white-space: normal;
width: 120px;
}
}
}
</style>
label 文字样式编辑,主要是给文字添加描边
在series里面编辑
series: [
{
label: {
show: true, // 是否显示label
position: [10, 0], // 文字位置 可以是数组、inside outside insideLeft insideRight 以此类推
color: "#fff", // 文本颜色
lineHeight: 18, // 行高
fontSize: "16", // 字号
textBorderColor: "red", // 文字描边颜色
textBorderWidth: 1,
// backgroundColor: 'blue', // 整个label的背景色
// borderColor: '#fff', // 整个label的边框
// borderRadius: 20,
// borderWidth: 15,
formatter(params) { // label的文本内容
return `${params.name}`;
}
}
]
版权声明:本文为weixin_54106595原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。