import { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { useRequest, useAsyncEffect } from 'ahooks';
import { getFetch } from '@/utils/doFetch';
import { useModel } from '@umijs/max';
import * as echarts from 'echarts';
import ReactECharts from 'echarts-for-react';
import { message } from 'antd';
const color = [
'#322145',
'#302A4C',
'#2E3353',
'#284563',
'#2C395B'
];
let names = ["内蒙古自治区", '广西壮族自治区', "宁夏回族自治区", "西藏自治区", "新疆维吾尔自治区", "香港特别行政区", "澳门特别行政区"];
const Mapindex = ({ }) => {
const mapRef = useRef();
const [maps, setMaps] = useState([
{
adcode: 100000,
name: '中国'
}
]);
const [mapData, setMapData] = useState({});
// 在组件挂载后初始化地图,显示中国地图
useAsyncEffect(async () => {
await getGeoJson(100000, '中国');
}, []);
let options = useMemo(() => {
if (mapData?.name && mapData?.geoJson) {
echarts.registerMap(mapData?.name, mapData?.geoJson);
return {
geo: [
{
map: mapData?.name,
roam: true, // 开启缩放和平移
show: true,
label: {
show: false
},
zoom: 1.5,
top: '20%',
zlevel: 1,
label: {
show: true, // 显示标签
color: "#fff",
formatter: (params) => {
if (names.indexOf(params.name) > -1) {
return params?.name?.substr(0, 2)
}
return params.name
// if (params.data.level === 'province') {
// return params?.name.indexOf('黑龙江') == -1 ? params?.name?.substr(0, 2) : params?.name?.substr(0, 3)
// }
// return params?.name;
}
},
regions: mapData?.geoJson?.features?.map((item) => {
let itemcolor = color[Math.floor(Math.random() * color.length)];
return {
name: item.properties.name,
itemStyle: {
areaColor: itemcolor, // 正常状态下区域的颜色
borderColor: '#525E80' // 边界颜色
},
emphasis: {
itemStyle: {
areaColor: itemcolor,
borderColor: '#02F2F3'
}, // 鼠标移到区域上时的颜色
label: {
color: "#02F2F3"
}
},
}
})
}
],
series: [
// {
// type: 'map',
// name: mapData?.name,
// map: mapData?.name,
// roam: true, // 开启缩放和平移
// label: {
// show: true, // 显示标签
// color: "#fff",
// formatter: (params) => {
// if (params.data.level === 'province') {
// return params?.name.indexOf('黑龙江') == -1 ? params?.name?.substr(0, 2) : params?.name?.substr(0, 3)
// }
// return params?.name;
// }
// },
// //数据处理,通过映射获取每个区域的名称、值和行政区划代码
// data: mapData?.geoJson?.features?.map((item) => {
// let itemcolor = color[Math.floor(Math.random() * color.length)];
// return {
// name: item.properties.name,
// value: item.properties.childrenNum,
// adcode: item.properties.adcode,
// level: item.properties.level,
// itemStyle: {
// areaColor: itemcolor, // 正常状态下区域的颜色
// borderColor: '#525E80' // 边界颜色
// },
// emphasis: {
// itemStyle: {
// areaColor: itemcolor,
// borderColor: '#02F2F3'
// }, // 鼠标移到区域上时的颜色
// label: {
// color: "#02F2F3"
// }
// },
// }
// }),
// zoom: 1.5,
// top: '20%'
// },
{
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 2,
rippleEffect: { //涟漪特效
period: 4, //动画时间,值越小速度越快
brushType: 'stroke', //波纹绘制方式 stroke, fill
scale: 4 //波纹圆环最大限制,值越大波纹越大
},
label: {
normal: {
show: true,
position: 'right', //显示位置
offset: [5, 0], //偏移设置
formatter: function (params) {//圆环显示文字
return params.data.name;
},
color: '#FFD200',
fontSize: 16
},
emphasis: {
show: true
}
},
symbol: 'circle',
// symbolSize: function (val) {
// return 5 + val[2] * 5; //圆环大小
// },
itemStyle: {
normal: {
show: true,
color: '#ffffff'
}
},
data: [
{
name: "卫生监督所",
value: [118.767413, 32.041544, 0],
},
{
name: "瑞金医院",
value: [114.297769838, 35.7554258742, 0],
},
],
},
]
}
}
return {};
}, [mapData]);
let getGeoJson = async (adcode, name) => {
//MAP_URL是我本地的常量:/map/,代理到:https://geo.datav.aliyun.com/areas_v3/bound/geojson
let res = await fetch(`${MAP_URL}?code=${adcode}_full`, {
method: "GET"
});
if (res.status == 200) {
let data = await res?.json();
setMapData({
adcode,
name,
geoJson: data
});
} else {
message.error("数据获取有误!")
}
}
return (
<div style={{ width: '100%', height: '100%' }}>
{
options?.series && <ReactECharts
ref={mapRef}
option={options}
style={{ height: '100%', width: '100%' }}
lazyUpdate={true}
notMerge={true}
onEvents={{
"click": async (e) => {
let items = mapData?.geoJson?.features?.filter(it => it.properties.name === e.name)?.[0]?.properties ?? {};
if (Object.keys(items).length > 0) {
if (items.level == 'district') {
message.destroy();
return message.warning("不可以继续下钻!")
}
await getGeoJson(items.adcode, items.name);
setMaps(s => {
if (s?.map(it => it.adcode)?.indexOf(items.adcode) == -1) {
return [...s, { adcode: items.adcode, name: items.name }]
}
return s;
});
}
},
"contextmenu": async (e) => {
e.event.stop();
let items = mapData?.geoJson?.features?.filter(it => it.properties.name === e.name)?.[0]?.properties ?? {};
if (Object.keys(items).length > 0) {
let newdatas = JSON.parse(JSON.stringify(maps));
let newMaps = newdatas.slice(0, -1);
let prev = newMaps[newMaps.length - 1] ?? {};
let { adcode, name } = prev;
if (adcode && name) {
await getGeoJson(adcode, name);
setMaps((s) => {
return newMaps;
});
}
}
}
}}
/>
}
</div>
)
}
export default Mapindex;
nginx配置MAP_URL
location /map/ {
proxy_pass https://geo.datav.aliyun.com/areas_v3/bound/geojson;
proxy_set_header Host geo.datav.aliyun.com;
proxy_set_header User-Agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3";
proxy_set_header Referer "https://geo.datav.aliyun.com/";
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
add_header 'Access-Control-Allow-Headers' '*';
}
proxy.js这样配置:
dev: {
'/map/': {
target: xxx, //xxx是nginx配置的代理地址,例如:https://tasks.youtianchen.cn/
changeOrigin: true,
// pathRewrite: { '^/map/': '' },
}
}
效果如下:
echarts-for-react和echarts连用实现地