本地图主要使用ehcarts和echarts-gl进行开发,实现的3D地图可以旋转、缩放、多角度观察。悬浮框是自定义样式。
1、引入echarts和echarts-gl库
echarts的资源比较常见,这里主要列出echarts-gl的离线资源
<script type="text/javascript" src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/echarts-gl/2.0.8/echarts-gl.js"></script>
2、3D地图的基础配置
根据网上获取的json数据进行初始化地图,然后配置地图的option,重点在于series和viewcontrol的配置。地图的透明质感主要来自于其透明度的设置和材质的选择,可以在网络上寻找蓝色渐变、具有科技感的材质图。
let mapJson = './map/ganziMap.json'
const myChart = echarts.init(document.getElementById('map'))
let option = {
backgroundColor: "rgba(0,0,0,0)",
series: {
type: 'map3D',
show: true,
map: "centerMap",
left: "0%",
roam: true,
shading: 'realistic',
realisticMaterial: {
roughness: 1,
textureTiling: 1,
detailTexture: mapTexture
},
regionHeight: 10,
label: {
show: true,
distance: 0,
borderRadius: 0,
color: "#fff",
fontSize: '16px'
},
itemStyle: {
// 三维地理坐标系组件 中三维图形的视觉属性,包括颜色,透明度,描边等。
color: "rgba(255,255,255, 0.2)", // 地图板块的颜色
//opacity: 2, // 图形的不透明度 [ default: 1 ]
borderWidth: 2.5, // (地图板块间的分隔线)图形描边的宽度。加上描边后可以更清晰的区分每个区域 [ default: 0 ]
borderColor: "rgb(141, 228, 238)", // 图形描边的颜色。[ default: #333 ]
},
emphasis: {
label: {
show: true,
color: "#fff",
},
itemStyle: {
color: "rgb(77, 138, 164)",
opacity: 0.5,
},
},
light: {
// 光照阴影
main: {
color: "#FFFFFF", // 光照颜色
intensity: 2.5, // 光照强度
shadowQuality: "light", // 阴影亮度
shadow: false, // 是否显示阴影
alpha: 70,
beta: 10,
},
},
regions: [],
viewControl: {
"projection": "perspective",
"autoRotate": false,
"autoRotateAfterStill": 3,
"distance": 140.65,
"alpha": 50.433,
"beta": -67.27,
"minAlpha": -200,
"maxAlpha": 200,
"minBeta": -1036800,
"maxBeta": 1036800,
"animation": true,
"animationDurationUpdate": 1000,
"animationEasingUpdate": "cubicInOut",
"orthographicSize": 60,
"autoRotateDirection": "cw",
"autoRotateSpeed": 10,
"damping": 0.8,
"rotateSensitivity": 1,
"zoomSensitivity": 1,
"panSensitivity": 1,
"panMouseButton": "middle",
"rotateMouseButton": "left",
"minDistance": 120.8,
"maxDistance": 160,
"maxOrthographicSize": 400,
"minOrthographicSize": 20,
"center": [
0,
0,
0
]
},
},
}
myChart.showLoading();
$.getJSON(mapJson, function (geoJson) {
echarts.registerMap('centerMap', geoJson);
myChart.hideLoading();
myChart.setOption(option);
});
3、自定义样式的悬浮框
需求是要使用自定义的图片样式作为悬浮框,但是echarts-gl不支持为tooltip设置html,所以采用动态创建和改变悬浮框以及配合鼠标悬浮事件的方案进行实现。其中悬浮框的底图采用base64格式的图片进行设置,可在css中设置backgroun-image,此处不加赘述。
let tooltip = null
let that = this
myChart.on('mouseover', function (params) {
let target = that.findParam(that.allData, "NAME", params.name)
let event = params.event;
let mouseX = event.offsetX;
let mouseY = event.offsetY;
let arr = ["xx县", "xx县", "xx县", "xx县", "xx县"]
let leftDistance = mouseX + 3 + 'px'
let topDistance = mouseY + 3 + 'px'
if (arr.includes(params.name)) {
leftDistance = mouseX + (-275) + 'px'
topDistance = mouseY + (-183) + 'px'
}
// 如果自定义div已经存在,则更新位置和内容
if (tooltip) {
tooltip.style.left = leftDistance; // 更新div的left位置
tooltip.style.top = topDistance; // 更新div的top位置
tooltip.innerHTML = `
<div style="">...</div>`;
} else {
// 如果自定义div不存在,则创建它
tooltip = document.createElement('div');
tooltip.className = 'container'; // 设置div的样式类名
tooltip.innerHTML = `
<div style="">...</div>`; // 设置div的内容
tooltip.style.left = leftDistance; // 更新div的left位置
tooltip.style.top = topDistance; // 更新div的top位置
let distance = myChart.getOption().series[0].viewControl.distance; // 获取当前的distance值
//悬浮框大小自适应
let newScale = distance / 175.8
tooltip.style.transform = 'scale(' + newScale + ')';
// 将div添加到页面中
document.body.appendChild(tooltip);
}
});
// 监听鼠标离开事件,用于隐藏自定义的div
myChart.on('globalout', function (params) {
// 隐藏自定义的div
if (tooltip) {
tooltip.remove();
tooltip = null;
}
});