我采用的是Echarts.js这个实现的具体实现步骤如下:
先上个图吧:
1.首先下载Echarts.js
npm install echarts
2.不废话喜欢上图
其它的地方没啥难的,我直接把代码丢这里,是vue3加ts写的已经封装好了
<template>
<div class="warpMap">
<div id="map" class="maps">
</div>
</div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts'
import { reactive, ref, onMounted, nextTick } from 'vue'
import { getAssetsFile } from "../../utils/putUse"
import axios from 'axios';
const props = defineProps({
dataList: {
type: Array,
default: [],
}
})
const seriesData = ref([])
const scatterData = ref([])
const myChart = ref()
onMounted(() => {
nextTick(() => {
getDt()
})
})
const getDt = () => {
//地图区域的数据
const JJJ = "https://geo.datav.aliyun.com/areas_v3/bound/420000_full.json";
var chartDom: any = document.getElementById('map');
myChart.value = echarts.init(chartDom);
axios.get(JJJ).then((mapData: any) => {
echarts.registerMap('JJJ', mapData.data);
// myChart.hideLoading();
const geoCoordMap: any = {
'武汉市': [114.296063, 30.598716],
'黄石市': [115.03518, 30.008966],
'十堰市': [110.795905, 32.623143],
'宜昌市': [111.283353, 30.685769],
'襄阳市': [112.119909, 32.009653],
'鄂州市': [115.056551, 30.377069],
'荆门市': [112.201215, 31.034059],
'孝感市': [113.665191, 31.12279],
'荆州市': [112.243219, 30.333612],
'黄冈市': [114.930806, 31.208407],
'咸宁市': [114.328519, 29.847808],
'随州市': [113.386573, 32.096762],
'恩施州': [109.492868, 30.303635],
'神农架': [110.582522, 31.850251]
};
seriesData.value = [
{
name: "武汉市",
value: 2350,
},
{
name: "黄石市",
value: 3231
},
{
name: "十堰市",
value: 1234
},
{
name: "宜昌市",
value: 1234
},
{
name: "襄阳市",
value: 1234
},
{
name: "鄂州市",
value: 1234
},
{
name: "荆门市",
value: 1234
},
{
name: "孝感市",
value: 1234
},
{
name: "荆州市",
value: 1234
},
{
name: "黄冈市",
value: 1234
},
{
name: "咸宁市",
value: 1234
},
{
name: "随州市",
value: 1234
},
{
name: "恩施州",
value: 1234
},
{
name: "神农架",
value: 1234
},
];
for (var i = 0; i < seriesData.value.length; i++) {
var geoCoord = geoCoordMap[seriesData.value[i].name];
if (geoCoord) {
scatterData.value.push({
name: seriesData.value[i].name,
value: geoCoord.concat(seriesData.value[i].value),
symbol: `image://${getAssetsFile('img/noh.png')}`, // 设置自定义图标的URL
label: {
show: true,
formatter(params) {
return `{a|${params.name}}`;
},
rotate: -22,
rich: {
a: {
color: "#fff",
fontSize: "16px",
padding: [8, 5, 8, 5],
backgroundColor: "rgba(58, 129, 130,1)",
// backgroundColor: "#005975",
borderColor: "#27F2FF",
borderWidth: 0.5,
angle: -22,
},
},
offset: [0, -55],
},
});
}
}
let option = {
tooltip: {
trigger: "item",
showContent: true, //是否显示提示框浮层,默认显示
alwaysShowContent: false, //是否永远显示提示框内容,默认情况下在移出可触发提示框区域后 一定时间 后隐藏,设置为 true 可以保证一直显示提示框内容
hideDelay: 0, //鼠标移出坐标点时,浮层隐藏的延迟时间,单位为 ms,在 alwaysShowContent 为 true 的时候无效
// enterable: true,
triggerOn: 'click',
extraCssText: 'margin: 0px; padding: 0px;', // 设置 margin 和 padding 来调整距离
formatter: (params) => {
let rotatedContent
props.dataList.forEach((item: any) => {
if (item.area == params.name) {
rotatedContent = `
<div class="Pop">
<div class="item">
<div class="name">
地调推送
</div>
<div class="num">
${item.dd}
</div>
</div>
<div class="item">
<div class="name">
省调推送
</div>
<div class="num">
${item.sd}
</div>
</div>
<div class="item">
<div class="name">
量测中心推送
</div>
<div class="num">
${item.lc}
</div>
</div>
<div class="item">
<div class="name">
数据中台库
</div>
<div class="num">
${item.zt}
</div>
</div>
<div class="item">
<div class="name">
配自主站
</div>
<div class="num">
${item.zz}
</div>
</div>
<div class="item">
<div class="name">
遥脉
</div>
<div class="num">
${item.ym}
</div>
</div>
</div>
`; // 旋转 tooltip 内容
}
})
// var content = params.name; // 自定义 tooltip 内容
return rotatedContent;
},
backgroundColor: 'rgba(0, 0, 0, 0.0)',
borderColor: 'rgba(0, 0, 0, 0.0)',
shadowColor: 'rgba(0, 0, 0, 0.0)',
},
geo: [
{
map: 'JJJ',
top: '4%',
silent: true,
label: {
show: false,
color: "#eee"
},
itemStyle: { //地图区域的多边形 图形样式
color: '#1962a5', //背景
borderColor: '#1962a5',//边框颜色
borderWidth: 3,
},
},
{
map: 'JJJ',
top: '2%',
silent: true,
label: {
show: false,
color: "#eee"
},
itemStyle: { //地图区域的多边形 图形样式
color: '#1d9edd', //背景
borderColor: '#1d9edd',//边框颜色
borderWidth: 3,
},
},
],
series: [
{
// name: `行业:全部`,
type: 'map',
silent: true,
mapType: 'JJJ',
top: '0%',//组件距离容器的距离
// zoom: 1.2,
label: {
show: false,
color: "#eee"
},
itemStyle: { //地图区域的多边形 图形样式
borderColor: '#d3f2ff',//边框颜色
borderWidth: 1,
areaColor: {
type: "map",
image: getAssetsFile('img/mapbg.png'),
repeat: "repeat",
global: false, // 缺省为 false
},
transform: 'rotate(-22deg)' // 旋转整个 tooltip 弹窗
},
data: seriesData.value
},
{
type: 'scatter',
coordinateSystem: 'geo',
color: 'rgba(209,250,12,0.5)',
symbolSize: [42, 40],
symbolRotate: -22,
// symbol: `image://${getAssetsFile('img/noh.png')}`,
// label: {
// show: true,
// formatter(params) {
// return `{a|${params.name}}`;
// },
// rotate: -22,
// rich: {
// a: {
// color: "#fff",
// fontSize: "16px",
// padding: [8, 5, 8, 5],
// backgroundColor: "rgba(58, 129, 130,1)",
// // backgroundColor: "#005975",
// borderColor: "#27F2FF",
// borderWidth: 0.5,
// angle: -22,
// },
// },
// offset: [0, -55],
// },
data: scatterData.value,
}
]
};
myChart.value.on("click", (params: any) => {
if (params.componentType == 'series') {
// 获取点击的数据项的索引
var dataIndex = params.dataIndex;
// 更新散点图的颜色
updateScatterColor(dataIndex);
}
})
myChart.value.setOption(option);
})
}
const updateScatterColor = (dataIndex) => {
// 获取当前散点图的配置项
var currentOption = myChart.value.getOption();
// 获取散点图系列的配置项
var seriesOption = currentOption.series[1];
// 获取当前散点图的数据
var data = seriesOption.data;
// 更新点击的数据项的符号样式
data.forEach((item) => {
item.symbol = `image://${getAssetsFile('img/noh.png')}`;
(item.symbolSize = [42, 40]),
(item.label = {
show: true,
formatter(params) {
return `{a|${params.name}}`;
},
rotate: -22,
rich: {
a: {
color: "#fff",
fontSize: "16px",
padding: [8, 5, 8, 5],
backgroundColor: "rgba(58, 129, 130,1)",
borderColor: "#fbf4b6",
borderWidth: 0.5,
},
},
offset: [0, -55],
});
});
data[dataIndex].symbol = `image://${getAssetsFile('img/ish.png')}`; // 这里可以根据需要设置新的符号样式
data[dataIndex].symbolSize = [52, 50]; // 这里可以根据需要设置新的符号样式
data[dataIndex].label.rich.a.backgroundColor = "#feac15"; // 这里可以根据需要设置新的符号样式
// 更新散点图的配置项
myChart.value.setOption(currentOption);
}
</script>
<style lang="scss" scoped>
.warpMap {
width: 100%;
height: 100%;
position: relative;
background: url('@/assets/img/mapgq.png') no-repeat;
background-size: 60% 62%;
background-position: 230px 123px;
.maps {
width: 100%;
height: 100%;
transform: rotate(-22deg);
}
}
</style>
<style lang="scss">
.Pop {
background: url('@/assets/img/maptc.png') no-repeat;
background-size: 100%;
width: 200px;
padding: 15px;
transform: rotate(22deg);
.item {
display: flex;
align-items: center;
justify-content: space-between;
margin: 7px 0;
.name {
font-size: 15px;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #E5FFFF;
}
.num {
font-size: 15px;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #FFC93E;
}
}
}
</style>