【echarts 4.x+Vue】实现中国地图(气泡图)+自定义点击事件

Vue内使用echarts(4.9.0版本)插件,绘制气泡地图,含默认高亮区域和地图自定义点击事件。效果和全部代码如下:

展示效果

1. 静态图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 动态图

在这里插入图片描述

代码部分

1. template部分

<template>
    <div class="china-map">
        <p class="title">{{nowProvince}}</p>
        <!-- 左上角固定框部分 -->
        <div class="left">
            <ul class="left_ul">
                <li 
                    class="left_li"
                    v-for="(item, index) of provinceInfo"
                    :key="index"
                    :style="{'--color': item.color}"
                >
                    <span>{{item.value}}</span>
                    <label>{{item.name}}</label>
                </li>
            </ul>
        </div>
        <!-- 地图 -->
        <div id="chinaMapEle"></div>
    </div>
</template>

2. Js部分

<script>
import "echarts/map/js/china.js";//注册地图铺底的中国省份数据,注意:仅echarts 4.x版本才有map文件夹,5.x版本取消map文件了
import echarts from "echarts";

export default {
    name: "ChinaMap",
    data() {
        return {
            nowProvince: "上海",//记录当前选中(高亮)区域的省份名称
            chart: null, //图表的dom
            chinaData: [],//全国34个省份的基础数据
            scatterData: [],//气泡的基础数据
            provinceInfo: [//左上角固定框部分内容
                {name: "公司总数", value: 0, color: "#94BCFF"},
                {name: "小微企业数", value: 0, color: "#94BCFF"},
                {name: "中型企业数", value: 0, color: "#41D2BD"},
                {name: "大型企业数", value: 0, color: "#FFD394"},
            ]
        }
    },
    created() {
        this.chinaData = echarts.getMap("china").geoJson.features;//获取全国34个省份的基础数据
        this.scatterData = this.setScatterData();//设置气泡数据
        this.getProniceData('310000');//上海Id:310000
    },

    mounted() {
        this.chart = echarts.init(document.getElementById("chinaMapEle"));
        this.drawMap();
    },

    methods: {
        drawMap() {
            let options = {//每个属性含义可参考echarts官网的配置手册进行了解
                geo: {
                    map: "china",
                    center: "",
                    zoom: 1.1,
                    itemStyle: {//地图各省份区域属性
                        areaColor: "rgba(129, 156, 230, 0.3)",
                        borderColor: "rgba(142, 171, 255, 0.2)",
                        borderWidth: 2
                    },
                    emphasis: {//区域高亮时属性
                        label: {
                            show: false,
                        },
                        itemStyle: {
                            areaColor: "rgba(129, 156, 230, 0.3)",
                            borderColor: "#94BCFF",
                            borderWidth: 3,
                            shadowColor: "#94BCFF",
                            shadowBlur: 5
                        }
                    }
                },
                series: [
                    {//地图层:属性见上述geo
                        type: "map",
                        map: "china",
                        geoIndex: 0
                    },
                    {//气泡层
                        name: "气泡",
                        type: "scatter",
                        coordinateSystem: "geo",
                        symbolSize: 10,//统一设置气泡大小为10。也可以在data内根据value[3]数值来设置气泡的不同大小
                        label: {//气泡和文字标签
                            show: true,
                            color: "#FFFFFF",
                            formatter: "{b}",//就是省份名-name
                            position: "top",
                            distance: 3,//省份名与气泡之间的距离
                        },
                        itemStyle: {//气泡属性
                            color: "#94BCFF",
                            borderColor: "rgba(148, 188, 255, 0.2)",
                            borderWidth: 5
                        },
                        emphasis: {//高亮时属性
                            label: {
                                show: true,
                                fontSize: 18,
                                fontWeight: "bold",
                            },
                            itemStyle: {
                                color: "#FFFFFF",
                                borderColor: "#94BCFF",
                                borderWidth: 3,
                                shadowColor: "#94BCFF",
                                shadowBlur: 10
                            }
                        },
                        data: this.scatterData,
                    }
                ],
            };
            this.chart.setOption(options);
            this.setAreaHighlight(this.nowProvince);//设置默认高亮区域
            
            //监听地图点击事件
            this.chart.off("click");
            this.chart.on("click", params => this.handleMapClick(params));
        },
        /**
         * 初始化气泡数据集合
         * return 返回的数据结构:
         *  [
         *      { id: "省份Id", name: "省份名称", value: [经度, 纬度, 固定数值1]},
         *      { id: "省份Id", name: "省份名称", value: [经度, 纬度, 固定数值1]},
         *  ]
         * 固定数值1: 通常被用来作为设置气泡大小的依据。
        */
        setScatterData() {
            let scatterData = [];
            this.chinaData.forEach(province => {
                scatterData.push({
                    id: province.id,//省份id,一般用于请求数据的唯一参数标识
                    name: province.properties.name,
                    value: [...province.properties.cp, 1]
                })
            })
            return scatterData;
        },

        /**
         * 设置区域高亮
         * @param name series中的name值,也是区域(省份)名称
        */
        setAreaHighlight(name) {
            this.chart.dispatchAction({
                type: "highlight",
                seriesIndex: 0,//地图层
                name: name
            });
            this.chart.dispatchAction({
                type: "highlight",
                seriesIndex: 1,//气泡层
                name: name
            });
        },
        /**
         * 取消区域高亮
         * @param name series中的name值,也是区域(省份)名称
        */
        setAreaDownplay(name) {
            this.chart.dispatchAction({
                type: "downplay",
                seriesIndex: 0,//地图层
                name: name
            });
            this.chart.dispatchAction({
                type: "downplay",
                seriesIndex: 1,//气泡层
                name: name
            });
        },

        /**
         * 区域点击后的动作
         * @param data 击中的seriesIndex之dataIndex的对象信息{}
        */
        handleMapClick(data) {
            let { name, dataIndex } = data;
            
            //判断击中区域是否为当前高亮区域,若是则不做任何动作;若不是则替换高亮区域
            if(name !== this.nowProvince) {
                this.setAreaDownplay(this.nowProvince);//1.将原来的高亮区域取消
                this.nowProvince = name; //2. 记录最新的高亮区域(省份)名称
                this.setAreaHighlight(this.nowProvince);//3.将新的区域置为高亮
                if(this.scatterData[dataIndex]) {//铺底数据内含有此省份id信息
                    this.getProniceData(this.scatterData[dataIndex].id);//4.(可选)自定义请求数据
                }else {//铺底数据内不含有此省份id信息
                    this.getProniceData('-1');//4.(可选)自定义请求数据
                }
                
            }
        },

        /**
         * 获取省份的数据
         * @param proId 省份Id
        */
        getProniceData(pronId) {
            // console.log("这里可自定义一些数据处理逻辑");
            for(let i=0; i<4; i++) {
                this.provinceInfo[i].value = pronId === '-1' ? 0 : Number((Math.random() * 10000).toFixed(0)).toLocaleString();//number.toLocaleString()  添加千分符
            }
        }
    }
}
</script>

