<template>
|
<div id="map" :style="{ width: props.width, height: props.height }" ref="mapRef"></div>
|
</template>
|
<script setup lang="ts">
|
// import { reactive, ref, watch, toRefs, onMounted } from "vue";
|
import axios from "axios";
|
import * as echarts from "echarts";
|
import { options } from "./static/map";
|
import chinaJSON from "./static/china.json";
|
const CK = "👉";
|
|
type Resolve = (list: any[]) => void;
|
// interface mapType {
|
// width: string;
|
// height: string;
|
// lazyLoad?: (node: any, resolve: Resolve) => void;
|
// }
|
const props = withDefaults(defineProps<{ width: string; height: string; lazyLoad?: (node: any, resolve: Resolve) => void }>(), {
|
width: "600px",
|
height: "600px",
|
azyLoad: undefined,
|
});
|
// const props = defineProps<mapType>();
|
|
const mapRef = ref<HTMLElement>();
|
|
const state = reactive({
|
myChart: undefined as unknown as echarts.EChartsType,
|
});
|
let geoJson: any = {};
|
let geoName: string = "中国";
|
/**
|
* 数据加载记录
|
*/
|
const geoList = ref([
|
{
|
name: "中国",
|
code: "100000",
|
},
|
]);
|
onMounted(() => {
|
init();
|
GetGeoJsonData().then((res) => {
|
geoJson = res.data;
|
if (props.lazyLoad) {
|
// console.log("第一次加载");
|
props.lazyLoad({ label: "", value: "" }, resolve);
|
} else {
|
applyData();
|
}
|
});
|
});
|
|
/**
|
* 初始化
|
*/
|
const init = () => {
|
state.myChart = echarts.init(mapRef.value as HTMLElement);
|
state.myChart.on("click", (params: any) => {
|
// console.log("sssssss", params);
|
state.myChart.showLoading({
|
text: "loading",
|
color: "rgba(147, 235, 248, 1)",
|
textColor: "#000",
|
maskColor: "rgba(255,255,255,0.4)",
|
zlevel: 0,
|
});
|
//注册点击事件
|
if (params.componentType === "title") {
|
//点击标题回退上一级
|
geoList.value.pop();
|
GetGeoJsonData().then((res) => {
|
geoJson = res.data;
|
if (props.lazyLoad) {
|
props.lazyLoad({ label: geoList.value[geoList.value.length - 1].name, value: "" }, resolve);
|
} else {
|
applyData();
|
}
|
});
|
state.myChart.hideLoading();
|
return false;
|
}
|
|
geoJson.features.forEach((el: any) => {
|
//过滤找到name相同的code
|
if (el.properties.name === params.name) {
|
if (el.properties.childrenNum > 0) {
|
//存在下级区域 el.properties.adcode
|
geoName = params.name;
|
geoList.value.push({
|
name: el.properties.name,
|
code: el.properties.adcode,
|
});
|
GetGeoJsonData().then((res) => {
|
geoJson = res.data;
|
if (props.lazyLoad) {
|
props.lazyLoad({ label: geoName, value: "" }, resolve);
|
} else {
|
applyData();
|
}
|
});
|
} else {
|
state.myChart.hideLoading();
|
}
|
}
|
});
|
});
|
// /* 注册标题点击回退事件 */
|
// state.myChart.getZr().on("click", (params: any) => {
|
// // console.log(params);
|
// // 设置限制条件,确保只有点击的节点为title时才生效
|
// if (params.target && params.target.componentType === "title") {
|
// console.log("有限点击==>");
|
// }
|
// });
|
};
|
|
/**
|
* 渲染数据
|
*/
|
const applyData = (list: any[] = []) => {
|
// console.log("========>", list);
|
let str = JSON.stringify(options);
|
let option = JSON.parse(str);
|
echarts.registerMap(geoName, geoJson as any); //注册可用的地图
|
/** 设置地图回退标题 */
|
let len = geoList.value.length;
|
if (len > 1) {
|
let obj = geoList.value[len - 1];
|
option.title.push({
|
text: CK + "上一级",
|
show: true,
|
left: 150,
|
textStyle: {
|
color: "#006edd",
|
},
|
triggerEvent: true, // 是否触发事件
|
});
|
geoName = obj.name;
|
} else {
|
geoName = geoList.value[0].name;
|
}
|
option.geo.map = geoName;
|
option.series[0].name = geoName;
|
option.series[0].data = list;
|
state.myChart!.setOption(option, true, false);
|
state.myChart.hideLoading();
|
};
|
|
/**
|
* 数据加载
|
*/
|
const resolve = (list: any[]) => {
|
applyData(list);
|
};
|
|
/**
|
* 获取地图数据
|
*/
|
const GetGeoJsonData = () => {
|
let len = geoList.value.length;
|
let code = geoList.value[len - 1]?.code;
|
let baseUrl = `https://geo.datav.aliyun.com/areas_v3/bound/${code}_full.json`;
|
// if (code) {
|
// url = `${baseUrl}${code}_full.json`;
|
// } else {
|
// url = `${baseUrl}${geoList.value[0].url}.json`;
|
// geoName = "china";
|
// }
|
return axios.get(baseUrl);
|
};
|
|
/**
|
* 重新渲染
|
* @param type true 回到首页重新加载 false 当前数据源加载
|
*/
|
const againApply = (type: boolean) => {
|
if (type) {
|
geoList.value.splice(1, geoList.value.length - 1);
|
}
|
// console.log("======>", geoList.value);
|
GetGeoJsonData().then((res) => {
|
geoJson = res.data;
|
if (props.lazyLoad) {
|
// console.log("第一次加载");
|
props.lazyLoad({ label: type ? "" : geoList.value[geoList.value.length - 1].name, value: "" }, resolve);
|
} else {
|
applyData();
|
}
|
});
|
};
|
|
defineExpose({
|
againApply,
|
mapRef,
|
});
|
</script>
|
|
<style lang="scss" scoped></style>
|