Vue3 + ECharts 实现地图显示,深蓝色科技风地图、涟漪点、向上连线 ,标签

项目依赖:echarts@5.4.3

复制代码
npm install echarts@5.4.3

地图数据获取

  • 你可以从 阿里云 DataV 下载标准的 china.json,放到项目的 src/assets/ 目录下即可。

echarts 参数配置

效果 实现方式
带涟漪的发光点 effectScatter 系列,配合 rippleEffectshadowBlur
向上的蓝线 lines 系列,curveness: 0 画直线,从点的位置向上延伸
带背景的标签 scatter 系列,symbolSize: 0 隐藏圆点,用 label 实现文字框
深蓝色科技风 统一 backgroundColorgeo.itemStyle.areaColoritemStyle.color 为同色系

可调整的参数

  • pointData 里的经纬度可以改成你实际业务的坐标
  • lat + 2 控制连线的高度,数值越大,线越长
  • geo.centergeo.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>
相关推荐
iuu_star1 小时前
跑通最简单的Vue3+Python前后端分离项目
前端·vue.js·python
AIGC大时代1 小时前
从识图模型、平价 Mac 到智能汽车:科技产品正在进入交付能力竞争
科技·ai·科普
YJlio2 小时前
2023-09-25:ChatGPT 开始支持“看、听、说”,从纯文本正式迈向多模态交互
人工智能·python·科技·chatgpt·django·交互·pygame
码海扬帆:前端探索之旅10 小时前
深度定制 uni-combox:新增功能详解与实战指南
前端·vue.js·uni-app
jieyucx10 小时前
Go语言深度解剖:Map扩容机制全解析(增量扩容+等量扩容+渐进式迁移)
开发语言·后端·golang·map·扩容策略
葫三生11 小时前
《论三生原理》系列构建文理同构的认知体系?
人工智能·科技·深度学习·算法·机器学习·transformer
换日线°14 小时前
vue 加入购物车抛物线动画
前端·javascript·vue.js
计算机学姐14 小时前
基于微信小程序的图书馆座位预约系统【uniapp+springboot+vue】
vue.js·spring boot·微信小程序·小程序·java-ee·uni-app·intellij-idea
数智大号15 小时前
信通院互联互通测试全面通过-航天万源云数据可信数控空间
科技