最近遇到一个需求:需要在地图中实现鼠标点击或者停留在地图中某一片区域时,该区域显示亮高和显示tooltip提示框信息,但是难点在于需要在tooltip提示框中再绘制一层图表。按以往我们做过都是这种,tooltip提示框中只是单纯显示文本信息。
但是,需求要的不是这种,先不多说,直接给你们看最终展示的效果:
鼠标点击或停留在某一片区域时,在tooltip提示框中显示该区域的另外一层数据图表,鼠标单击可选中或取消区域的亮高显示,以及两层地图凸显一个立体层次感。看完记得点个赞(技术分享,加快成长)。
这里我们以广州市作为Demo,可以看出这是我们想要的在tooltip提示框中绘制另外一层图表的效果。
ok,接下来我们不唠嗑,直接上代码(大家最喜欢的哈哈)。
项目结构:
项目是使用Vue + typescript + antd vue,大家根据自己的项目来配置。
一、创建gzMap.vue文件:
<template>
<div class="main">
<div ref="gzMap" class="gzMap">div>
<div class="Mybutton">
<a-radio-group :value="typeName" @change="handleTypeChange">
<a-radio-button value="type1">
模块一
a-radio-button>
<a-radio-button value="type2">
模块二
a-radio-button>
a-radio-group>
div>
div>
template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import gzMapData from "@/common/gzMap-common/index";
@Component
export default class HelloWorld extends Vue {
//模块名称
private typeName: string = "type1";
// 广州地图各类型指数数据
private guangzhouDatas: any;
// 引入广州地图地理位置数据
private guangzhouMap: any = require("@/common/gzMap-common/guangzhou.json");
// 引入地图需要的tooltip配置项
private mapAreaDatas: any;
private $echarts: any;
//监听传入指数模块名称改变
@Watch("typeName", { immediate: true })
private watchNum(val: string, oldVal: string) {
// 根据指数类型引入对应echart配置项文件
this.OptionType();
// 根据指数类型引入对应echart地图数据文件
this.dataType();
}
private mounted() {
const ele = this.$refs.gzMap;
const guangzhouChart: any = this.$echarts.init(ele);
//页面切换,销毁监听事件
this.$on("hook:beforeDestroy", () => {
window.removeEventListener("resize", () => {
guangzhouChart.resize();
});
});
}
// 根据不同模块指数,按需动态引入不同echart配置项文件,用于地图tooltip渲染
private OptionType() {
if (this.typeName == "type1") {
//指数1数据
import("@/common/gzMap-common/gzMapData1").then(module => {
this.mapAreaDatas = module.default.option_gzMapType;
});
}
}
// 根据不同模块指数,按需要动态引入不同地图数据文件
private dataType() {
import("@/common/gzMap-common/index").then(module => {
//指数模块名称
let tag: string = "";
tag = this.typeName;
switch (tag) {
case "type1": {
this.guangzhouDatas = module.default.dataType1;
break;
}
// 根据自己的需求可引入多种地图数据文件
default: {
break;
}
}
//地图数据加载后执行,绘制地图
if (this.guangzhouDatas) {
this.mapDraw();
}
});
}
//绘制广州地图
private mapDraw() {
const ele = this.$refs.gzMap;
const guangzhouChart = this.$echarts.init(ele, "shine");
guangzhouChart.showLoading();
guangzhouChart.hideLoading();
const option = {
tooltip: {
textStyle: {
color: "#B1D6F6",
fontSize: 8,
padding: 20,
align: "left"
},
trigger: "item",
formatter: function(params:any, ticket:any, callback:any) {
// 区域名称
let AreaName = params.data.name;
// 区域数据百分比
let percent = params.data.percent;
// 区域数据增长百分比
let Increase = params.data.Increase;
// 给tooltip传入元素的id,延迟执行,否则会找不到元素
setTimeout(function() {
that.tooltipFn("toolpitData", params);
}, 100);
return `${AreaName}${percent}%
+${Increase}%
`;
}
},
// 第二层地图,可设置与一层地图位置偏差一些,突出点立体层次感
geo: {
map: "guangzhou",
roam: false,
zoom: 1.1,
aspectScale: 1.1, //长宽比
itemStyle: {
normal: {
areaColor: "#073E5420",
shadowColor: "transparent"
},
emphasis: {
borderWidth: 1,
color: "#166F6134",
label: {
show: false
}
}
}
},
// 第一层地图
series: [
{
name: "广州",
type: "map",
aspectScale: 1, // 长宽比
zoom: 1.1,
mapType: "guangzhou", // 自定义扩展图表类型
selectedMode: "multiple",
label: {
show: false
},
// 是否开启鼠标缩放和平移漫游
roam: false,
//地图样式:
itemStyle: {
borderColor: "#10B9C1",
borderWidth: "1",
shadowColor: "#23C6CE",
shadowBlur: 50,
shadowOffsetX: -10,
shadowOffsetY: -5,
areaColor: "#247a9a34"
},
// 高亮状态下的多边形和标签样式:
emphasis: {
label: {
color: "#FFFFFF"
},
itemStyle: {
areaColor: "#389BB7"
}
},
data: this.guangzhouDatas
}
]
};
this.$echarts.registerMap("guangzhou", this.guangzhouMap);
guangzhouChart.setOption(option);
const that = this;
// 鼠标单击选中亮高或取消亮高,显示区域数据
guangzhouChart.on("click", function(params:any) {
//第二层地图位地理坐标系组件,不设置鼠标单击事件
if (params.componentType === "geo") {
return;
}
// 遍历广州地图判断被点击选中的区域
for (let i = 0; i < that.guangzhouDatas.length; i++) {
if (params.name == that.guangzhouDatas[i].name) {
if (that.guangzhouDatas[i].checked === false) {
// 设置选中区域亮高
that.guangzhouDatas[i].checked= true;
params.data.checked= true;
} else {
// 取消选中区域亮高
that.guangzhouDatas[i].checked= false;
params.data.checked= false;
}
}
}
guangzhouChart.setOption(option);
});
window.addEventListener("resize", function() {
guangzhouChart.resize();
});
}
// 绘制广州地图tooltip中的图表
private tooltipFn(el:string, params:any) {
const event = document.getElementById(el);
// 根据不同类型指数分别引用不同图表数据
if (this.typeName == "type1") {
// 设置指数1数据
let dataLength = this.mapAreaDatas.series.length;
for (let i = 0; i < dataLength; i++) {
this.mapAreaDatas.series[i].data = [];
this.mapAreaDatas.series[i].data = params.data.dataList[i];
}
}
const toolitpChart: any = this.$echarts.init(event);
toolitpChart.setOption(this.mapAreaDatas);
window.addEventListener("resize", function() {
toolitpChart.resize();
});
}
// 切换模块类型,这里Demo只引入一种tooltip层图表类型
private handleTypeChange(e:any) {
this.typeName = e.target.value;
this.$message.success("当前地图加载类型是:"+ e.target.value)
}
}
script>
<style lang="less">
.main {
width: 100%;
height: 100%;
}
.gzMap {
width: 100%;
height: 100%;
background-color: black;
}
.toolpitData {
width: 100%;
height: 4vh;
margin: 0.5vh auto 0;
}
.tooltipArea {
width: 7rem;
height: 100%;
.title {
text-align: left;
font-size: 0.05rem;
color: #9fc5e4;
padding-left: 0.1rem;
}
.percent {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.18rem;
margin-top: 0.5vh;
}
.percent :nth-child(1) {
color: #9ac0de;
margin-left: 0.1rem;
}
.percent :nth-child(2) {
font-size: 0.16rem;
color: #38e5a5;
position: relative;
margin-right: 0.3rem;
.triangle-up {
position: absolute;
top: 0;
width: 0;
height: 0;
border-left: 0.2rem solid transparent;
border-right: 0.2rem solid transparent;
border-bottom: 0.4rem solid #38e5a5;
margin-top: 0.5vh;
}
}
}
.Mybutton {
margin: 5vh auto;
}
style>
二、创建guangzhou.json文件(代码行数太长这里不贴出来了,大家自己动动手) 文件下载地址:
广州市地图json文件
记得选能显示具体到镇区的json文件。
三、创建index.ts(存放静态数据文件)
// 广州地图各类型指数数据
import gzMapData from './gzMap-data'
//广州地图各类型指数数据
export default {
...gzMapData
}
四、创建gzMap-data.ts(tooltip提示框中的图表数据文件)
export default {
// 指数1,只供参考数据结构格式,数据内容是随便写的,无任何意义
dataType1: [
{ name: "荔湾区", dataList: [[5,5], [10,10], [8,8]], percent: 88, Increase: 5, checked: false },
{ name: "越秀区", dataList: [[5,5], [10,10], [5,5]], percent: 85, Increase: 1, checked: false },
{ name: "海珠区", dataList: [[5,5], [10,10], [5,5]], percent: 70, Increase: 9, checked: false },
{ name: "天河区", dataList: [[5,5], [10,10], [12,12]], percent: 88, Increase: 3, checked: false },
{ name: "白云区", dataList: [[5,5], [10,10], [5,5]], percent: 50, Increase: 3, checked: false },
{ name: "黄埔区", dataList: [[5,5], [10,10], [5,5]], percent: 66, Increase: 4, checked: false },
{ name: "番禺区", dataList: [[5,5], [10,10], [9,9]], percent: 50, Increase: 8, checked: false },
{ name: "花都区", dataList: [[5,5], [10,10], [5,5]], percent: 50, Increase: 1, checked: false },
{ name: "南沙区", dataList: [[5,5], [10,10], [7,5]], percent: 50, Increase: 5, checked: false },
{ name: "从化区", dataList: [[5,5], [10,10], [5,5]], percent: 70, Increase: 3, checked: false },
{ name: "增城区", dataList: [[5,5], [10,10], [6,5]], percent: 50, Increase: 7, checked: false },
],
}
五、创建gzMapData1.ts(tooltip提示框中的图表配置文件)
import echarts from "echarts";
export default {
//数据图表配置(指数1),根据需要引入不同配置,这些很简单,直接去echarts官网找一个
option_gzMapType: {
grid: {
top: "3%",
width: "100%",
height: "50%",
left: 0,
bottom: 0
},
legend: {
data: ["产业A", "产业B"],
icon: "circle",
itemWidth: 8,
itemHeight: 8,
bottom: 0,
top: 15,
textStyle: {
color: "rgba(150, 245, 246, 1)",
fontSize: 6
}
},
xAxis: {
type: "value",
max: 25,
axisLabel: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
show: false
}
},
yAxis: {
type: "category",
axisLine: {
show: false
}
},
series: [
{
type: "bar",
barWidth: "40%",
name: "产业A",
stack: "one",
itemStyle: {
color: "RGBA(255,205,67)"
},
data: [
{
value: 4,
itemStyle: {
color: "RGBA(196, 255, 255, 1)"
}
},
{
value: 4,
itemStyle: {
color: "RGBA(255,205,67)"
}
}
]
},
{
type: "bar",
name: "产业B",
itemStyle: {
color: "RGBA(221,79,66)"
},
stack: "one",
data: [
{
value: 8,
itemStyle: {
color: "RGBA(75,139,244)"
}
},
{
value: 8,
itemStyle: {
color: "RGBA(221,79,66)"
}
}
]
},
{
type: "bar",
name: "产业C",
itemStyle: {
color: "RGBA(75,139,244)"
},
stack: "one",
data: [
{
value: 8,
itemStyle: {
color: "RGBA(221,79,66)"
}
},
{
value: 8,
itemStyle: {
color: "RGBA(75,139,244)"
}
}
]
}
]
},
}
功能的实现就差不多介绍完了,这里为了简单方便又快速地向大家介绍,就只介绍配置了一种tooltip层的配置图表,大家根据自己的需求可往里面加入更多元素。其中的地图区域被鼠标选中或者停留时显示亮高以及设置两层地图突出一个层次感等这些效果,大家可以自己研究一下echarts的配置文档,博主也是一步步摸爬滚打过来的,如果有什么说的不对,请指出来哈哈!
如果这个项目对你有帮助或者感兴趣,记得帮忙点个赞呀,如果有什么问题也可以私信留言。