feat: 地图模块
This commit is contained in:
parent
c1f5e00dd5
commit
bcedcb34dd
|
@ -0,0 +1,180 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from "vue";
|
||||
import { centerMap, GETNOBASE } from "@/api";
|
||||
import { registerMap, getMap } from "echarts/core";
|
||||
import { optionHandle, regionCodes } from "./center.map";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import type { MapdataType } from "./center.map";
|
||||
|
||||
const option = ref({});
|
||||
const code = ref("china"); //china 代表中国 其他地市是行政编码
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
// 结束数值
|
||||
title: number | string;
|
||||
}>(),
|
||||
{
|
||||
title: "地图",
|
||||
}
|
||||
);
|
||||
|
||||
const dataSetHandle = async (regionCode: string, list: object[]) => {
|
||||
const geojson: any = await getGeojson(regionCode);
|
||||
let cityCenter: any = {};
|
||||
let mapData: MapdataType[] = [];
|
||||
//获取当前地图每块行政区中心点
|
||||
geojson.features.forEach((element: any) => {
|
||||
cityCenter[element.properties.name] =
|
||||
element.properties.centroid || element.properties.center;
|
||||
});
|
||||
//当前中心点如果有此条数据中心点则赋值x,y当然这个x,y也可以后端返回进行大点,前端省去多行代码
|
||||
list.forEach((item: any) => {
|
||||
if (cityCenter[item.name]) {
|
||||
mapData.push({
|
||||
name: item.name,
|
||||
value: cityCenter[item.name].concat(item.value),
|
||||
});
|
||||
}
|
||||
});
|
||||
await nextTick();
|
||||
|
||||
option.value = optionHandle(regionCode, list, mapData);
|
||||
};
|
||||
|
||||
const getData = async (regionCode: string) => {
|
||||
// 强制使用'china'作为regionCode,确保只显示全国地图
|
||||
centerMap({ regionCode: 'china' })
|
||||
.then((res) => {
|
||||
console.log("中上--设备分布", res);
|
||||
if (res.success) {
|
||||
dataSetHandle('china', res.data.dataList);
|
||||
} else {
|
||||
ElMessage.error(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err);
|
||||
});
|
||||
};
|
||||
const getGeojson = (regionCode: string) => {
|
||||
return new Promise<boolean>(async (resolve) => {
|
||||
let mapjson = getMap(regionCode);
|
||||
if (mapjson) {
|
||||
mapjson = mapjson.geoJSON;
|
||||
resolve(mapjson);
|
||||
} else {
|
||||
mapjson = await GETNOBASE(`./map-geojson/${regionCode}.json`).then(
|
||||
(data) => data
|
||||
);
|
||||
code.value = regionCode;
|
||||
registerMap(regionCode, {
|
||||
geoJSON: mapjson as any,
|
||||
specialAreas: {},
|
||||
});
|
||||
resolve(mapjson);
|
||||
}
|
||||
});
|
||||
};
|
||||
getData(code.value);
|
||||
|
||||
// 移除地图点击切换功能,只显示全国地图
|
||||
// const mapClick = (params: any) => {
|
||||
// // console.log(params);
|
||||
// let xzqData = regionCodes[params.name];
|
||||
// if (xzqData) {
|
||||
// getData(xzqData.adcode);
|
||||
// } else {
|
||||
// window["$message"].warning("暂无下级地市");
|
||||
// }
|
||||
// };
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="centermap">
|
||||
<div class="mapwrap">
|
||||
<!-- <div class="quanguo" @click="getData('china')" v-if="code !== 'china'">
|
||||
中国
|
||||
</div> -->
|
||||
<v-chart
|
||||
class="chart"
|
||||
:option="option"
|
||||
ref="centerMapRef"
|
||||
v-if="JSON.stringify(option) != '{}'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.centermap {
|
||||
margin-bottom: 30px;
|
||||
background: #fff;
|
||||
|
||||
.maptitle {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-top: 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.titletext {
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 6px;
|
||||
background: linear-gradient(
|
||||
92deg,
|
||||
#0072ff 0%,
|
||||
#00eaff 48.8525390625%,
|
||||
#01aaff 100%
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.zuo,
|
||||
.you {
|
||||
background-size: 100% 100%;
|
||||
width: 29px;
|
||||
height: 20px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.zuo {
|
||||
background: url("@/assets/img/xiezuo.png") no-repeat;
|
||||
}
|
||||
|
||||
.you {
|
||||
background: url("@/assets/img/xieyou.png") no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.mapwrap {
|
||||
height: 402px;
|
||||
width: 100%;
|
||||
// padding: 0 0 10px 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.quanguo {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: -46px;
|
||||
width: 80px;
|
||||
height: 28px;
|
||||
border: 1px solid #00eded;
|
||||
border-radius: 10px;
|
||||
color: #00f7f6;
|
||||
text-align: center;
|
||||
line-height: 26px;
|
||||
letter-spacing: 6px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 4px rgba(0, 237, 237, 0.5),
|
||||
0 0 6px rgba(0, 237, 237, 0.4);
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,381 @@
|
|||
|
||||
|
||||
//mapData数据结构
|
||||
export interface MapdataType {
|
||||
name: string;
|
||||
value: [number, number, number]; //x,y,value 第一个x 第二个y 第三个value
|
||||
}
|
||||
export const optionHandle = (regionCode: string,
|
||||
list: object[],
|
||||
mapData: MapdataType[]) => {
|
||||
let top = 45;
|
||||
let zoom = ["china"].includes(regionCode) ? 1.05 : 1;
|
||||
return {
|
||||
backgroundColor: "rgba(0,0,0,0)",
|
||||
tooltip: {
|
||||
show: false,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
visualMap: {
|
||||
seriesIndex:0,
|
||||
show: false, // 隐藏visualMap控件
|
||||
pieces: [
|
||||
{ gte: 1000, label: "1000个以上" }, // 不指定 max,表示 max 为无限大(Infinity)。
|
||||
{ gte: 600, lte: 999, label: "600-999个" },
|
||||
{ gte: 200, lte: 599, label: "200-599个" },
|
||||
{ gte: 50, lte: 199, label: "49-199个" },
|
||||
{ gte: 10, lte: 49, label: "10-49个" },
|
||||
{ lte: 9, label: "1-9个" }, // 不指定 min,表示 min 为无限大(-Infinity)。
|
||||
],
|
||||
inRange: {
|
||||
// 设置地图颜色为#0091fe
|
||||
color: ["#0091fe"]
|
||||
},
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
geo: {
|
||||
map: regionCode,
|
||||
roam: false,
|
||||
selectedMode: false, //是否允许选中多个区域
|
||||
zoom: zoom,
|
||||
top: top,
|
||||
// aspectScale: 0.78,
|
||||
show: false,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "MAP",
|
||||
type: "map",
|
||||
map: regionCode,
|
||||
// aspectScale: 0.78,
|
||||
data: list,
|
||||
// data: [1,100],
|
||||
selectedMode: false, //是否允许选中多个区域
|
||||
zoom: zoom,
|
||||
geoIndex: 1,
|
||||
top: top,
|
||||
tooltip: {
|
||||
show: true,
|
||||
formatter: function (params: any) {
|
||||
if (params.data) {
|
||||
return params.name + ":" + params.data["value"];
|
||||
} else {
|
||||
return params.name;
|
||||
}
|
||||
},
|
||||
backgroundColor: "rgba(0,0,0,.6)",
|
||||
borderColor: "rgba(0, 145, 254, 0.8)",
|
||||
textStyle: {
|
||||
color: "#FFF",
|
||||
},
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
color: "#000",
|
||||
// position: [-10, 0],
|
||||
formatter: function (val: any) {
|
||||
// console.log(val)
|
||||
if (val.data !== undefined) {
|
||||
return val.name.slice(0, 2);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
rich: {},
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
areaColor: {
|
||||
type: "radial",
|
||||
x: 0.5,
|
||||
y: 0.5,
|
||||
r: 0.8,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(0, 145, 254, 0.2)", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(0, 145, 254, 0.8)", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
globalCoord: false,
|
||||
},
|
||||
borderWidth: 1,
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
borderColor: "rgba(0, 145, 254, 0.8)",
|
||||
borderWidth: 1,
|
||||
areaColor: {
|
||||
type: "radial",
|
||||
x: 0.5,
|
||||
y: 0.5,
|
||||
r: 0.8,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: "rgba(0, 145, 254, 0.3)", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "rgba(0, 145, 254, 0.5)", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
globalCoord: false,
|
||||
},
|
||||
shadowColor: "rgba(0, 145, 254, 0.3)",
|
||||
shadowOffsetX: -2,
|
||||
shadowOffsetY: 2,
|
||||
shadowBlur: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
data: mapData,
|
||||
type: "effectScatter",
|
||||
coordinateSystem: "geo",
|
||||
symbolSize: function (val: any) {
|
||||
return 4;
|
||||
// return val[2] / 50;
|
||||
},
|
||||
legendHoverLink: true,
|
||||
showEffectOn: "render",
|
||||
rippleEffect: {
|
||||
// period: 4,
|
||||
scale: 6,
|
||||
color: "rgba(255,255,255, 1)",
|
||||
brushType: "fill",
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
formatter: function (params: any) {
|
||||
if (params.data) {
|
||||
return params.name + ":" + params.data["value"][2];
|
||||
} else {
|
||||
return params.name;
|
||||
}
|
||||
},
|
||||
backgroundColor: "rgba(0,0,0,.6)",
|
||||
borderColor: "rgba(0, 145, 254, 0.8)",
|
||||
textStyle: {
|
||||
color: "#FFF",
|
||||
},
|
||||
},
|
||||
label: {
|
||||
formatter: (param: any) => {
|
||||
return param.name.slice(0, 2);
|
||||
},
|
||||
|
||||
fontSize: 11,
|
||||
offset: [0, 2],
|
||||
position: "bottom",
|
||||
textBorderColor: "#fff",
|
||||
textShadowColor: "#000",
|
||||
textShadowBlur: 10,
|
||||
textBorderWidth: 0,
|
||||
color: "#FFF",
|
||||
show: true,
|
||||
},
|
||||
// colorBy: "data",
|
||||
itemStyle: {
|
||||
color: "rgba(255,255,255,1)",
|
||||
borderColor: "rgba(2255,255,255,2)",
|
||||
borderWidth: 4,
|
||||
shadowColor: "#000",
|
||||
shadowBlur: 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
//动画效果
|
||||
// animationDuration: 1000,
|
||||
// animationEasing: 'linear',
|
||||
// animationDurationUpdate: 1000
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export const regionCodes: any = {
|
||||
"中国": {
|
||||
"adcode": "100000",
|
||||
"level": "country",
|
||||
"name": "中华人民共和国"
|
||||
},
|
||||
"新疆维吾尔自治区": {
|
||||
"adcode": "650000",
|
||||
"level": "province",
|
||||
"name": "新疆维吾尔自治区"
|
||||
},
|
||||
"湖北省": {
|
||||
"adcode": "420000",
|
||||
"level": "province",
|
||||
"name": "湖北省"
|
||||
},
|
||||
"辽宁省": {
|
||||
"adcode": "210000",
|
||||
"level": "province",
|
||||
"name": "辽宁省"
|
||||
},
|
||||
"广东省": {
|
||||
"adcode": "440000",
|
||||
"level": "province",
|
||||
"name": "广东省"
|
||||
},
|
||||
"内蒙古自治区": {
|
||||
"adcode": "150000",
|
||||
"level": "province",
|
||||
"name": "内蒙古自治区"
|
||||
},
|
||||
"黑龙江省": {
|
||||
"adcode": "230000",
|
||||
"level": "province",
|
||||
"name": "黑龙江省"
|
||||
},
|
||||
"河南省": {
|
||||
"adcode": "410000",
|
||||
"level": "province",
|
||||
"name": "河南省"
|
||||
},
|
||||
"山东省": {
|
||||
"adcode": "370000",
|
||||
"level": "province",
|
||||
"name": "山东省"
|
||||
},
|
||||
"陕西省": {
|
||||
"adcode": "610000",
|
||||
"level": "province",
|
||||
"name": "陕西省"
|
||||
},
|
||||
"贵州省": {
|
||||
"adcode": "520000",
|
||||
"level": "province",
|
||||
"name": "贵州省"
|
||||
},
|
||||
"上海市": {
|
||||
"adcode": "310000",
|
||||
"level": "province",
|
||||
"name": "上海市"
|
||||
},
|
||||
"重庆市": {
|
||||
"adcode": "500000",
|
||||
"level": "province",
|
||||
"name": "重庆市"
|
||||
},
|
||||
"西藏自治区": {
|
||||
"adcode": "540000",
|
||||
"level": "province",
|
||||
"name": "西藏自治区"
|
||||
},
|
||||
"安徽省": {
|
||||
"adcode": "340000",
|
||||
"level": "province",
|
||||
"name": "安徽省"
|
||||
},
|
||||
"福建省": {
|
||||
"adcode": "350000",
|
||||
"level": "province",
|
||||
"name": "福建省"
|
||||
},
|
||||
"湖南省": {
|
||||
"adcode": "430000",
|
||||
"level": "province",
|
||||
"name": "湖南省"
|
||||
},
|
||||
"海南省": {
|
||||
"adcode": "460000",
|
||||
"level": "province",
|
||||
"name": "海南省"
|
||||
},
|
||||
"江苏省": {
|
||||
"adcode": "320000",
|
||||
"level": "province",
|
||||
"name": "江苏省"
|
||||
},
|
||||
"青海省": {
|
||||
"adcode": "630000",
|
||||
"level": "province",
|
||||
"name": "青海省"
|
||||
},
|
||||
"广西壮族自治区": {
|
||||
"adcode": "450000",
|
||||
"level": "province",
|
||||
"name": "广西壮族自治区"
|
||||
},
|
||||
"宁夏回族自治区": {
|
||||
"adcode": "640000",
|
||||
"level": "province",
|
||||
"name": "宁夏回族自治区"
|
||||
},
|
||||
"浙江省": {
|
||||
"adcode": "330000",
|
||||
"level": "province",
|
||||
"name": "浙江省"
|
||||
},
|
||||
"河北省": {
|
||||
"adcode": "130000",
|
||||
"level": "province",
|
||||
"name": "河北省"
|
||||
},
|
||||
"香港特别行政区": {
|
||||
"adcode": "810000",
|
||||
"level": "province",
|
||||
"name": "香港特别行政区"
|
||||
},
|
||||
"台湾省": {
|
||||
"adcode": "710000",
|
||||
"level": "province",
|
||||
"name": "台湾省"
|
||||
},
|
||||
"澳门特别行政区": {
|
||||
"adcode": "820000",
|
||||
"level": "province",
|
||||
"name": "澳门特别行政区"
|
||||
},
|
||||
"甘肃省": {
|
||||
"adcode": "620000",
|
||||
"level": "province",
|
||||
"name": "甘肃省"
|
||||
},
|
||||
"四川省": {
|
||||
"adcode": "510000",
|
||||
"level": "province",
|
||||
"name": "四川省"
|
||||
},
|
||||
"天津市": {
|
||||
"adcode": "120000",
|
||||
"level": "province",
|
||||
"name": "天津市"
|
||||
},
|
||||
"江西省": {
|
||||
"adcode": "360000",
|
||||
"level": "province",
|
||||
"name": "江西省"
|
||||
},
|
||||
"云南省": {
|
||||
"adcode": "530000",
|
||||
"level": "province",
|
||||
"name": "云南省"
|
||||
},
|
||||
"山西省": {
|
||||
"adcode": "140000",
|
||||
"level": "province",
|
||||
"name": "山西省"
|
||||
},
|
||||
"北京市": {
|
||||
"adcode": "110000",
|
||||
"level": "province",
|
||||
"name": "北京市"
|
||||
},
|
||||
"吉林省": {
|
||||
"adcode": "220000",
|
||||
"level": "province",
|
||||
"name": "吉林省"
|
||||
}
|
||||
}
|
|
@ -12,9 +12,14 @@ const LeftBottom = defineAsyncComponent(() => import("./LeftBottom.vue"));
|
|||
// 导入中间组件
|
||||
const CenterTop = defineAsyncComponent(() => import("./components/CenterTop.vue"));
|
||||
const CenterBottom = defineAsyncComponent(() => import("./components/CenterBottom.vue"));
|
||||
const CenterMap = defineAsyncComponent(() => import("./center-map.vue"));
|
||||
|
||||
// 导入右侧组件
|
||||
const RightCenter = defineAsyncComponent(() => import("./RightCenter.vue"));
|
||||
|
||||
// 地图
|
||||
const mapRef: any = ref(null);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -38,7 +43,8 @@ const RightCenter = defineAsyncComponent(() => import("./RightCenter.vue"));
|
|||
|
||||
<!-- 中间内容区域 -->
|
||||
<div class="center-content">
|
||||
<CenterTop />
|
||||
<CenterMap class="center_content_top" title="咨询地图"/>
|
||||
<!-- <CenterTop /> -->
|
||||
<!-- <ItemWrap title="高频咨询问题" class="module-item">
|
||||
<CenterBottom />
|
||||
</ItemWrap> -->
|
||||
|
@ -85,6 +91,10 @@ const RightCenter = defineAsyncComponent(() => import("./RightCenter.vue"));
|
|||
gap: 20px;
|
||||
}
|
||||
|
||||
.center_content_top {
|
||||
|
||||
}
|
||||
|
||||
.left-contetn-top {
|
||||
height: 200px;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue