开发笔记04:vue3+TS+echart、echart-gl实现3D效果地图
echart+tooltip效果样式的调整+区域的高亮+数据展示不同颜色+地图添加纹理贴图+线条样式修改+厚度+旋转
·
解:因为简单方便快捷,需求简单,不需要去了解其他语言
效果如下(贴图的话图片中没有展示被我注释掉了,environment属性引入图片即可):
一、下载所需要的地图json数据
json数据的获取在阿里云可以直接下载,以绍兴市为例,链接地址:阿里云地图json获取
二、echarts使用
1.引入库
安装需要用到的插件(本人用的pnpm,需要可出使用方法):
pnpm install echart echart-gl
2.安装完成之后引入组件
import * as echarts from 'echarts'
import 'echarts-gl'
3.初始化页面
以下引入代码就可正常展示效果,页面效果做的不是很好需要自己后面去优化一下,对于途中的贴图小水滴一样的暂时只支持简单的path矢量图或者自带的默认几个效果,暂无找到解决办法,有解决的欢迎来分享一下哈。
<script setup lang="ts" name="Map">
import type { VNode } from 'vue'
import { createVNode, render } from 'vue'
import * as echarts from 'echarts'
import geoJson from './sxMap.json' // 为刚刚下载的json文件,需正确引入路径
import MapTooltip from './tip.vue' // tooltip样式需调整,单独封装之后引入页面
import 'echarts-gl'
// const blue = `image://${new URL('./img/top_location_blue.png', import.meta.url).href}`
const mapChart = ref<HTMLElement>()
const scatterData = ref([
{ name: '越城区', value: [120.585315, 29.996993, 0] },
{ name: '柯桥区', value: [120.476075, 30.078038, 0] },
{ name: '上虞区', value: [120.874185, 30.016769, 0] },
{ name: '新昌县', value: [120.905665, 29.501205, 0] },
{ name: '诸暨市', value: [120.244326, 29.713662, 0] },
{ name: '嵊州市', value: [120.82888, 29.586606, 0] },
])
const labelData = ref([
{
name: '越城区',
value: [120.645315, 30.069932],
itemStyle: { color: '#96fdfd' },
},
{
name: '柯桥区',
value: [120.636075, 29.848038, 0],
itemStyle: { color: '#96fdfd' },
},
{
name: '上虞区',
value: [120.899185, 30.070069, 0],
itemStyle: { color: '#96fdfd' },
},
{
name: '新昌县',
value: [120.965665, 29.447205, 0],
itemStyle: { color: '#96fdfd' },
},
{
name: '诸暨市',
value: [120.244326, 29.723662, 0],
itemStyle: { color: '#96fdfd' },
},
{
name: '嵊州市',
value: [120.73888, 29.626606, 0],
itemStyle: { color: '#96fdfd' },
},
])
const cacheCom = new Map<string, HTMLDivElement>()
const initMap = async () => {
// 名称为引入json文件的名称,需要和下面的geo3D名称对应
echarts.registerMap('shaoxing', geoJson as any)
const myChart = echarts.init(mapChart.value!)
const data3d = scatterData.value.map((el) => {
return {
name: el.name,
value: el.value,
}
})
// 图表配置项
const option = {
tooltip: {
trigger: 'item',
className: 'map-tooltip',
formatter: (params: any) => {
const { name } = params.data
// 本需求为鼠标悬浮某个区域之后需要获取当下区域的数据,所以加上缓存,避免大量请求接口
// 如果没有此需求可以将数据进行修改一下去掉缓存即可
const cacheNode = cacheCom.get(name)
if (cacheNode) {
return cacheNode
}
else {
// 创建虚拟DOM节点 引入封装好的toopltip组件并传参
const tip = createVNode(MapTooltip, {
info: params.data,
})
const mountNode = document.createElement('div')
render(tip, mountNode)
cacheCom.set(name, mountNode)
return mountNode
}
},
},
geo3D: {
map: 'shaoxing',
roam: true,
shading: 'realistic', // 设置阴影效果
// top: '0',
regionHeight: 5, // 地图厚度
// environment: bg,
itemStyle: {
// 图片配置区域
color: 'rgba(36, 63, 123, 0.2)', // 区域颜色
opacity: 0.7,
borderWidth: 3,
borderColor: '#3898ff', // 地图边缘线条颜色
},
viewControl: {
autoRotate: false,
// autoRotateAfterStill: 3,
// 无法旋转
rotateSensitivity: 0,
panSensitivity: 0, // 禁用平移
zoomSensitivity: 0, // 禁用缩放
projection: 'orthographic',
orthographicSize: 85, // 透视投影方式下,相机距离主体的距离,是相机位置和目标点连线和视点方向夹角的函数。默认情况下,该距离会通过自适应的方式计算。用户可以手动设置一个固定的距离值。
distance: 210,
minAlpha: 15, // 上下旋转的最小 alpha 值。即视角能旋转到达最上面的角度。[ default: 5 ]
maxAlpha: 90, // 上下旋转的最大 alpha 值。即视角能旋转到达最下面的角度。[ default: 90 ]
minBeta: -360, // 左右旋转的最小 beta 值。即视角能旋转到达最左的角度。[ default: -80 ]
maxBeta: 360, // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。[ default: 80 ]
animation: true, // 是否开启动画。[ default: true ]
animationDurationUpdate: 2000, // 过渡动画的时长。[ default: 1000 ]
animationEasingUpdate: 'cubicInOut', // 过渡动画的缓动效果。[ default: cubicInOut ]
},
emphasis: {
disabled: true, // 是否可以被选中
label: {
// 移入时的高亮文本
show: true,
color: '#fff', // 显示字体颜色变淡
fontSize: 20, // 显示字体变大
fontFamily: 'GBKFont',
borderColor: 'red', // 地图边缘线条颜色
},
itemStyle: {
color: 'rgba(98, 241, 255, 0.6)', // 显示移入的区块变色
fontFamily: 'GBKFont',
borderColor: 'red', // 地图边缘线条颜色
},
},
label: {
show: true,
// borderWidth: 10,
color: '#ffffff', // 地图初始化区域字体颜色
fontSize: 20,
fontFamily: 'GBKFont',
// fontWeight: 'bold',
lineHeight: 22,
formatter(params: any) {
return `${params.name}`
},
},
realisticMaterial: {
// detailTexture: bgBase64,
roughness: 0,
},
postEffect: {
enable: false,
},
groundPlane: {
show: false,
},
light: {
// 光照阴影
main: {
color: '#fff', // 光照颜色
intensity: 1, // 光照强度
shadowQuality: 'high', // 阴影亮度
shadow: true, // 是否显示阴影
// shadowQuality: 'medium', // 阴影质量 ultra //阴影亮度
alpha: 85,
beta: 10,
},
ambient: {
intensity: 0.7,
},
},
// 高亮区域设置,本次未做展示,注释关闭即可看到
// regions: [
// {
// name: '柯桥区',
// itemStyle: {
// color: '#fff',
// distance: '20px',
// borderWidth: 10,
// },
// },
// ],
},
series: [
{
type: 'map3D', // 加载series数据
map: 'shaoxing',
itemStyle: {
// 图片配置区域
color: 'rgba(36, 63, 123, 0.6)', // 区域颜色
opacity: 0,
borderWidth: 0,
borderColor: '#3898ff', // 地图边缘线条颜色
},
data: data3d,
regions: [],
zlevel: 5,
viewControl: {
autoRotate: false,
// autoRotateAfterStill: 3,
// 无法旋转
rotateSensitivity: 0,
panSensitivity: 0, // 禁用平移
zoomSensitivity: 0, // 禁用缩放
projection: 'orthographic',
orthographicSize: 85, // 透视投影方式下,相机距离主体的距离,是相机位置和目标点连线和视点方向夹角的函数。默认情况下,该距离会通过自适应的方式计算。用户可以手动设置一个固定的距离值。
distance: 120,
minAlpha: 15, // 上下旋转的最小 alpha 值。即视角能旋转到达最上面的角度。[ default: 5 ]
maxAlpha: 90, // 上下旋转的最大 alpha 值。即视角能旋转到达最下面的角度。[ default: 90 ]
minBeta: -360, // 左右旋转的最小 beta 值。即视角能旋转到达最左的角度。[ default: -80 ]
maxBeta: 360, // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。[ default: 80 ]
animation: true, // 是否开启动画。[ default: true ]
animationDurationUpdate: 1000, // 过渡动画的时长。[ default: 1000 ]
animationEasingUpdate: 'cubicInOut', // 过渡动画的缓动效果。[ default: cubicInOut ]
},
},
{
type: 'scatter3D',
coordinateSystem: 'geo3D',
// symbolSize: 30,
zlevel: 99,
geo3DIndex: 0,
shadowBlur: 10,
silent: false,
itemStyle: {
opacity: 1,
width: 1,
},
emphasis: {
disable: false,
},
label: {
show: false,
},
// symbolSize: [20, 20],
symbol: 'pin',
symbolSize: 25,
data: labelData.value,
shading: 'lambert',
},
],
}
myChart.setOption(option)
window.addEventListener('resize', () => {
myChart.resize()
})
}
onMounted(() => {
// 初始化地图
initMap()
})
</script>
<template>
<div ref="mapChart" class="mapChart" />
</template>
<style lang="scss" scoped>
::v-deep(.map-tooltip) {
padding: 0 !important;
background: transparent !important;
border: none !important;
}
</style>
4. 封装的tooltip页面
其实就和封装正常的页面是一样的,不过就是引入这里的话稍微有点不一样,代码的话就随便放一个好了,样式的话自行根据需求来修改就好。
<script setup lang="ts" name="Tip">
import { debounce, throttle } from 'lodash'
const props = defineProps<{
info: { name: string; value: Array<number> }
}>()
const number = ref(0)
const disposed = ref(0)
const feedback = ref(0)
</script>
<template>
<div class="Tip">
<div class="header">
{{ props.info.name }}
</div>
<div class="content">
自己的内容
</div>
</div>
</template>
<style scoped lang="scss">
.Tip {
padding: 15px 30px;
width: 280px;
height: 160px;
background: url(./img/floating-window_bg.png) no-repeat;
background-size: 100% 100%;
color: #fff;
.header {
text-align: center;
font-size: 20px;
margin-bottom: 10px;
font-weight: 700;
letter-spacing: 4px;
}
}
</style>
总结
基本的3D效果是可以达到的,里面有包含对于tooltip效果样式的调整、部分区域的高亮展示、以及不用数据展示不同颜色、地图添加纹理贴图、对于边缘线的样式修改以及厚度是否旋转等等,基础的使用基本上问题不大。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)