梳理清楚的echarts地图下钻和标点信息组件
效果图
说明
默认数据没有就是全国地图,
$bus.off("onresize")
是地图容器变化刷新地图适配的,可以你们自己写
getEchartsFontSize
是适配字体大小的,getEchartsFontSize(0.12) === 12
mapScatter
是base64图片就是图上那个标点的底图
GetMapGeoJson
是获取地图json的,这里的是我公司的,可以用阿里云的代替
还有不明白的可以看是之前的文章,echart5.x地图下钻和地图标点(vue3+ts)
// 地图2--阿里云地图
function GetMapGeoJson2(cityCN: string, citylevel: string) {
var uploadedDataURL = "";
if (citylevel == "china") {
//全国地图
return "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json";
}
if (citylevel != "district" && (cityCN + "").substring(4) != "00")
citylevel = "district";
if (citylevel == "district") {
uploadedDataURL =
"https://geo.datav.aliyun.com/areas_v3/bound/" + cityCN + ".json";
} else if (citylevel == "city") {
uploadedDataURL =
"https://geo.datav.aliyun.com/areas_v3/bound/" + cityCN + "_full.json";
} else {
uploadedDataURL =
"https://geo.datav.aliyun.com/areas_v3/bound/" + cityCN + "_full.json";
}
return uploadedDataURL;
}
使用
<!-- :defaultMap="defaultMap" -->
<mapChart :list="scatterList" @changeMapData="changeMapData" />
import mapChart from "@/views/universal-visuali/components/charts/map/mapChart.vue";
// 默认的地图数据
let defaultMap = {
// prefix: "china",
// adcode: "110000",
// name: "全国",
prefix: "province",
adcode: "150000",
name: "内蒙古自治区",
};
// 标点
let scatterList = ref<any>([
{
FarmName: "养殖场一场",
Admin: "小王",
Livestock: 10000,
Address: "江苏省连云港市",
Long: 109.494324,
Lati: 19.598813,
},
{
FarmName: "向东养殖户",
Admin: "向东",
Livestock: 0,
Address: "长虹科技大厦",
Long: 113.964139785699,
Lati: 22.544018837551,
},
{
FarmName: "牧养殖种植合作社",
Admin: "马胜军",
Livestock: 91,
Address: "广东省云浮市新兴县",
Long: 112.231496832189,
Lati: 22.701890082606,
},
{
FarmName: "苏垦牧场",
Admin: "小刘",
Livestock: 8080,
Address: "江苏省连云港连云区农场",
Long: 119.43188,
Lati: 34.62367,
},
]);
const changeMapData = (info: any) => {
console.log(info);
};
mapChart 组件代码
<template>
<div class="cityMap">
<div class="backMap" :class="{ notAllowed: !notAllowed }" @click="backMap">
<span>返回</span>
</div>
<div class="tradeIn-cattle-map" ref="echartsRef"></div>
</div>
</template>
<script setup lang="ts">
/**
* 省市区-地图下钻
*/
import * as echarts from "echarts";
import { ElMessage } from "element-plus";
import {
ref,
onMounted,
reactive,
Ref,
onUnmounted,
nextTick,
watch,
} from "vue";
import axios from "axios";
import { getEchartsFontSize } from "@/utils/common";
import { mapScatter } from "@/utils/youran";
import $bus from "@/utils/bus";
const props = defineProps({
list: {
type: Array,
default: [],
},
defaultMap: {
type: Object,
default: {
prefix: "china",
adcode: "110000",
name: "全国",
},
},
});
// 坐标点
let scatterDataList = ref<any>([]);
// dom和注册的echart实例
let echartsRef: Ref = ref(null);
let myChart: any = null;
// 没有上一级了,和点击的防抖
let notAllowed = ref<Boolean>(false);
let timeFn: any = null;
// 当前激活地图
let defaultMap = ref<any>({
prefix: "china",
adcode: "110000",
name: "全国",
});
if (props.defaultMap) {
defaultMap.value = JSON.parse(JSON.stringify(props.defaultMap));
}
// 地图栈
let mapStack: any[] = [];
// 所有下级地图,下钻用
let AllMap = ref<any[]>([]);
// 向外传值
const emit = defineEmits(["changeMapData"]);
onMounted(() => {
// 如果容器大小变化
$bus.on("onresize", () => {
initChart();
myChart.resize();
});
initChart();
});
onUnmounted(() => {
$bus.off("onresize");
if (timeFn) {
clearTimeout(timeFn);
}
});
watch(
() => props,
(val) => {
nextTick(() => {
mapStack = []
if (props.defaultMap) {
defaultMap.value = JSON.parse(JSON.stringify(props.defaultMap));
}
initChart();
});
},
{
deep: true,
}
);
// 获取地图--和域名一样的地图(上线上上去,防跨域)
function GetMapGeoJson(cityCN: string, citylevel: string) {
var uploadedDataURL = "";
if (citylevel == "china") {
//全国地图
return "/YooHooMIS/Scripts/echarts/china/100000_full.json";
}
if (citylevel != "district" && (cityCN + "").substring(4) != "00")
citylevel = "district";
if (citylevel == "district") {
uploadedDataURL =
"/YooHooMIS/Scripts/echarts/china/district/" + cityCN + ".json";
} else if (citylevel == "city") {
uploadedDataURL =
"/YooHooMIS/Scripts/echarts/china/city/" + cityCN + "_full.json";
} else {
uploadedDataURL =
"/YooHooMIS/Scripts/echarts/china/province/" + cityCN + "_full.json";
}
return uploadedDataURL;
}
// 创建地图实例
let initChart = () => {
if (!myChart) {
myChart = echarts.init(echartsRef.value);
}
loadMap();
};
// 注册地图
function loadMap() {
// 当前地图
if (mapStack.length <= 0) {
mapStack.push(defaultMap.value);
} else {
defaultMap.value = mapStack[mapStack.length - 1];
}
console.log(defaultMap.value, props.defaultMap, mapStack);
let mapData = GetMapGeoJson(defaultMap.value.adcode, defaultMap.value.prefix);
// 注册当前激活地图
axios
.get(mapData)
.then((geoJson: any) => {
AllMap.value = geoJson.data.features || [];
echarts.registerMap(defaultMap.value.name, geoJson.data);
setOption();
})
.catch((err: any) => {
// 接口404没地图数据的情况
ElMessage.error(`无${defaultMap.value.name}的地图数据`);
mapStack.pop();
defaultMap.value = mapStack[mapStack.length - 1];
if (mapStack && mapStack.length <= 1) {
notAllowed.value = false;
}
});
}
// 加牧场坐标点
function addScatter() {
scatterDataList.value = [];
if (props.list && props.list.length > 0) {
props.list.forEach((item: any) => {
let name = `
<div class="CityMapChartTooltipBgBox">
<div class="list">
<div class="item">
<span>${item.FarmName || ""}:</span>
<span>${item.Livestock || 0}头</span>
</div>
<div class="item">
<span>负责人:</span>
<span>${item.Admin || ""}</span>
</div>
<div class="item">
<span>地址:</span>
<span>${item.Address || ""}</span>
</div>
</div>
</div>`;
scatterDataList.value.push({
name: name,
value: [item.Long, item.Lati],
});
});
}
}
// 创建地图
function setOption() {
addScatter();
let option = {
tooltip: {
show: true,
className: "CityMapChartTooltipBg",
formatter: (params: any) => {
if (params.componentSubType === "scatter") return params.name;
},
},
geo: {
show: false,
map: defaultMap.value.name || "全国",
},
series: [
{
name: "MAP",
type: "map",
map: defaultMap.value.name || "全国",
selectedMode: "false", //是否允许选中多个区域
aspectScale: 0.75,
zoom: 1.2,
zlevel: 1,
label: {
show: true,
textStyle: {
color: "#fff",
// fontSize: getEchartsFontSize(0.14),
fontFamily: "YouSheBiaoTiHei",
},
},
itemStyle: {
areaColor: new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{
offset: 0,
color: `#06236d`,
},
{
offset: 1,
color: `#1d46a1`,
},
]),
borderColor: "#6789d7",
borderWidth: getEchartsFontSize(0.01),
shadowColor: "#0156f2",
shadowOffsetX: -getEchartsFontSize(0.03),
shadowOffsetY: getEchartsFontSize(0.03),
shadowBlur: getEchartsFontSize(0.02),
emphasis: {
show: true,
areaColor: "#182e8f", // 鼠标悬浮地图面的颜色
borderColor: "#fff",
borderWidth: getEchartsFontSize(0.02),
label: {
show: true,
textStyle: {
color: "#fff",
fontSize: getEchartsFontSize(0.16),
fontFamily: "YouSheBiaoTiHei",
},
},
},
},
data: [],
},
{
type: "scatter",
coordinateSystem: "geo",
symbol: "image://" + mapScatter,
symbolSize: [getEchartsFontSize(0.66), getEchartsFontSize(0.36)],
itemStyle: {
color: "#1cedd4",
shadowBlur: getEchartsFontSize(0.1),
shadowColor: "#333",
},
zlevel: 200,
data: scatterDataList.value || [],
},
],
};
// 地图数据的关系setOption有时会报错,暂时无解
myChart.setOption(option);
mapChartAddClick();
}
// 加点击事件
function mapChartAddClick() {
// 清空之前的点击事件
myChart.off("click");
myChart.on("click", (params: any) => {
if (timeFn) {
clearTimeout(timeFn);
}
//由于单击事件和双击事件冲突,故单击的响应事件延迟250毫秒执行
timeFn = setTimeout(() => {
// 现在和点的是一个阻止
if (params.name === mapStack[mapStack.length - 1].name) {
return;
}
if (params.seriesType == "scatter") {
// 点标点逻辑,传递标点信息
emit("changeMapData", props.list[params.dataIndex]);
} else {
// 地图下钻逻辑
if (AllMap.value && AllMap.value.length > 0) {
let clickMap = AllMap.value.find(
(item) => item.properties.name === params.name
);
if (!clickMap) {
ElMessage.warning("无此区域地图显示");
return;
}
mapStack.push({
prefix: clickMap.properties.level,
adcode: clickMap.properties.adcode,
name: clickMap.properties.name,
});
notAllowed.value = true;
loadMap();
} else {
ElMessage.warning("无下级地图数据");
}
}
}, 250);
});
// 绑定双击事件,返回
// myChart.on("dblclick", (params: any) => {
// backMap();
// });
}
// 返回上一级
let backMap = () => {
// 当双击事件发生时,清除单击事件,仅响应双击事件
if (timeFn) {
clearTimeout(timeFn);
}
// 删最后一个,跳上一个
if (mapStack && mapStack.length > 1) {
mapStack.pop();
loadMap();
}
// 鼠标放上去的禁用状态
if (mapStack && mapStack.length <= 1) {
notAllowed.value = false;
}
};
</script>
<style lang="less" scoped>
.cityMap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.backMap {
position: absolute;
top: 27px;
left: 40px;
border: none;
z-index: 9;
cursor: pointer;
// width: 123px;
// height: 44px;
// background-image: url("../assets/common/top_icon_back_default.png");
// background-size: 100% 100%;
// padding-left: 50px;
// padding-top: 10px;
span {
display: block;
font-size: 12px;
// margin-left: 40px;
border-radius: 7px;
background-color: #1c4fb1;
padding: 4px 6px;
color: #fff;
}
&:focus {
outline: none;
}
&:hover {
// opacity: 0.93;
// background-image: url("../assets/common/top_icon_back_select.png");
background-size: 100% 100%;
span {
color: #ffffff;
}
}
&.notAllowed {
cursor: not-allowed;
}
}
.tradeIn-cattle-map {
// height: 600px;
width: 100%;
height: 100%;
// margin-top: 50px;
}
}
</style>
原文地址:https://blog.csdn.net/qq_43217258/article/details/139295931
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!