当我们手机用 scatter3D 类型时,最小值因为渲染问题会塌陷进模型里面,所以只要让value固定,再将label formatter 配合 boxHeight属性即可解决,(代码附带自定义label图标解决办法)
解决:
<template>
<div ref="chartRef" class="map-3d-container" style="width: 100%; height: 100%"></div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import * as echarts from 'echarts'
import 'echarts-gl'
import { user } from '@/store/modules/user'
import shadowImg from '@/assets/shadow.png'
import marker from '@/assets/3DMap-marker.png'
const userStore = user()
const emits = defineEmits(['click'])
const chartRef = ref<HTMLDivElement | null>(null)
onMounted(async () => {
const testData = [
{ lat: '30.257572', lng: '120.189438', guns: '1', deptId: 1 },
{ lat: '30.300447', lng: '119.922606', guns: '351', deptId: 2 },
{ lat: '30.337124', lng: '120.434121', guns: '51', deptId: 3 },
{ lat: '30.284913', lng: '119.715042', guns: '52', deptId: 4 },
]
let chartData: { value: any[] }[] = []
testData .forEach((e) => {
if (e.lng && e.lat && e.guns) {
chartData.push({
value: [e.lng, e.lat, { ...e }],
})
}
})
const myChart = echarts.init(chartRef.value as HTMLDivElement)
echarts.registerMap('map', userStore.mapData)
const option = {
backgroundColor: 'rgba(0,0,0,0)',
animation: true,
tooltip: {
trigger: 'axis',
},
geo3D: {
map: 'map',
show: true,
shading: 'realistic',
regionHeight: 4,
width: '100%',
height: '100%',
boxHeight: 8,
realisticMaterial: {
oughness: 1,
textureTiling: 1,
roughness: 1,
detailTexture: shadowImg, // 地图表面贴图
},
viewControl: {
rotateSensitivity: 2,
alpha: 40,
beta: 60,
autoRotate: true,
autoRotateAfterStill: 30,
autoRotateSpeed: 6, // 旋转速度
distance: 60,
minDistance: 80,
maxDistance: 200,
minBeta: null, // 确保可以完全旋转
maxBeta: null,
center: [20, 0, 0],
panMouseButton: 'left',
animation: true, // 确保动画开启
},
itemStyle: {
color: 'rgb(55,155,255)',
opacity: 1,
borderWidth: 3,
borderColor: 'rgb(58,255,255)',
},
emphasis: {
show: false,
itemStyle: {
color: 'rgb(55,155,255)',
},
},
label: {
show: true,
color: 'rgb(250,250,250)',
fontWeight: '600',
fontSize: 14,
},
light: {
// 光照阴影
main: {
color: 'rgb(26,92,211)', // 光照颜色
intensity: 2, // 光照强度
shadowQuality: 'high', //阴影亮度
shadow: true, // 是否显示阴影
alpha: 10,
beta: 90,
},
ambient: {
intensity: 0.8,
},
},
},
series: [
{
type: 'scatter3D',
coordinateSystem: 'geo3D',
opacity: 1,
symbol: 'circle',
symbolSize: 40,
itemStyle: {
color: 'rgb(20,20,20)',
},
emphasis: {
itemStyle: {
color: '#fff',
},
},
data: chartData.map((it) => {
return {
value: [it.value[0], it.value[1], 100, it.value[2]],
}
}),
label: {
distance: -88,
show: true,
position: 'top',
color: '#fff',
height: 28,
fontSize: 14,
fontWeight: 600,
padding: [28, 20],
backgroundColor: {
image: marker,
},
formatter: (res: any) => {
const value = Number(res.value[3].guns) > 999 ? 999 : Number(res.value[3].guns)
const leftNbsp = value >= 100 ? '' : 0
const rightNbsp = value >= 10 ? '' : 0
return `${leftNbsp}${rightNbsp}${value}`
},
},
},
],
}
myChart.setOption(option)
myChart.on('click', (params) => {
if (params.seriesType === 'scatter3D') {
emits('click', params?.value[3])
}
console.log(params, 'paramsparams')
})
})
</script>
<style>
html,
body,
#app {
width: 100%;
height: 100%;
}
.container {
background: url('./assets/background.png') no-repeat 100%;
}
</style>