vue3+vite+echarts实现地图散点+hover有tooltip

400 阅读1分钟

前言

image.png

前端就是这个亚子永远都在学习新东西
接到这个需求我的第一方案是找开源的地图,在看了十几个开源地图之后锁定leaflet,一顿CV之后pr说样式不够好看,没办法只能用echarts搭配world.json手撸一个了

一、安装echarts并在main.js里引入

npm i echarts -D

我当时引入的时候有点问题因为我用的是vue3所以引入的写法会有点不一样 import { createApp } from 'vue'
import App from './App.vue'
import * as echarts from 'echarts'

const app = createApp(App)
app.config.globalProperties.$echarts = echarts
app.mount('#app') world.js文件可以放在公共资源的public里面(文件可以在github上面搜一个,一大堆)

二、在components目录下面创建一个Map.vue

<style>
	#myEcharts {
    width: 100vw;
		height: 700px;
    overflow-x: hidden;
	}
	.icon-type1 {
		width: 7px;
		height: 7px;
		border-radius: 50%;
		background: var(--theme-color);
	}
</style>

<template>
  <div id="myEcharts" ref="myEcharts" style="width: 100%; height: 100%"></div>
</template>

<script setup>
  import { onMounted, ref, nextTick, watch } from 'vue'
  import * as echarts from "echarts";
  import "leaflet/dist/leaflet.css";
  import world from '../../public/assets/map/world.json';
  // import china from '/assets/map/china.json';
  const myEcharts = ref()
  // 已上线
  // 散点数据
  const activeData = [
    {name:"London", value:[-0.130345,51.511834]},
    {name:"Amsterdam", value:[4.904139,52.367573]},
    {name:"Frankfurt", value:[8.67954,50.116651]},
    {name:"Beijing", value:[116.417124,39.91513]},
    {name:"Seoul", value:[126.963884,37.601537]},
    {name:"Tokyo", value:[139.770924,35.724525]},
    {name:"Shanghai ", value:[121.479103,31.237658]},
    {name:"Taipei", value:[121.571725,25.041583]},
    {name:"Hong Kong", value:[114.173181,22.282127]},
    {name:"Guangzhou", value:[113.269992,23.136665]},
    {name:"Manila", value:[121.021037,14.616925]},
    {name:"Kuala Lumpur", value:[101.683118,3.147961]},
    {name:"Singapore", value:[103.865874,1.363204]},
    {name:"Jakarta", value:[106.844015,-6.199943]},
    {name:"Surabaya", value:[112.730923,-7.256737]},
    {name:"Los Angeles", value:[-118.246182,34.058993]},
    {name:"Chicago", value:[-87.633312,41.888331]},
    {name:"Dallas", value:[-96.796126,32.779821]},
    {name:"New York", value:[-73.866264,40.850676]},
    {name:"New Jersey", value:[-74.652587,40.204178]},
    {name:"Sao Paulo", value:[-93.09657,44.945333]},
  ]
  // 建设中
  const constructionData = [
    {name:"Helsinki", value:[24.94147,60.171284]},
    {name:"Stockholm", value:[18.059962,59.338171]},
    {name:"Moscow", value:[37.606099,55.765875]},
    {name:"Dublin", value:[-6.262487,53.364771]},
    {name:"Paris", value:[2.330663,48.869702]},
    {name:"Marseille", value:[2.363254,48.871337]},
    {name:"Madrid", value:[-3.705802,40.423586]},
    {name:"Lisbon", value:[-9.163191,38.768858]},
    {name:"Milan", value:[9.187395,45.466023]},
    {name:"Warsaw", value:[21.018266,52.237264]},
    {name:"Sofia", value:[21.014048,52.218414]},
    {name:"Istanbul", value:[28.970023,41.013682]},
    {name:"Dubai", value:[55.301069,25.270304]},
    {name:"Fujairah", value:[56.326854,25.129853]},
    {name:"Lagos", value:[3.711151,6.535943]},
    {name:"Mumbai", value:[72.830365,18.981282]},
    {name:"New Delhi", value:[77.105415,28.71266]},
    {name:"Chennai", value:[80.269101,13.088448]},
    {name:"Ho Chi Minh", value:[106.68284,10.7696]},
    {name:"Bangkok", value:[100.446391,13.753354]},
    {name:"Osaka", value:[135.501878,34.716766]},
    {name:"Johannesburg", value:[28.025621,-26.189498]},
    {name:"Perth", value:[115.855155,-31.944378]},
    {name:"Adelaide", value:[138.598734,-34.915003]},
    {name:"Melbourne", value:[144.945523,-37.796978]},
    {name:"Sydney", value:[151.207284,-33.853711]},
    {name:"Brisbane", value:[153.063735,-27.543081]},
    {name:"Seattle", value:[-122.330887,47.606878]},
    {name:"San Jose", value:[-121.889157,37.342552]},
    {name:"Denver", value:[-104.983267,39.726041]},
    {name:"Toronto", value:[-79.383471,43.659279]},
    {name:"Miami", value:[-80.199167,25.778194]},
    {name:"Mexico City", value:[-99.133093,19.432614]},
    {name:"Bogta", value:[-74.07123,4.719642]},
    {name:"Rio De Janeiro", value:[-43.179508,-22.902852]},
  ]
watch()
  const initMap = () => {
    nextTick(() => {
      echarts.registerMap('world', world)
      const myChart = echarts.init(myEcharts.value, '')
      const option = {
        title: {
                left: 'center',
        },
        geo: {
                map: 'world',
                aspectScale: 0.8, //长宽比
                zoom: 1.0,
                roam: true,
        layoutCenter: ['60%', '50%'],
        layoutSize:'150%',
        scaleLimit: {
          min: 1.1,
          max: 3
        },
        itemStyle: {
          normal: {
            show: true,
            textStyle: {
              color: 'white'
            },
            borderColor: '#797979',
            borderWidth: 1,
            areaColor: {
              type: 'radial',
              x: 0.5,
              y: 0.5,
              r: 0.8,
              colorStops: [
                {
                  offset: 0,
                  color: '#363636', // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: '#363636', // 100% 处的颜色
                },
              ],
              globalCoord: true, // 缺省为 false
            },
          },
          emphasis: {
            color: 'white',
            areaColor: '#555',
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            borderWidth: 0,
          },
        },
        label: {
          emphasis: {
            show: true,
            textStyle: {
              fontSize: '16px',
              color: '#fff'
            }
          }
        }
    },
    series: [
           {
          type: 'effectScatter',
          symbolSize: 8,
          name: 'active',
	  map: 'world',
          showEffectOn:'render',
          rippleEffect:{ 
             color:'#24A148',
             brushType:'stroke',
             period: 7,   
             scale:'4',  
          },
          itemStyle: {
            normal: {
              color:'#24A148'
            }
          },
        coordinateSystem:"geo",
	data: activeData,
	},
        {
	  type: 'scatter',
          symbolSize: 8,
          name: 'construction',
	  map: 'world',
          itemStyle: {
            normal: {
              color:'#FF832B'
            }
          },
          coordinateSystem:"geo",
	  data: constructionData,
            },
    ],
      tooltip: {
        trigger: 'item',
        formatter:function(params){
			    return params.name + '</br>' + '&nbsp<span style="font-size:12px; color: #999">ECS</span>'+'</br>'+'&nbsp<span style="font-size:12px; color: #999">IPT</span>'+'</br>'+'&nbsp<span style="font-size:12px; color: #999">BMS</span>'
        }
      }
      }
      myChart.setOption(option)
    })
  }
  onMounted(() => {
   initMap()

});
</script>