沈丘营商办后台前端项目
346149741
2024-06-18 9fb6a0ff49c2af567be2e3adaf93c4c301b3f102
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<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>