效果图
业务组件
<template>
<mapEcharts
:itemStyle="mapProps.itemStyle"
:emphasisLabelStyle="mapProps.emphasisLabelStyle"
:emphasisItemStyle="mapProps.emphasisItemStyle"
:labelInfo="mapProps.labelInfo"
:rippleEffect="mapProps.rippleEffect"
:tooltipProps="mapProps.tooltipProps"
:tooltipFormat="mapProps.tooltipFormat"
:itemColorFormat="mapProps.itemColorFormat"
:seriesData="mapProps.seriesData">
</mapEcharts>
</template>
<script setup lang="ts">
const mapProps = reactive({
idType:"0",
jsonData:{
},
itemStyle: {
areaColor: '#186894',//区域颜色
shadowColor: '#2894c9',//边缘阴影颜色
color: 'rgba(255, 255, 255, 1)'//文字颜色
},
emphasisLabelStyle: {
color: "rgba(255, 255, 255, 1)"
},
emphasisItemStyle: {
areaColor: '#39baf6',
shadowColor: '#2894c9',
},
labelInfo: {
show: true,
color: 'rgba(255,255,255,0.6)',
position: 'inside',
distance: 0,
fontSize: 10,
rotate: 0,
},
rippleEffect: {
number: 4,
period: 4,
scale: 4.5,
brushType: 'fill'
},
tooltipProps: {
show: true,
shadowColor: 'rgba(0, 0, 0, 0)', // 设置阴影颜色为透明
shadowBlur: 0, // 设置阴影模糊度为0,即无阴影
backgroundColor: "rgba(21, 29, 56,0)",
borderColor: "rgba(21, 29, 56,0)"
},
tooltipFormat: (params: any) => {
//弹窗提示的逻辑处理
console.log("params11", params)
const curItem = mapDataByProvice(params.name)
if(!curItem||!curItem.selfCount){
return ""
}
let fromatStr =
`<div style="background:url(${getImg('/src/assets/img/mapHoverBg.png')});width:324px;height:225px;background-size:contain;background-repeat:no-repeat;">
<div style="width: 100px;height: 90px;padding-top:4px;position:relative;">
<div style="position:absolute;left:20px;top:10px;font-weight:bold;color:#fff;">
${params.name}
</div>
<div style="position:absolute;left:120px;top:58px;color:#fff;width:120px;text-align:right;">
${curItem.selfCount}
</div>
<div style="position:absolute;left:135px;top:108px;color:#fff;width:120px;text-align:right;">
${curItem.toCount}
</div>
<div style="position:absolute;left:166px;top:158px;color:#fff;width:120px;text-align:right;">
${curItem.inCount}
</div>
</div>
</div>`
return fromatStr
},
itemColorFormat: (params: any) => {
//颜色的业务逻辑
console.log("params001", params)
if (params.value[2] > 0 && params.value[2] <= 100) {
return '#00ff31';
} else if (params.value[2] > 100 && params.value[2] <= 200) {
return '#f00';
} else if (params.value[2] > 200 && params.value[2] <= 300) {
return '#0ff';
} else if (params.value[2] > 300 && params.value[2] <= 400) {
return '#ff0';
}
},
effectScatterCallBack:(params:any)=>{
//散点点击触发的 业务逻辑
console.log("equipmentDialogRef",params)
equipmentDialogRef.value.open()
},
seriesData: [{ name: '肇庆市', value: [112.48461, 23.05196, 100] },
{ name: '佛山市', value: [110.130214, 23.018978, 200] },
{ name: '广州', value: [115.261081, 23.139856, 300] },
{ name: '南宁', value: [107.45, 22.139856, 400] },
{ name: '贵阳', value: [106.7, 26.36, 200] },
{ name: '昆明', value: [102.33, 24.23, 300] } ,
{ name: '海口', value: [110.33,19.823, 10] }]
})
const mapDataByProvice = (provinceName: String) => {
let listData = [
{
name: "广东省",
selfCount: 123,
toCount: 300,
inCount: 987
},
{
name: "广西壮族自治区",
selfCount: 23,
toCount: 55,
inCount: 278
},
{
name: "云南省",
selfCount: 256,
toCount: 2456,
inCount: 745
},
{
name: "贵州省",
selfCount: 963,
toCount: 4521,
inCount: 963
}
]
const curItem: any = listData.find(ele => ele.name == provinceName)
return curItem
}
</script>
封装组件
<template>
<div :id="'mapEcharts' + idType" style="width: 100%;height: 100%;" ></div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts'
const propsVal: any = defineProps({
idType: {
type: String,
default: '0'
},
jsonData: {
type: Object,
default: {
}
},
title: {//标题
type: Object,
default: {
}
},
itemStyle: {//地图项样式
type: Object,
default: {
areaColor: '#186894',//区域颜色
shadowColor: '#2894c9',//边缘阴影颜色
color: 'rgba(255, 255, 255, 1)'//文字颜色
}
},
emphasisLabelStyle: {//鼠标移入 文本 label 高亮的样式
type: Object,
default: {
color: "rgba(255, 255, 255, 1)"
}
},
emphasisItemStyle: {//鼠标移入 地图高亮样式
type: Object,
default: {
areaColor: '#39baf6',
shadowColor: '#2894c9',
}
},
labelInfo: {
type: Object,//地图标签配置 如 云南省等
default: {
show: true,
color: 'rgba(255,255,255,0.6)',
position: 'inside',
distance: 0,
fontSize: 10,
rotate: 0,
}
},
rippleEffect: {//点的闪烁配置
type: Object,
default: {
number: 4,
period: 4,
scale: 4.5,
brushType: 'fill'
}
},
tooltipProps: {//鼠标移动提示框的样式
type: Object,
default: {
show: false,//是否显示,默认不显示
backgroundColor: '#fff'//提示框的背景色
}
},
tooltipFormat: {//提示 格式
type: Function,
default: () => { }
},
itemColorFormat: {//颜色格式化
type: Function,
default: () => { }
},
seriesData: {//地图点标记数据
type: Array,
default: []
},
effectScatterCallBack: {//effectScatter 点击事件
type: Function,
default: () => { }
},
})
const initEcharts = () => {
echarts.registerMap('guangdong', propsVal.jsonData)
nextTick(() => {
const domitem = document.getElementById("mapEcharts" + propsVal.idType)
const map = echarts.init(domitem, null, {
renderer: 'canvas',
})
const option = {
title: propsVal.title,
// 悬浮窗
tooltip: {
trigger: 'item',//触发条件
},
geo: {
map: 'guangdong',
zoom: 1,
roam: '',
label: propsVal.labelInfo,
// 所有地图的区域颜色
itemStyle: propsVal.itemStyle,
emphasis: {
label: propsVal.emphasisLabelStyle,
itemStyle: propsVal.emphasisItemStyle
},
tooltip: {
...propsVal.tooltipProps,
formatter: (params: any) => {
return propsVal.tooltipFormat(params)
}
}
},
series: [
{
name: 'Top 5',
type: 'effectScatter',
colorBy: 'series',
effectType: 'ripple',
showEffectOn: 'render',
rippleEffect: propsVal.rippleEffect,
itemStyle: {
color: (params: any) => {
return propsVal.itemColorFormat(params)
}
},
coordinateSystem: 'geo',
data: propsVal.seriesData,
},
{
name: 'eventDom',
type: 'scatter',
coordinateSystem: 'geo',
data: propsVal.seriesData,
symbolSize: 32,
itemStyle: {
color:"rgba(255,255,255,0)"
},
},
],
}
map.setOption(option)
chartClickEventListener(map)
})
}
onMounted(() => {
console.log("propsval", propsVal)
initEcharts()
})
const chartClickEventListener = (mychart: any) => {
mychart.on("click", (parmas: any) => {
propsVal.effectScatterCallBack(parmas)
})
}
const chagneJSON = (item: any) => {
console.log("propsval", propsVal)
propsVal.idType = item.navId
setTimeout(() => {
initEcharts()
})
}
defineExpose({
chagneJSON
})
</script>
<style scoped>
.map-echart {
height: 600px;
width: 900px;
}
</style>