项目依赖:echarts@5.4.3
npm install echarts@5.4.3
地图数据获取
- 你可以从 阿里云 DataV 下载标准的
china.json,放到项目的src/assets/目录下即可。
echarts 参数配置
| 效果 | 实现方式 |
|---|---|
| 带涟漪的发光点 | effectScatter 系列,配合 rippleEffect 和 shadowBlur |
| 向上的蓝线 | lines 系列,curveness: 0 画直线,从点的位置向上延伸 |
| 带背景的标签 | scatter 系列,symbolSize: 0 隐藏圆点,用 label 实现文字框 |
| 深蓝色科技风 | 统一 backgroundColor、geo.itemStyle.areaColor、itemStyle.color 为同色系 |
可调整的参数
pointData里的经纬度可以改成你实际业务的坐标lat + 2控制连线的高度,数值越大,线越长geo.center和geo.zoom可以调整地图的位置和缩放- 所有颜色值都可以根据你的设计稿微调
Vue3 代码
<template>
<div class="map-container" ref="chartRef"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
// 引入中国地图 GeoJSON 数据(也可以用 CDN 方式引入)
import chinaJson from '@/assets/china.json' // 请自行下载 china.json 放到 assets 目录
const chartRef = ref(null)
let myChart = null
// 1. 定义点位数据:经纬度 + 金额
const pointData = [
{
name: '点1',
value: [89.44, 36.32, 100], // 西藏附近 示例坐标
label: '100万'
},
{
name: '点2',
value: [96.72, 33.23, 10], // 青海附近 示例坐标
label: '10万'
},
{
name: '点3',
value: [104.06, 30.67, 100], // 四川 示例坐标
label: '100万'
},
{
name: '点4',
value: [102.71, 25.04, 100], // 云南 示例坐标
label: '100万'
},
{
name: '点5',
value: [106.71, 26.57, 100], // 贵州 示例坐标
label: '100万'
}
]
// 2. 注册地图
echarts.registerMap('china', chinaJson)
// 3. 初始化图表
const initChart = () => {
myChart = echarts.init(chartRef.value)
const option = {
backgroundColor: '#0A192F', // 深蓝色背景,匹配科技风
geo: {
map: 'china',
roam: false, // 禁止缩放平移,如需开启设为 true
zoom: 1.2, // 地图缩放
center: [103, 35], // 地图中心位置,可微调
itemStyle: {
areaColor: '#0B3D91', // 地图区域底色
borderColor: '#4CC9F0', // 省份边框
borderWidth: 1
},
emphasis: {
itemStyle: {
areaColor: '#1E88E5' // hover 高亮色
}
},
label: {
show: true,
color: 'rgba(255,255,255,0.7)', // 省份文字半透明白色
fontSize: 12
}
},
series: [
// ① 涟漪特效散点(图中带波纹的圆点)
{
type: 'effectScatter',
coordinateSystem: 'geo',
symbolSize: 12,
rippleEffect: {
brushType: 'stroke',
scale: 4,
period: 3
},
itemStyle: {
color: '#4CC9F0', // 圆点颜色,匹配科技蓝
shadowBlur: 10,
shadowColor: '#4CC9F0'
},
data: pointData.map(item => ({
name: item.name,
value: item.value.slice(0, 2) // 取经纬度
}))
},
// ② 普通散点,用于定位+画连线起点(和上面的涟漪点位置重合)
{
type: 'scatter',
coordinateSystem: 'geo',
symbolSize: 8,
itemStyle: {
color: '#4CC9F0'
},
data: pointData.map(item => ({
name: item.name,
value: item.value.slice(0, 2)
}))
},
// ③ 自定义连线 + 标签(模拟向上的垂直线+标签)
{
type: 'lines',
coordinateSystem: 'geo',
polyline: false,
zlevel: 2,
effect: {
show: false
},
lineStyle: {
color: '#4CC9F0',
width: 2,
curveness: 0
},
data: pointData.map(item => {
const [lng, lat] = item.value
// 从点的位置向上画一条线(纬度增加 2 度,可调整)
return {
coords: [
[lng, lat],
[lng, lat + 2]
]
}
})
},
// ④ 用 scatter 实现文字标签(放在连线顶部)
{
type: 'scatter',
coordinateSystem: 'geo',
symbolSize: 0, // 隐藏圆点,只显示文字
label: {
show: true,
position: 'right',
formatter: params => {
const point = pointData.find(p => p.name === params.name)
return point?.label || ''
},
backgroundColor: 'rgba(20, 30, 48, 0.8)', // 深色背景框
borderColor: '#4CC9F0',
borderWidth: 1,
borderRadius: 8,
padding: [8, 16],
color: '#fff',
fontSize: 14
},
data: pointData.map(item => {
const [lng, lat] = item.value
return {
name: item.name,
value: [lng, lat + 2] // 标签放在连线顶部
}
})
}
]
}
myChart.setOption(option)
// 响应式适配
window.addEventListener('resize', () => {
myChart.resize()
})
}
onMounted(() => {
initChart()
})
onUnmounted(() => {
if (myChart) {
myChart.dispose()
}
window.removeEventListener('resize', () => {})
})
</script>
<style scoped>
.map-container {
width: 100%;
height: 800px;
}
</style>
Html 版代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>完整中国地图</title>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#081734;padding:20px}
#map{width:100%;height:750px}
</style>
</head>
<body>
<div id="map"></div>
<script>
const chinaJson = {"type":"FeatureCollection","features":[{"type":"Feature","id":"110000","properties":{"name":"北京市","cp":[116.403874,39.914885],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[116.403874,39.914885]]]}},{"type":"Feature","id":"120000","properties":{"name":"天津市","cp":[117.205905,39.090671],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[117.205905,39.090671]]]}},{"type":"Feature","id":"130000","properties":{"name":"河北省","cp":[114.502464,38.045474],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[114.502464,38.045474]]]}},{"type":"Feature","id":"140000","properties":{"name":"山西省","cp":[112.548986,37.857469],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[112.548986,37.857469]]]}},{"type":"Feature","id":"150000","properties":{"name":"内蒙古自治区","cp":[111.765801,40.808263],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[111.765801,40.808263]]]}},{"type":"Feature","id":"210000","properties":{"name":"辽宁省","cp":[123.429096,41.835684],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[123.429096,41.835684]]]}},{"type":"Feature","id":"220000","properties":{"name":"吉林省","cp":[125.324584,43.886841],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[125.324584,43.886841]]]}},{"type":"Feature","id":"230000","properties":{"name":"黑龙江省","cp":[126.641975,45.753618],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[126.641975,45.753618]]]}},{"type":"Feature","id":"310000","properties":{"name":"上海市","cp":[121.473701,31.230416],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[121.473701,31.230416]]]}},{"type":"Feature","id":"320000","properties":{"name":"江苏省","cp":[118.762859,32.060257],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[118.762859,32.060257]]]}},{"type":"Feature","id":"330000","properties":{"name":"浙江省","cp":[120.153576,30.287459],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[120.153576,30.287459]]]}},{"type":"Feature","id":"340000","properties":{"name":"安徽省","cp":[117.283447,31.861194],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[117.283447,31.861194]]]}},{"type":"Feature","id":"350000","properties":{"name":"福建省","cp":[119.306239,26.075302],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[119.306239,26.075302]]]}},{"type":"Feature","id":"360000","properties":{"name":"江西省","cp":[115.892151,28.673083],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[115.892151,28.673083]]]}},{"type":"Feature","id":"370000","properties":{"name":"山东省","cp":[117.000923,36.675808],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[117.000923,36.675808]]]}},{"type":"Feature","id":"410000","properties":{"name":"河南省","cp":[113.726647,34.774564],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[113.726647,34.774564]]]}},{"type":"Feature","id":"420000","properties":{"name":"湖北省","cp":[114.341867,30.546524],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[114.341867,30.546524]]]}},{"type":"Feature","id":"430000","properties":{"name":"湖南省","cp":[112.938814,28.228209],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[112.938814,28.228209]]]}},{"type":"Feature","id":"440000","properties":{"name":"广东省","cp":[113.264385,23.12911],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[113.264385,23.12911]]]}},{"type":"Feature","id":"450000","properties":{"name":"广西壮族自治区","cp":[108.320004,22.824027],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[108.320004,22.824027]]]}},{"type":"Feature","id":"460000","properties":{"name":"海南省","cp":[110.33119,20.031971],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[110.33119,20.031971]]]}},{"type":"Feature","id":"500000","properties":{"name":"重庆市","cp":[106.551559,29.563009],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[106.551559,29.563009]]]}},{"type":"Feature","id":"510000","properties":{"name":"四川省","cp":[104.065735,30.659462],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[104.065735,30.659462]]]}},{"type":"Feature","id":"520000","properties":{"name":"贵州省","cp":[106.713708,26.578343],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[106.713708,26.578343]]]}},{"type":"Feature","id":"530000","properties":{"name":"云南省","cp":[102.712251,24.880109],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[102.712251,24.880109]]]}},{"type":"Feature","id":"540000","properties":{"name":"西藏自治区","cp":[91.132213,29.392428],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[91.132213,29.392428]]]}},{"type":"Feature","id":"610000","properties":{"name":"陕西省","cp":[108.948024,34.263161],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[108.948024,34.263161]]]}},{"type":"Feature","id":"620000","properties":{"name":"甘肃省","cp":[103.823557,36.058039],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[103.823557,36.058039]]]}},{"type":"Feature","id":"630000","properties":{"name":"青海省","cp":[101.777827,36.623177],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[101.777827,36.623177]]]}},{"type":"Feature","id":"640000","properties":{"name":"宁夏回族自治区","cp":[106.278179,37.387761],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[106.278179,37.387761]]]}},{"type":"Feature","id":"650000","properties":{"name":"新疆维吾尔自治区","cp":[87.616892,43.588249],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[87.616892,43.588249]]]}},{"type":"Feature","id":"710000","properties":{"name":"台湾省","cp":[121.520076,25.030724],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[121.520076,25.030724]]]}},{"type":"Feature","id":"810000","properties":{"name":"香港特别行政区","cp":[114.173355,22.320048],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[114.173355,22.320048]]]}},{"type":"Feature","id":"820000","properties":{"name":"澳门特别行政区","cp":[113.54909,22.198951],"childNum":1},"geometry":{"type":"Polygon","coordinates":[[[113.54909,22.198951]]]}}]};
const myChart = echarts.init(document.getElementById('map'));
echarts.registerMap('china', chinaJson);
const points = [
{ name: '西藏', lnglat: [88, 30], label: '100万' },
{ name: '青海', lnglat: [96, 36], label: '10万' },
{ name: '四川', lnglat: [104, 31], label: '100万' },
{ name: '云南', lnglat: [102, 25], label: '100万' },
{ name: '贵州', lnglat: [107, 27], label: '100万' },
];
window.onload = function(){
const option = {
backgroundColor:'#081734',
geo:{map:'china',roam:false,zoom:1.15,center:[100,33],itemStyle:{areaColor:'#0A3D7A',borderColor:'#4ECDC4',borderWidth:1.5},emphasis:{itemStyle:{areaColor:'#1A5FA8'}},label:{show:true,color:'rgba(255,255,255,0.7)',fontSize:13}},
series:[
{type:'effectScatter',coordinateSystem:'geo',symbolSize:14,rippleEffect:{brushType:'stroke',scale:5,period:3.5},itemStyle:{color:'#4ECDC4',shadowBlur:15},data:points.map(p=>({name:p.name,value:p.lnglat}))},
{type:'scatter',coordinateSystem:'geo',symbolSize:8,itemStyle:{color:'#4ECDC4'},data:points.map(p=>({name:p.name,value:p.lnglat}))},
{type:'lines',coordinateSystem:'geo',lineStyle:{color:'#4ECDC4',width:2},data:points.map(p=>({coords:[p.lnglat,[p.lnglat[0],p.lnglat[1]+2.5]]}))},
{type:'scatter',coordinateSystem:'geo',symbolSize:0,label:{show:true,position:'right',formatter:params=>points.find(i=>i.name===params.name)?.label||'',backgroundColor:'rgba(10,30,50,0.9)',borderColor:'#4ECDC4',borderWidth:1,borderRadius:10,padding:[10,18],color:'#fff',fontSize:16},data:points.map(p=>({name:p.name,value:[p.lnglat[0],p.lnglat[1]+2.5]}))}
]
};
myChart.setOption(option);
window.addEventListener('resize',()=>myChart.resize());
}
</script>
</body>
</html>