3. CSS部分

<style scoped>
	.china-map {
	    width: 700px;
	    height: 500px;
	    background-color: #0B1F4F;
	    position: relative;
	    overflow: hidden;
	}
	/* 地图背景光圈 */
	.china-map::before {
	    content: " ";
	    position: absolute;
	    left: 20%;
	    top: 15%;
	    width: 500px;
	    height: 500px;
	    border-radius: 50%;
	    background-image: radial-gradient(circle, #395AAC, #172E63, #122555, #0E2251);
	}
	/* 顶部省份名称 */
	.title {
	    position: absolute;
	    top: 0;
	    left: 50%;
	    z-index: 2;
	    transform: translateX(-50%);
	    background-color: rgba(148, 188, 255, 0.5);
	    box-shadow: inset 0 0 8px 0 rgba(148, 188, 255, 1);
	    border-radius: 4px;
	    font-size: 16px;
	    font-weight: 400;
	    font-family: PingFangSC-Regular;
	    color: #FFFFFF;
	    letter-spacing: 3px;
	    line-height: 16px;
	    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
	    padding: 8px 20px;
	}
	/* 左上角-框体内容 */
	.left {
	    position: absolute;
	    top: 0;
	    left: 0;
	    z-index: 2;
	    background-color: rgba(72, 107, 204, 0.1);
	    box-shadow: inset 0 0 4px 0 rgba(148, 188, 255, 1);
	}
	/* 去除ul默认样式 */
	ul {
	    padding: 0;
	    margin: 0;
	}
	.left_ul {
	    width: 180px;
	    display: flex;
	    justify-content: center;
	    align-items: center;
	    flex-wrap: wrap;
	    font-family: PingFangSC-Regular;
	    font-size: 14px;
	    font-weight: 400;
	    line-height: 14px;
	    color: rgba(255, 255, 255, 0.5);
	    position: relative;
	}
	
	.left_ul::after {
	    content: " ";
	    position: absolute;
	    width: 1px;
	    height: 96px;
	    left: 50%;
	    top: 50%;
	    transform: translate(-50%, -50%);
	    background-color: rgba(142, 171, 255, 0.2);
	}
	
	.left_li {
	    width: 90px;
	    height: 60px;
	    display: flex;
	    justify-content: center;
	    align-items: center;
	    flex-direction: column;
	}
	
	.left_li > span {
	    font-size: 20px;
	    color: var(--color, #94BCFF);
	    line-height: 20px;
	    display: block;
	    padding-bottom: 8px;
	}
	
	/* 地图尺寸 */
	#chinaMapEle {
	    width: 700px;
	    height: 500px;
	}
</style>
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值