地图下钻的独立组件,引入即用
在echart地图上踩了太多坑了,记录下吧
<CityMap :list="mapList" @params="changeParams" />
// 地图标点
let mapList = [
{
FarmID: "337207bb-5abe-42ea-949c-e034a3ae6377",
FarmName: "优然牧场一场",
Long: 119.23944,
Lati: 34.324724,
Admin: "小王",
Tel: "",
Livestock: 7660,
Address: "",
},
];
let changeParams = (val: any) => {
console.log("地图会传的数据:", val);
};
<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 {
ref,
onMounted,
reactive,
Ref,
onUnmounted,
nextTick,
watch,
} from "vue";
import axios from "axios";
import { mapScatter } from "@/utils/youran";
// 本地测试用的地图json数据
const mapDatas = require("./320700_full.json");
const mapDatas2 = require("./320723.json");
const echartsRef: Ref = ref(null);
let notAllowed = ref<Boolean>(false);
let timeFn: any = null;
let myChart: any = null;
// 所有地图
let AllMap = reactive([
{
prefix: "",
adcode: "",
name: "",
},
]);
onMounted(() => {
initChart();
});
onUnmounted(() => {});
// 获取地图--和域名一样的地图(上线上上去,防跨域)
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;
}
// 地图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;
}
// 向外传值
const emit = defineEmits(["params"]);
function returnParams(params: object) {
emit("params", params);
}
const props = defineProps({
funType: {
type: Object,
default: {},
},
list: {
type: Array,
default: [],
},
});
//各省份的数据--本地图是标点图,所以不需要了,废弃了这里
let allData: any = reactive([]);
function initMapData() {
// Api.getMapData({
// funType: props.funType.module,
// mapData: JSON.stringify(AllMap),
// range: props.funType.range,
// }).then((res) => {
// allData.length = 0;
// allData.push(
// ...[
// {
// prefix: "district",
// adcode: "320703",
// name: "连云区",
// value: "0",
// },
// {
// prefix: "district",
// adcode: "320707",
// name: "赣榆区",
// value: "0",
// },
// {
// prefix: "district",
// adcode: "320722",
// name: "东海县",
// value: "0",
// },
// {
// prefix: "district",
// adcode: "320706",
// name: "海州区",
// value: "0",
// },
// {
// prefix: "district",
// adcode: "320723",
// name: "灌云县",
// value: "0",
// },
// {
// prefix: "district",
// adcode: "320724",
// name: "灌南县",
// value: "0",
// },
// ]
// );
// console.log("AllMap", AllMap);
// console.log("各省份的数据allData", allData);
setTimeout(() => {
setOption();
}, 1);
// });
}
watch(
[() => props, AllMap],
(val, val2) => {
initMapData();
},
{
deep: true,
}
);
// 激活地图栈
// 当前激活地图
let defaultMap = reactive({
prefix: "",
adcode: "",
name: "",
});
// 初始化地图
initData();
function initData() {
defaultMap = {
prefix: "city",
adcode: "320700",
name: "连云港市",
};
}
/**
获取对应的json地图数据,然后向echarts注册该区域的地图,最后加载地图信息
@params {String} mapCode:json数据的地址
@params {String} name: 地图名称
*/
let mapStack: any[] = [];
function loadMap() {
if (mapStack.length == 0) {
mapStack.push(defaultMap);
}
let mapData = GetMapGeoJson2("320700", "city") || mapDatas;
if (mapStack.length > 1) {
mapData = GetMapGeoJson2(
mapStack[mapStack.length - 1].adcode,
mapStack[mapStack.length - 1].prefix
);
}
AllMap = [
{
prefix: "district",
adcode: "320703",
name: "连云区",
},
{
prefix: "district",
adcode: "320707",
name: "赣榆区",
},
{
prefix: "district",
adcode: "320722",
name: "东海县",
},
{
prefix: "district",
adcode: "320706",
name: "海州区",
},
{
prefix: "district",
adcode: "320723",
name: "灌云县",
},
{
prefix: "district",
adcode: "320724",
name: "灌南县",
},
];
// 注册当前激活地图
// console.log("激活地图", mapStack[mapStack.length - 1].name, mapData);
axios.get(mapData).then((geoJson: any) => {
echarts.registerMap(mapStack[mapStack.length - 1].name, geoJson.data);
nextTick(() => {
setOption();
});
});
}
function setOption() {
let option = {
tooltip: {
show: true,
className: "CityMapChartTooltipBg",
formatter: (params: any) => {
if (params.componentSubType === "scatter") return params.name;
},
},
geo: {
map: mapStack[mapStack.length - 1].name || "连云港市",
itemStyle: {
normal: {
areaColor: `#10359b`,
borderColor: `#fff`,
borderWidth: 1,
shadowColor: `#94d9ff`,
shadowOffsetX: -4,
shadowOffsetY: 8,
shadowBlur: 1,
},
emphasis: {
label: {
show: false,
},
},
},
},
xAxis: [],
yAxis: [],
series: [
{
name: "MAP",
type: "map",
map: mapStack[mapStack.length - 1].name || "连云港市",
selectedMode: "false", //是否允许选中多个区域
label: {
normal: {
show: true,
textStyle: {
color: "#fff",
fontSize: 16,
fontFamily: "SourceHanSansCN",
},
},
},
itemStyle: {
areaColor: "#0f18c2",
borderColor: "#6becf5",
borderWidth: 1.5,
emphasis: {
show: true,
areaColor: "#55ade8", // 鼠标悬浮地图面的颜色
shadowColor: "#94d9ff",
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 5,
label: {
show: true,
textStyle: {
color: "#fff",
fontSize: 16,
fontFamily: "SourceHanSansCN",
},
},
},
},
// data: allData,//各省的数据,鼠标放上显示,现在是标点图所以不显示
},
],
};
addScatter(option);
myChart.setOption(option);
}
// 加牧场坐标点
function addScatter(option: any) {
let dataList: any = [];
if (props.list.length > 0) {
props.list.forEach((item: any) => {
let name = `
${item.FarmName || ""}:
${item.Livestock || 0}头
负责人:
${item.Admin || ""}
地址:
${item.address || ""}
`;
dataList.push({
name: name,
value: [item.Long, item.Lati],
});
});
}
option.series.push({
type: "scatter",
coordinateSystem: "geo",
symbol: "image://" + mapScatter,
symbolSize: [66, 36],
itemStyle: {
normal: {
color: "#1cedd4",
shadowBlur: 10,
shadowColor: "#333",
},
},
zlevel: 2,
data: dataList,
});
}
let initChart = () => {
if (!myChart) {
myChart = echarts.init(echartsRef.value);
}
loadMap();
//单击切换到省级地图,当mapCode有值,说明可以切换到下级地图
myChart.on("click", (params: any) => {
notAllowed.value = true;
clearTimeout(timeFn);
//由于单击事件和双击事件冲突,故单击的响应事件延迟250毫秒执行
timeFn = setTimeout(() => {
let clickMap = AllMap.find((item) => item.name == params.name);
// if (!clickMap) {
// alert("无此区域地图显示");
// return;
// }
// 向外传参
returnParams(clickMap || {});
// 只存3级
if (mapStack.length < 3) {
mapStack.push(clickMap);
}
loadMap();
}, 250);
});
// 绑定双击事件,返回全国地图
myChart.on("dblclick", (params: any) => {
//当双击事件发生时,清除单击事件,仅响应双击事件
clearTimeout(timeFn);
// 以防初始化双击丢栈
if (mapStack.length > 1) {
mapStack.pop();
}
let res = mapStack[mapStack.length - 1];
//返回参数
returnParams(res);
loadMap();
});
};
let backMap = () => {
notAllowed.value = false; //鼠标放上去的禁用状态
//当双击事件发生时,清除单击事件,仅响应双击事件
clearTimeout(timeFn);
// 取当前默认地图
returnParams(defaultMap);
mapStack.length = 0;
// 地图栈 最后一个
loadMap();
};
</script>
<style lang="less" scoped>
.cityMap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.backMap {
position: absolute;
top: 0;
left: 40px;
border: none;
z-index: 9;
span {
display: block;
font-size: 12px;
border-radius: 7px;
background-color: #06bcec;
padding: 4px 6px;
color: #fff;
cursor: pointer;
}
&:focus {
outline: none;
}
&:hover {
background-size: 100% 100%;
span {
color: #ffffff;
}
}
&.notAllowed {
cursor: not-allowed;
}
}
.tradeIn-cattle-map {
width: 90%;
height: 90%;
}
}
</style>