echarts-gl的type为map3D修改不同区域的颜色和点击事件

效果图
在这里插入图片描述
regions的数据格式
在这里插入图片描述
以下是地图初始化代码、双击地图和单击高亮,方法是封装后的,mapData 的数据格式我放在后面,均有注释

const drawEcharts = mapData => {
	//数据过多的时候,echarts渲染过慢,可以使用此方法
	if (myChart.value) {
		myChart.value.dispose();
	}
	let chartDom = centerMap.value;
	myChart.value = echarts.init(chartDom);
	myChart.value.clear();
	myChart.value.resize();
	let nameMap = "centerMap";
	// 图标数据
	// 根据传入的type获取不同的初始数据
	mapDataList = mapData;

	// 根据获取到的区划第一个查询区划的等级(地图下转的时候用,如果不需要可以用,这个是为了获取区划等级)
	currentMapLevel.value = mapUtils.getRegionLevel(mapData.features[0].properties.adcode.toString());
	//渲染地图数据
	echarts.registerMap(nameMap, mapData);
	// mapData的数据中含有每个区对应有多少人(如:成都市1000人)
	//number和resultSac是将每个区的人数做一个排序,然后规定一个范围,然后某个范围只能用一种颜色
	// 比如索引中0-5是颜色#d0f8ff,6-11是颜色#93d5fd以此类推
	// 这两个代码主要是为了让颜色能更好的划分区域,也可以自己手动划分,如果手动划分,number和resultSac是可以不要的

	// 获取分段后数据
	let number: any = mapData.features
		.map(function (feature) {
			return feature.properties.num ? Number(feature.properties.num) : 0;
		})
		.sort(function (a, b) {
			return a - b;
		});
	// mapUtils.sacdata是封装的方法,可以不需要
	let resultSac = mapUtils.sacdata(number, 5);
	// 地图模块颜色划分(这是主要的颜色划分)regions 的数据格式放在上面的,可以对照查看,手动的我放在下面了
	let regions = mapData.features.map(function (feature) {
		let colorArr = ["#d0f8ff", "#93d5fd", "#5eaedd", "#3787b7", "#0e6598"];
		let colorNum = 0;
		for (let index = 0; index < resultSac.length; index++) {
			if (feature.properties.num <= resultSac[index]) {
				colorNum = index;
				break;
			}
		}
		return {
			name: feature.properties.name,
			value: feature.properties.adcode,
			num: feature.properties.num,
			itemStyle: { color: colorArr[colorNum] }
		};
	});
	// console.log(regions, "regions");
	// 地图配置
	let optionMap = {
		geo3D: {
			//加载geo3D
			map: nameMap,
			// 设置3D视角的位置和朝向
			viewControl: {
				distance: 130, // 相机距离物体的距离
				alpha: 70, // 三维场景水平方向的旋转角度
				beta: 30 // 三维场景垂直方向的旋转角度
			},
			// 文字
			label: {
				show: false,
				fontSize: 13,
				fontWeight: 600,
				opacity: 1,
				textStyle: {
					backgroundColor: "transparent", // 设置 label 背景透明
					color: "#ffffff", // 设置 label 文字颜色
					fontFamily: "YSBTH"
				}
			},
			itemStyle: {
				color: "#5ca3f9", //将geo3d数据设置为透明
				opacity: 1, //透明
				borderColor: "#62def5",
				borderWidth: 1,
				areaColor: "rgba(37,157,255,0.2)"
			},
			// 类似于hover
			emphasis: {
				label: {
					show: false
				}
			},
			zlevel: 2
		},
		series: [
			{
				type: "map3D", //加载series数据
				map: nameMap,
				// 外边界颜色
				itemStyle: {
					color: "rgba(1, 16, 31, 0)",
					opacity: 1,
					borderColor: "#75f3f8",
					borderWidth: 1,
					shadowColor: "#3ffeff",
					shadowOffsetY: 15,
					shadowBlur: 8,
					areaColor: "rgba(5,21,35.0.1)"
				},

				label: {
					show: true,
					fontSize: 13,
					fontWeight: 600,
					opacity: 1,
					textStyle: {
						backgroundColor: "transparent", // 设置 label 背景透明
						color: "#ffffff", // 设置 label 文字颜色
						fontFamily: "YSBTH"
					}
				},
				// 设置3D视角的位置和朝向
				viewControl: {
					distance: 130, // 相机距离物体的距离
					alpha: 70, // 三维场景水平方向的旋转角度
					beta: 30 // 三维场景垂直方向的旋转角度
				},
				// 类似于hover,双击地图的区块或者点击,就是通过这个传递的值
				emphasis: {
					label: {
						formatter: function (params) {
							highlightObj.value = params;
							return params.name;
						},
						show: true,
						fontSize: 13,
						fontWeight: 600,
						opacity: 1,
						textStyle: {
							backgroundColor: "transparent", // 设置 label 背景透明
							color: "#fff", // 设置 label 文字颜色
							fontFamily: "YSBTH"
						}
					},
					itemStyle: {
						color: "#15ffff",
						opacity: 1,
						borderColor: "#62def5",
						borderWidth: 5
					}
				},
				// shading: 'color',
				zlevel: 3,
				// 数据
				data: regions,
				large: true
			}
		]
	};

	myChart.value.clear();
	// myChart.value.resize();
	myChart.value.setOption(optionMap);
	
	// 双击下钻
	myChart.value.getZr().on("dblclick", async res => {
		res.event.stopPropagation();
		// 因为我是父传子封装的组件,会涉及到有些地方是不允许下转的,这个值就是父传递过来是否允许下转的
		if (!propsList.allow) return;
		// 这儿是接收emphasis.label的信息,在这儿我就不贴出数据格式了,可以自己打印看看
		let params = highlightObj.value;
		// 这儿是获取你点击的那个区的信息
		let curData = mapData.features[params.dataIndex];
		// 如果是村一级不下钻(这是项目要求,如果没有这个要求,可以删除)
		if (currentMapLevel.value == 6) {
			return;
		}
		// 获取这个点击地方的区划号,因为我们后端要求的是字符串,所以我转了一下格式
		let code = curData.properties.adcode.toString();
		// 这儿是我根据后端需求,返回上一级需要区划号,所以我把我下转的区划号存在一个数组里
		runInHole.value.push(code);
		//  层级(省的层级对应2;市=>3;区=>4以此类推)
		let level = currentMapLevel.value;
		level++;
		// 这是发送请求,请求获取地图信息,可以在这里获取到了新的地图信息后重新渲染地图,调用封装的方法drawEcharts
		// 因为系统响应时长的问题,我是通过其他地方调用的,就不在这儿展示了
		await getMapData(1, 99, [code], level);
		// 这个是子传父,可以不要
		emit("getRegionList", {
			level: level,
			regions: mapList,
			curData
		});


	// 定义单击高亮的地图
	let colorActive = ref({
		num: -1,
		color: null
	});
	// 单击高亮
	myChart.value.getZr().on("click", () => {
		click_type = false;
		let params = highlightObj.value;
		// 层级
		let level = currentMapLevel.value;
		level++;

		setTimeout(() => {
			if (click_type != false) return;
			highlightName.value = params.name;
			let option = myChart.value.getOption();
			let list = option.geo3D[0].regions;

			if (list.length == 1) return;
			//找到选中的地图,并设置高亮
			let result = list.find(el => el.name === params.name);
			// 所在位置索引
			let resultIndex = list.findIndex(el => el.name === highlightName.value);
			// 将之前的高亮过区域换成原本的颜色
			if (colorActive.value.num >= 0) {
				option.series[0].data[colorActive.value.num].itemStyle = {
					color: colorActive.value.color
				};
			}
			// 存储点击区域的索引和原本的颜色
			colorActive.value.num = resultIndex;
			colorActive.value.color = option.series[0].data[resultIndex].itemStyle.color;

			if (resultIndex != -1) {
				highlightIndex.value = resultIndex;
			}
			// 设置高亮-以及高亮字体大小
			if (result) {
				option.series[0].data[resultIndex].itemStyle = {
					color: "#15eaff"
				};
				option.series[0].label.textStyle.fontSize = 13;

				if (myChart.value) {
					myChart.value.clear();
				}
				myChart.value.setOption(option);
			}
		}, 500);
	});
};

这个是手动区分,就看绿色框框的,feature.properties.num就是各个区人数
在这里插入图片描述

mapData 的数据格式
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值