echarts 实现高亮轮廓的中国地图

194 阅读2分钟

实现高亮轮廓的中国地图,并且

一、效果展示

屏幕截图 2025-06-30 112549.png

二、实现步骤

  1. 安装echarts
npm install echarts --save
  1. 获取中国地图数据和轮廓地图数据

    数据来源:阿里云DataV数据可视化平台 datav.aliyun.com/portal/scho…

    中国地图数据

image.png

中国轮廓地图数据

image.png

  1. 创建地图
<template>
  <div class="page-wrapper">
    <div ref="mapContainer" style="width: 100%; height: 100%"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import chinaJson from './assets/chinaMap.json'
import chinaMapOutline from './assets/chinaMapOutline.json'
const mapContainer = ref(null)

let chart = null
// 飞线数据 - 湖北到其他省份
const flyLines = [
  { from: '湖北', to: '内蒙古' },
  { from: '湖北', to: '新疆' },
  { from: '湖北', to: '青海' },
  { from: '湖北', to: '四川' },
  { from: '湖北', to: '云南' }
]

// 省份坐标数据
const provinceCoords = {
  '湖北': [114.30, 30.60], // 武汉
  '内蒙古': [111.65, 40.82], // 呼和浩特
  '新疆': [87.68, 43.77], // 乌鲁木齐
  '青海': [101.74, 36.56], // 西宁
  '四川': [104.06, 30.67], // 成都
  '云南': [102.73, 25.04] // 昆明
}
function initMap() {
  if (!mapContainer.value) return
  chart = echarts.init(mapContainer.value)
  echarts.registerMap('china', chinaJson)
  echarts.registerMap('chinaMapOutline', chinaMapOutline)

  // 生成飞线数据
  const lineData = flyLines.map(item => ({
    coords: [provinceCoords[item.from], provinceCoords[item.to]]
  }))

  const option = {
    animation: false, // 禁用全局动画
    // 添加地理坐标系配置
    geo: {
      map: 'china',
      center: [104.4, 35],
      zoom: 1.3,
      zlevel: 20,
      itemStyle: {
        areaColor: 'transparent',
        borderColor: '#53FEFF',
        borderWidth: 3
      },
      // 移除emphasis配置以禁用悬停效果
      emphasis: {
        disabled: true, // 禁用悬停效果
        label: {
          show: false // 不显示悬停标签
        },
        itemStyle: {
          areaColor: 'transparent' // 悬停时保持透明
        }
      }
    },
    series: [
      // 中国地图-外轮廓
      {
        type: 'map',
        map: 'chinaMapOutline',
        zlevel: 1,
        center: [104.4, 35],
        zoom: 1.3,
        itemStyle: {
          normal: {
            areaColor: 'transparent',
            borderWidth: 1,
            borderColor: '#379aa5',
            shadowBlur: 0,
            shadowColor: '#379aa5',
            shadowOffsetX: 0,
            shadowOffsetY: 0
          }
        },
        label: {
          show: true,
          color: '#e6e6e6',
          fontSize: 10,
          // offset: [10, -10],
          fontWeight: 'normal',
          formatter: (params) => {
            if (params.name === '内蒙古自治区') return '内蒙古'
            if (params.name === '黑龙江省') return '黑龙江'
            if (params.name === '澳门特别行政区') return ''
            if (params.name === '香港特别行政区') return ''
            return params.name.substring(0, 2)
          }
        },
        emphasis: {
          disabled: true,
          itemStyle: {
            areaColor: 'transparent'
          }
        }
      },
      // 飞线系列 - 必须放在地理坐标系之后
      {
        type: 'lines',
        coordinateSystem: 'geo', // 指定使用geo坐标系
        zlevel: 15,
        effect: {
          show: true,
          period: 3,
          trailLength: 0.2,
          symbol: 'arrow',
          symbolSize: 6,
          color: '#FFCF0F'
        },
        lineStyle: {
          width: 1,
          opacity: 0.8,
          curveness: 0.3,
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 1,
            y2: 0,
            colorStops: [
              { offset: 0, color: 'rgba(255, 207, 15, 1)' }, // #D8D8D8 10%
              { offset: 1, color: 'rgba(216, 216, 216, 0.1)' } // #FFCF0F 100%
            ]
          }
        },
        data: lineData,
        emphasis: {
          disabled: true
        }
      },
      // 标记点
      {
        name: '标记点',
        type: 'scatter',
        coordinateSystem: 'geo', // 指定使用geo坐标系
        zlevel: 20,
        symbolSize: 8,
        itemStyle: {
          color: '#FFCF0F'
        },
        data: Object.keys(provinceCoords).map(province => ({
          name: province,
          value: provinceCoords[province]
        })),
        emphasis: {
          disabled: true
        }
      }
    ]
  }

  chart.setOption(option)
  // 优化resize处理
  const resizeHandler = () => {
    if (chart) {
      chart.resize()
    }
  }
  // 使用防抖
  let resizeTimer = null
  window.addEventListener('resize', () => {
    clearTimeout(resizeTimer)
    resizeTimer = setTimeout(resizeHandler, 200)
  })
}

// 添加销毁处理
onUnmounted(() => {
  if (chart) {
    chart.dispose()
    chart = null
  }
})

onMounted(async() => {
  initMap()
})
</script>

<style scoped>
.page-wrapper {
  width: 100vw;
  height: 100vh;
  background-color: rgb(4, 12, 25);
}
</style>

附上完整代码地址:gitee.com/TriF/echart…