Echarts中国地图下钻,支持下钻到县(vue3)
引言Echarts 大家都不陌生吧,时常被用于绘制各种图表,也作为大屏可视化的常驻用户,这里就不多说了,今天主要是讲述一下 Echarts 的地图下钻,支持下钻到县、返回上一级。
准备工作地图JSON数据 DataV.GeoAtlas地理小工具系列 (aliyun.com) 支持在线调用API和下载json资源(我这里是调用的API)
如果地图json API请求报错403,可参考这个解决办法 :地图请求阿里的geojson数据时,返回403Forbidden解决方案 - 掘金 (juejin.cn)
技术栈 vue: 3.3.7vue-echarts: 6.6.1 (直接使用 Echarts 也是一样的,这个只是对 Echarts 的组件封装)vite: 4.5.0地图效果
项目预览地址:UnusualAdmin
项目代码地址:UnusualAdmin
实现template 这里只需要一个 Echarts 节点和一个按钮就行了
template
div:style="`height:${calcHeight('main')};`"class="wh-fullpos-relative"
v-chart:option="mapOption":autoresize="true"@click="handleClick"/
n-buttonv-show="isShowBack"class="pos-absolutetop-10left-10"@click="goBack"返回/n-button
/div
/template
获取mapJson //使用线上API
constgetMapJson=async(mapName:string)={
consturl=`https://geo.datav.aliyun.com/areas_v3/bound/${mapName}.json`
constmapJson=awaitfetch(url).then(res=res.json())
returnmapJson
}
//使用本地资源
constgetMapJson=async(mapName:string)={
consturl=`@/assets/mapJson/${mapName}.json`
constmapJson=awaitimport(/*@vite-ignore*/url)
returnmapJson
}
第二种方法(使用本地资源)存在问题:这个方法后续发现,vite打包不会把json文件打包到dist,线上会报错,目前没找到可靠的解决办法(如果放到public文件夹下会打包进去),故舍弃。
如果大家有什么解决这个问题的好办法,请在评论区留言,博主会一一去尝试的??????
更新地图配置options constsetOptions=(mapName:string,mapData:any)={
return{
//鼠标悬浮提示
tooltip:{
show:true,
formatter:function(params:any){
//根据需要进行数据处理或格式化操作
if(paramsparams.data){
const{adcode,name,data}=params.data;
//返回自定义的tooltip内容
return`adcode:${adcode}name:${name}data:${data}`;
}
},
},
//左下角的数据颜色条
visualMap:{
show:true,
min:0,
max:100,
left:'left',
top:'bottom',
text:['高','低'],//文本,默认为数值文本
calculable:true,
seriesIndex:[0],
inRange:{
color:['#00467F','#A5CC82']//蓝绿
}
},
//geo地图
geo:{
map:mapName,
roam:true,
select:false,
//图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
selectedMode:'single',
label:{
show:true
},
emphasis:{
itemStyle:{
areaColor:'#389BB7',
borderColor:'#389BB7',
borderWidth:0
},
label:{
fontSize:14,
},
}
},
series:[
//地图数据
{
type:'map',
map:mapName,
roam:true,
geoIndex:0,
select:false,
data:mapData
},
//散点
{
name:'散点',
type:'scatter',
coordinateSystem:'geo',
data:mapData,
itemStyle:{
color:'#05C3F9'
}
},
//气泡点
{
name:'点',
type:'scatter',
coordinateSystem:'geo',
symbol:'pin',//气泡
symbolSize:function(val:any){
if(val){
returnval[2]/4+20;
}
},
label:{
show:true,
formatter:function(params:any){
returnparams.data.data||0;
},
color:'#fff',
fontSize:9,
},
itemStyle:{
color:'#F62157',//标志颜色
},
zlevel:6,
data:mapData,
},
//地图标点
{
name:'Top5',
type:'effectScatter',
coordinateSystem:'geo',
data:mapData.map((item:{data:number})={
if(item.data60)returnitem
}),
symbolSize:15,
showEffectOn:'render',
rippleEffect:{
brushType:'stroke'
},
label:{
formatter:'{b}',
position:'right',
show:true
},
itemStyle:{
color:'yellow',
shadowBlur:10,
shadowColor:'yellow'
},
zlevel:1
},
]
}
}
渲染地图 constrenderMapEcharts=async(mapName:string)={
constmapJson=awaitgetMapJson(mapName)
registerMap(mapName,mapJson);//注册地图
//为地图生成一些随机数据
constmapdata=mapJson.features.map((item:{properties:any})={
constdata=(Math.random()*80+20).toFixed(0)//20-80随机数
consttempValue=item.properties.center?[...item.properties.center,data]:item.properties.center
return{
name:item.properties.name,
value:tempValue,//中心点经纬度
adcode:item.properties.adcode,//区域编码
level:item.properties.level,//层级
data//模拟数据
}
//更新地图options
mapOption.value=setOptions(mapName,mapdata)
}
实现地图点击下钻 //点击下砖
constmapList=refstring[]([])//记录地图
consthandleClick=(param:any)={
//只有点击地图才触发
if(param.seriesType!=='map')return
const{adcode,level}=param.data
constmapName=level==='district'?adcode:adcode+'_full'
//防止最后一个层级被重复点击,返回上一级出错
if(mapList.value[mapList.value.length-1]===mapName){
returnnotification.warning({content:'已经是最下层了',duration:1000})
}
//每次下转都记录下地图的name,在返回的时候使用
mapList.value.push(mapName)
renderMapEcharts(mapName)
}
返回上一级实现 //点击返回上一级地图
constgoBack=()={
constmapName=mapList.value[mapList.value.length-2]||'100000_full'
mapList.value.pop()
renderMapEcharts(mapName)
}
全部代码 template
div:style="`height:${calcHeight('main')};`"class="wh-fullpos-relative"
v-chart:option="mapOption":autoresize="true"@click="handleClick"/
n-buttonv-show="isShowBack"class="pos-absolutetop-10left-10"@click="goBack"/n-button
/div
/template
scriptsetuplang="ts"name="EchartsMap"
import{use,registerMap}from'echarts/core'
importVChartfrom'vue-echarts'
import{CanvasRenderer}from'echarts/renderers'
import{MapChart,ScatterChart,EffectScatterChart}from'echarts/charts'
import{TitleComponent,TooltipComponent,LegendComponent,GridComponent,VisualMapComponent}from'echarts/components'
import{calcHeight}from'@/utils/help';
use([
CanvasRenderer,
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
VisualMapComponent,
MapChart,
ScatterChart,
EffectScatterChart
])
constnotification=useNotification()
constmapOption=ref()
constmapList=refstring[]([])//记录地图
constisShowBack=computed(()={
returnmapList.value.length!==0
})
constgetMapJson=async(mapName:string)={
consturl=`https://geo.datav.aliyun.com/areas_v3/bound/${mapName}.json`
constmapJson=awaitfetch(url).then(res=res.json())
returnmapJson
}
constsetOptions=(mapName:string,mapData:any)={
return{
tooltip:{
show:true,
formatter:function(params:any){
//根据需要进行数据处理或格式化操作
if(paramsparams.data){
const{adcode,name,data}=params.data;
//返回自定义的tooltip内容
return`adcode:${adcode}name:${name}data:${data}`;
}
},
},
visualMap:{
show:true,
min:0,
max:100,
left:'left',
top:'bottom',
text:['高','低'],//文本,默认为数值文本
calculable:true,
seriesIndex:[0],
inRange:{
color:['#00467F','#A5CC82']//蓝绿
}
},
geo:{
map:mapName,
roam:true,
select:false,
//zoom:1.6,
//layoutCenter:['45%','70%'],
//layoutSize:750,
//图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
selectedMode:'single',
label:{
show:true
},
emphasis:{
itemStyle:{
areaColor:'#389BB7',
borderColor:'#389BB7',
borderWidth:0
},
label:{
fontSize:14,
},
}
},
series:[
//数据
{
type:'map',
map:mapName,
roam:true,
geoIndex:0,
select:false,
data:mapData
},
{
name:'散点',
type:'scatter',
coordinateSystem:'geo',
data:mapData,
itemStyle:{
color:'#05C3F9'
}
},
{
name:'点',
type:'scatter',
coordinateSystem:'geo',
symbol:'pin',//气泡
symbolSize:function(val:any){
if(val){
returnval[2]/4+
}
},
label:{
show:true,
formatter:function(params:any){
returnparams.data.data||
},
color:'#fff',
fontSize:9,
},
itemStyle:{
color:'#F62157',//标志颜色
},
zlevel:6,
data:mapData,
},
{
name:'Top5',
type:'effectScatter',
coordinateSystem:'geo',
data:mapData.map((item:{data:number})={
if(item.data60)returnitem
}),
symbolSize:15,
showEffectOn:'render',
rippleEffect:{
brushType:'stroke'
},
label:{
formatter:'{b}',
position:'right',
show:true
},
itemStyle:{
color:'yellow',
shadowBlur:10,
shadowColor:'yellow'
},
zlevel:1
},
]
}
}
constrenderMapEcharts=async(mapName:string)={
constmapJson=awaitgetMapJson(mapName)
registerMap(mapName,mapJson);
constmapdata=mapJson.features.map((item:{properties:any})={
constdata=(Math.random()*80+20).toFixed(0)//20-80随机数
consttempValue=item.properties.center?[...item.properties.center,data]:item.properties.center
return{
name:item.properties.name,
value:tempValue,//中心点经纬度
adcode:item.properties.adcode,//区域编码
level:item.properties.level,//层级
data//模拟数据
}
mapOption.value=setOptions(mapName,mapdata)
}
renderMapEcharts('100000_full')//初始化绘制中国地图
//点击下砖
consthandleClick=(param:any)={
//只有点击地图才触发
if(param.seriesType!=='map')return
const{adcode,level}=param.data
constmapName=level==='district'?adcode:adcode+'_full'
//防止最后一个层级被重复点击,返回上一级出错
if(mapList.value[mapList.value.length-1]===mapName){
returnnotification.warning({content:'已经是最下层了',duration:1000})
}
mapList.value.push(mapName)
renderMapEcharts(mapName)
}
//点击返回上一级地图
constgoBack=()={
constmapName=mapList.value[mapList.value.length-2]||'100000_full'
mapList.value.pop()
renderMapEcharts(mapName)
}
/script
博客主要记录一些学习的文章,如有不足,望大家指出,谢谢。
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线