下载Echarts组件引入Echarts
准备好渲染地图的dom
<div class="map" ref="map"></div>
实例化echarts
const mycharts = echarts.init(this.$refs.map)
声明地图需要使用的变量数据
data() {
return {
mapOption: null, //option容器
mapList: [], //用来存储地图名称
mapList1: [],
mor: 2, //默认下标2热力图显示值1
activeButton: 'value1' //高亮
}
},
获取地图json数据的请求方法,传递两个参数,
this.getMapJson = async (mapName, lenvl) => {
const url = 'https://www.isqqw.com/asset/get/areas_v3/' + lenvl + '/' + mapName + '.json'
const mapJson = await fetch(url).then(res => res.json())
return mapJson
},
封装地图需要的option可选项,由于代码太多,只提供一个省级的option吧,市级的跟省级的类似
//封装随机排序数组方法
function getRandomItems(arr, num) {
const shuffled = arr.sort(() => 0.5 - Math.random()); // 随机排序数组
return shuffled.slice(0, num); // 返回前 num 个元素
}
var tool = {
show: true,
backgroundColor: 'rgba(0, 0, 0, 0.6)', // 蓝灰色背景,这里使用半透明的蓝色作为示例
borderColor: '#66ccff', // 蓝色边框
borderWidth: 3, // 三像素边框
borderRadius: 5, // 可选,圆角效果
padding: [10, 10], // 内边距,可调整提示框内部空间
textStyle: {
color: 'white', // 设置字体颜色为白色
fontSize: 14, // 可选,设置字体大小
},
formatter: function (params) {
// 根据需要进行数据处理或格式化操作
if (params && !params.data) {
// 返回自定义的tooltip内容
return `
暂无数据
`
}
if (params && params.data.value2) {
const { adcode, name, data } = params.data;
// 返回自定义的tooltip内容
return `
<div>参与量  ${params.data.value[2]}</div>
<div>业务量  ${params.data.value2}</div>
<div>核销量  ${params.data.value3}</div>
<div style="
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #66ccff;"></div>
</div>
`
}
if (params && params.data.value) {
// 返回自定义的tooltip内容
return `
<div>领券量  ${params.data.value[2]}</div>
<div>核销量  ${params.data.value2}</div>
<div style="
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #66ccff;"></div>
</div>
`
}
},
extraCssText: 'box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);', // 可选,添加阴影效果
position: function (point,) {
// 自定义提示框的位置,确保箭头指向省份
return [point[0] - 60, point[1] - 100]; // 示例值,具体数值需根据实际情况调整
}
}
var pie = [ // 手动定义区间及对应的颜色
{ min: 0, max: 0, color: '#10184d' }, // 特别处理0值
{ min: 1, max: 9, color: '#122666' },
{ min: 10, max: 29, color: '#133780' },
{ min: 30, max: 49, color: '#124d99' },
{ min: 50, max: 99, color: '#1067b3' },
{ min: 100, max: 199, color: '#0c86cc' },
{ min: 200, max: 299, color: '#07aae6' },
{ min: 300, max: 499, color: '#00d4ff' }
]
var ric = {
fline: {
padding: [0, 25],
color: '#fff',
textShadowColor: '#030615',
textShadowBlur: '0',
textShadowOffsetX: 1,
textShadowOffsetY: 1,
fontSize: 14,
fontWeight: 400,
},
tline: {
padding: [0, 27],
color: '#ABF8FF',
fontSize: 12,
},
}
var img2 = 'image://https://niecaihang.oss-cn-beijing.aliyuncs.com/kuang.png'
// var img2 = `image://${require('../assets/images/kuang.png')}`
//中国地图option可选项
export const setOptions = (mapName, mapData, dime) => {
var randomItems = getRandomItems(mapData, 2)
var imagePath = '@/assets/images/fangk.png';
// var img2 = `image://${imagePath}`
// var img2 = 'image://https://niecaihang.oss-cn-beijing.aliyuncs.com/fk.png'
return {
tooltip: tool,
visualMap: {
type: 'piecewise', // 分段型视觉映射组件
orient: 'vertical', // 视觉映射组件的方向,可选'horizontal'或'vertical'
show: true, // 是否显示视觉映射条
selectedMode: 'multiple',
dimension: dime,
pieces: pie,
splitNumber: 0, // 指定分割的段数,这里是7段,加上最小值段共8种颜色
left: "440", // 组件离左侧的距离
bottom: '30', // 组件离底部的距离
padding: 5,
itemHeight: 10, // 设置视觉映射条的高度
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
geo: {
map: mapName,
roam: true,
selectedMode: false,
select: false,
zoom: 0.8,
// layoutCenter: ['100%', '-50%'],
// layoutSize: 750,
// 图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
label: {
show: true,
fontSize: 12,
position: 'insideTopLeft',
textStyle: {
color: '#fff', // 这里设置你想要的颜色,例如黑色
},
formatter: function (params) {
return params.name.replace(/省|自治区|县|维吾尔|壮族|回族|特别行政区|地区|自治州|香港|澳门/g, '');
}
},
itemStyle: {
borderWidth: 1, // 增加边框宽度
borderColor: '#031534', // 设置边框颜色
areaColor: '#025fa1', // 设置地图区域颜色
},
emphasis: {
itemStyle: {
borderColor: 'red', // 划过省份时的边框颜色
borderWidth: 1,// 划过省份时的边框宽度
areaColor: null
}
},
},
series: [
{
type: "map",
map: mapName,
data: mapData,
selectedMode: false,
zoom: 1.0,
geoIndex: 0,
},
// 散点圆球
{
type: 'effectScatter',
coordinateSystem: 'geo',
showEffectOn: 'render',
rippleEffect: {
period: 1,
scale: 2,
brushType: 'fill'
},
data: randomItems,
rippleEffect: {
color: '#00ffff',
period: 20, // 动画时间,值越小速度越快
scale: 6, // 波纹圆环最大限制,值越大波纹越大
brushType: 'fill', // 波纹绘制方式 stroke, fill
},
symbolOffset: [0, -10], //偏移
},
{
type: 'scatter',
coordinateSystem: 'geo',
textStyle: {
color: 'white', // 设置字体颜色为白色
fontSize: 14, // 可选,设置字体大小
},
label: {
normal: {
show: true,
padding: 15,
formatter: function (params) {
if (params && params.data.value2) {
// console.log(params);
var value = params.data.data;
var text = `参与量: ${params.data.value[2]}\n\n业务量: ${params.data.value2}\n\n核销量: ${params.data.value3}`;
return text;
}
if (params && params.data.value) {
// console.log(params);
var value = params.data.data;
var text = `领券量: ${params.data.value[2]}\n\n核销量: ${params.data.value3}`;
return text;
}
},
color: '#fff',
rich: ric
},
emphasis: {
show: true,
},
},
itemStyle: {
color: '#fff',
},
symbol: img2,
symbolSize: function (val) {
if (val) {
return val[2] / 6 + 80;
}
},
symbolOffset: [-10, -50],
data: randomItems,
},
]
}
}
组件引入option可选项文件
import { setOptions, setOptions1 } from '../utils/MapOption'
封装渲染地图的方法
this.renderMapEcharts = async (mapName, lenvl) => {
console.log(this.pass);
const mapJson = await this.getMapJson(mapName, lenvl)
echarts.registerMap(mapName, mapJson);
const mapdata = mapJson.features.map((item) => {
const data = (Math.random() * 200 + 0).toFixed(0) // 20-80随机数
const data2 = (Math.random() * 300 + 0).toFixed(0) // 20-80随机数
const data3 = (Math.random() * 420 + 0).toFixed(0) // 20-80随机数
const center = { data, data2, data3 };
const tempValue = item.properties.center ? [...item.properties.center, data, data2, data3] : item.properties.center
return {
name: item.properties.name,
value: tempValue, // 中心点经纬度
value1: data,
value2: data2,
value3: data3,
adcode: item.properties.adcode, // 区域编码
level: item.properties.level, // 层级
}
});
//判断如果是china就传递中国地图的option
if (mapName != 'china') {
mycharts.resize()
this.mapOption = setOptions1(mapName, mapdata, this.mor)
}
//判断如果不是china就传递省区地图的option
else {
mycharts.resize()
this.mapOption = setOptions(mapName, mapdata, this.mor)
}
this.$nextTick(() => {
mycharts.setOption(this.mapOption)
mycharts.resize()
})
}
接着调用渲染地图的方法,进入页面初次渲染地图
this.$nextTick(() => {
this.renderMapEcharts('china', 'country') // 初始化绘制中国地图
mycharts.resize()
})
接着开始写地图下钻的事件,我这里只判断下钻到市级,区级设了限制,如果想下钻到区县级可以根据以下调试一下代码
//地图下钻
mycharts.on('click', (param) => {
if (param.data === undefined) {
this.$message({
type: 'error', // success error warning
message: '已经在最下层了,无法继续下钻',
})
return;
}
if (param.seriesType !== 'map') return
const { adcode, level } = param.data;
// 新增条件:如果当前已经是市区级别,则不执行下钻操作
if (level === 'city') {
this.$message({
type: 'error', // success error warning
message: '已经在最下层了,无法继续下钻',
})
return;
}
const mapName = level === 'city' ? adcode : adcode + '_full';
// 防止最后一个层级被重复点击,返回上一级出错
if (this.mapList[this.mapList.length - 1] === mapName) {
// alert('已经在最下层了');
this.$message({
type: 'error', // success error warning
message: '已经在最下层了,无法继续下钻',
})
return;
}
this.$nextTick(() => {
this.mapList.push(mapName);
this.mapList1.push(level);
this.renderMapEcharts(mapName, level);
mycharts.resize()
})
});
接着写一个地图返回的dom跟方法
<div class="back">
<span v-show="mapList.length !== 0" class="Mapback" @click="back">地图返回</span>
</div>
methods:
back() {
const level = this.mapList1[this.mapList.length - 2] || 'country';
const mapName = this.mapList[this.mapList.length - 2] || 'china'; // 假设 mapList 是一个数组
this.mapList.pop(); // 移除最后一个元素
this.renderMapEcharts(mapName, level); // 调用渲染地图的方法
},
结尾:
需要注意的是,我在渲染方法下边部分去判断了一下如果mapName是China那就使用封装好的setOption方法,我还封装了一个setOption1是市区的option,这些都可以根据自己的需求自己封装,可以以我封装的setOption进行更改就行