echarts 地图

效果图

业务组件

html 复制代码
<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>

封装组件

html 复制代码
<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>
相关推荐
书中自有妍如玉38 分钟前
layui时间选择器选择周 日月季度年
前端·javascript·layui
Riesenzahn38 分钟前
canvas生成图片有没有跨域问题?如果有如何解决?
前端·javascript
f89790707041 分钟前
layui 可以使点击图片放大
前端·javascript·layui
小贵子的博客41 分钟前
ElementUI 用span-method实现循环el-table组件的合并行功能
javascript·vue.js·elementui
明似水1 小时前
掌握 Flutter 中的 `Overlay` 和 `OverlayEntry`:弹窗管理的艺术
javascript·flutter
忘不了情1 小时前
左键选择v-html绑定的文本内容,松开鼠标后出现复制弹窗
前端·javascript·html
笃励1 小时前
Angular面试题四
前端·javascript·angular.js
前端专业写bug1 小时前
jspdf踩坑 htmltocanvas
java·前端·javascript
哈哈哈hhhhhh1 小时前
vue 入门一
前端·javascript·vue.js
小嘟嚷ovo1 小时前
markdown-it:将Markdown文本转换为HTML格式,展示在页面,怎么自定义里面的a标签设置为在新标签页打开
前端·javascript·html