VUE2+Echarts中国地图+散点+提示+功能下钻

 下载Echarts组件引入Echarts

准备好渲染地图的dom

   <div class="map" ref="map"></div>

 实例化echarts

 const mycharts = echarts.init(this.$refs.map)

声明地图需要使用的变量数据

    data() {
        return {
            mapOption: null, //option容器
            mapList: [], //用来存储地图名称
            mapList1: [],
            mor: 2, //默认下标2热力图显示值1
            activeButton: 'value1' //高亮
        }
    },

获取地图json数据的请求方法,传递两个参数,

     this.getMapJson = async (mapName, lenvl) => {
            const url = 'https://www.isqqw.com/asset/get/areas_v3/' + lenvl + '/' + mapName + '.json'
            const mapJson = await fetch(url).then(res => res.json())
            return mapJson
        },

封装地图需要的option可选项,由于代码太多,只提供一个省级的option吧,市级的跟省级的类似

//封装随机排序数组方法
function getRandomItems(arr, num) {
    const shuffled = arr.sort(() => 0.5 - Math.random()); // 随机排序数组
    return shuffled.slice(0, num); // 返回前 num 个元素
}
var tool = {
    show: true,
    backgroundColor: 'rgba(0, 0, 0, 0.6)', // 蓝灰色背景,这里使用半透明的蓝色作为示例
    borderColor: '#66ccff', // 蓝色边框
    borderWidth: 3, // 三像素边框
    borderRadius: 5, // 可选,圆角效果
    padding: [10, 10], // 内边距,可调整提示框内部空间
    textStyle: {
        color: 'white', // 设置字体颜色为白色
        fontSize: 14, // 可选,设置字体大小
    },
    formatter: function (params) {
        // 根据需要进行数据处理或格式化操作
        if (params && !params.data) {
            // 返回自定义的tooltip内容
            return `
            暂无数据
             `
        }
        if (params && params.data.value2) {
            const { adcode, name, data } = params.data;
            // 返回自定义的tooltip内容
            return `
           <div>参与量&emsp;&emsp;${params.data.value[2]}</div>
           <div>业务量&emsp;&emsp;${params.data.value2}</div>
           <div>核销量&emsp;&emsp;${params.data.value3}</div>
           <div style="
               position: absolute;
               bottom: -10px;
               left: 50%;
               transform: translateX(-50%);
               width: 0;
               height: 0;
               border-left: 10px solid transparent;
               border-right: 10px solid transparent;
               border-top: 10px solid #66ccff;"></div>
            </div>
             `
        }
        if (params && params.data.value) {
            // 返回自定义的tooltip内容
            return `
           <div>领券量&emsp;&emsp;${params.data.value[2]}</div>
           <div>核销量&emsp;&emsp;${params.data.value2}</div>
           <div style="
               position: absolute;
               bottom: -10px;
               left: 50%;
               transform: translateX(-50%);
               width: 0;
               height: 0;
               border-left: 10px solid transparent;
               border-right: 10px solid transparent;
               border-top: 10px solid #66ccff;"></div>
            </div>
             `
        }
    },
    extraCssText: 'box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);', // 可选,添加阴影效果
    position: function (point,) {
        // 自定义提示框的位置,确保箭头指向省份
        return [point[0] - 60, point[1] - 100]; // 示例值,具体数值需根据实际情况调整
    }
}
var pie = [ // 手动定义区间及对应的颜色
    { min: 0, max: 0, color: '#10184d' }, // 特别处理0值
    { min: 1, max: 9, color: '#122666' },
    { min: 10, max: 29, color: '#133780' },
    { min: 30, max: 49, color: '#124d99' },
    { min: 50, max: 99, color: '#1067b3' },
    { min: 100, max: 199, color: '#0c86cc' },
    { min: 200, max: 299, color: '#07aae6' },
    { min: 300, max: 499, color: '#00d4ff' }
]
var ric = {
    fline: {
        padding: [0, 25],
        color: '#fff',
        textShadowColor: '#030615',
        textShadowBlur: '0',
        textShadowOffsetX: 1,
        textShadowOffsetY: 1,
        fontSize: 14,
        fontWeight: 400,
    },
    tline: {
        padding: [0, 27],
        color: '#ABF8FF',
        fontSize: 12,
    },
}
var img2 = 'image://https://niecaihang.oss-cn-beijing.aliyuncs.com/kuang.png'
// var img2 = `image://${require('../assets/images/kuang.png')}`
//中国地图option可选项
export const setOptions = (mapName, mapData, dime) => {
    var randomItems = getRandomItems(mapData, 2)
    var imagePath = '@/assets/images/fangk.png';
    // var img2 = `image://${imagePath}`
    // var img2 = 'image://https://niecaihang.oss-cn-beijing.aliyuncs.com/fk.png'
    return {
        tooltip: tool,
        visualMap: {
            type: 'piecewise', // 分段型视觉映射组件
            orient: 'vertical', // 视觉映射组件的方向,可选'horizontal'或'vertical'
            show: true, // 是否显示视觉映射条
            selectedMode: 'multiple',
            dimension: dime,
            pieces: pie,
            splitNumber: 0, // 指定分割的段数,这里是7段,加上最小值段共8种颜色
            left: "440", // 组件离左侧的距离
            bottom: '30', // 组件离底部的距离
            padding: 5,
            itemHeight: 10,  // 设置视觉映射条的高度
            backgroundColor: 'rgba(0, 0, 0, 0.5)',
        },
        geo: {
            map: mapName,
            roam: true,
            selectedMode: false,
            select: false,
            zoom: 0.8,
            // layoutCenter: ['100%', '-50%'],
            // layoutSize: 750,
            // 图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
            label: {
                show: true,
                fontSize: 12,
                position: 'insideTopLeft',
                textStyle: {
                    color: '#fff', // 这里设置你想要的颜色,例如黑色
                },
                formatter: function (params) {
                    return params.name.replace(/省|自治区|县|维吾尔|壮族|回族|特别行政区|地区|自治州|香港|澳门/g, '');
                }
            },
            itemStyle: {
                borderWidth: 1,  // 增加边框宽度
                borderColor: '#031534',  // 设置边框颜色
                areaColor: '#025fa1',  // 设置地图区域颜色
            },
            emphasis: {
                itemStyle: {
                    borderColor: 'red', // 划过省份时的边框颜色
                    borderWidth: 1,// 划过省份时的边框宽度
                    areaColor: null
                }
            },
        },
        series: [
            {
                type: "map",
                map: mapName,
                data: mapData,
                selectedMode: false,
                zoom: 1.0,
                geoIndex: 0,
            },
            // 散点圆球
            {
                type: 'effectScatter',
                coordinateSystem: 'geo',
                showEffectOn: 'render',
                rippleEffect: {
                    period: 1,
                    scale: 2,
                    brushType: 'fill'
                },
                data: randomItems,
                rippleEffect: {
                    color: '#00ffff',
                    period: 20, // 动画时间,值越小速度越快
                    scale: 6, // 波纹圆环最大限制,值越大波纹越大
                    brushType: 'fill', // 波纹绘制方式 stroke, fill
                },
                symbolOffset: [0, -10], //偏移
            },
            {
                type: 'scatter',
                coordinateSystem: 'geo',
                textStyle: {
                    color: 'white', // 设置字体颜色为白色
                    fontSize: 14, // 可选,设置字体大小
                },
                label: {
                    normal: {
                        show: true,
                        padding: 15,
                        formatter: function (params) {
                            if (params && params.data.value2) {
                                // console.log(params);
                                var value = params.data.data;
                                var text = `参与量:     ${params.data.value[2]}\n\n业务量:     ${params.data.value2}\n\n核销量:     ${params.data.value3}`;
                                return text;
                            }

                            if (params && params.data.value) {
                                // console.log(params);
                                var value = params.data.data;
                                var text = `领券量:     ${params.data.value[2]}\n\n核销量:     ${params.data.value3}`;
                                return text;
                            }

                        },
                        color: '#fff',
                        rich: ric
                    },
                    emphasis: {
                        show: true,
                    },
                },
                itemStyle: {
                    color: '#fff',
                },
                symbol: img2,
                symbolSize: function (val) {
                    if (val) {
                        return val[2] / 6 + 80;
                    }
                },
                symbolOffset: [-10, -50],
                data: randomItems,
            },
        ]
    }
}

组件引入option可选项文件

import { setOptions, setOptions1 } from '../utils/MapOption'

封装渲染地图的方法

  this.renderMapEcharts = async (mapName, lenvl) => {
                console.log(this.pass);
                const mapJson = await this.getMapJson(mapName, lenvl)
                echarts.registerMap(mapName, mapJson);
                const mapdata = mapJson.features.map((item) => {
                    const data = (Math.random() * 200 + 0).toFixed(0) // 20-80随机数
                    const data2 = (Math.random() * 300 + 0).toFixed(0) // 20-80随机数
                    const data3 = (Math.random() * 420 + 0).toFixed(0) // 20-80随机数
                    const center = { data, data2, data3 };
                    const tempValue = item.properties.center ? [...item.properties.center, data, data2, data3] : item.properties.center
                    return {
                        name: item.properties.name,
                        value: tempValue, // 中心点经纬度
                        value1: data,
                        value2: data2,
                        value3: data3,
                        adcode: item.properties.adcode, // 区域编码
                        level: item.properties.level, // 层级
                    }
                });
                //判断如果是china就传递中国地图的option
                if (mapName != 'china') {
                    mycharts.resize()
                    this.mapOption = setOptions1(mapName, mapdata, this.mor)
                }
                //判断如果不是china就传递省区地图的option
                else {
                    mycharts.resize()
                    this.mapOption = setOptions(mapName, mapdata, this.mor)
                }
                this.$nextTick(() => {
                    mycharts.setOption(this.mapOption)
                    mycharts.resize()
                })

            }

接着调用渲染地图的方法,进入页面初次渲染地图

       this.$nextTick(() => {
            this.renderMapEcharts('china', 'country') // 初始化绘制中国地图
            mycharts.resize()
        })

接着开始写地图下钻的事件,我这里只判断下钻到市级,区级设了限制,如果想下钻到区县级可以根据以下调试一下代码

  //地图下钻
        mycharts.on('click', (param) => {
            if (param.data === undefined) {
                this.$message({
                    type: 'error', // success error warning
                    message: '已经在最下层了,无法继续下钻',
                })
                return;
            }
            if (param.seriesType !== 'map') return
            const { adcode, level } = param.data;
            // 新增条件:如果当前已经是市区级别,则不执行下钻操作
            if (level === 'city') {
                this.$message({
                    type: 'error', // success error warning
                    message: '已经在最下层了,无法继续下钻',
                })
                return;
            }
            const mapName = level === 'city' ? adcode : adcode + '_full';
            // 防止最后一个层级被重复点击,返回上一级出错
            if (this.mapList[this.mapList.length - 1] === mapName) {
                // alert('已经在最下层了');
                this.$message({
                    type: 'error', // success error warning
                    message: '已经在最下层了,无法继续下钻',
                })
                return;
            }
            this.$nextTick(() => {
                this.mapList.push(mapName);
                this.mapList1.push(level);
                this.renderMapEcharts(mapName, level);
                mycharts.resize()
            })
        });

接着写一个地图返回的dom跟方法

         <div class="back">
                <span v-show="mapList.length !== 0" class="Mapback" @click="back">地图返回</span>
            </div>

methods:

        back() {
            const level = this.mapList1[this.mapList.length - 2] || 'country';
            const mapName = this.mapList[this.mapList.length - 2] || 'china'; // 假设 mapList 是一个数组
            this.mapList.pop(); // 移除最后一个元素
            this.renderMapEcharts(mapName, level); // 调用渲染地图的方法
        },

结尾:

需要注意的是,我在渲染方法下边部分去判断了一下如果mapName是China那就使用封装好的setOption方法,我还封装了一个setOption1是市区的option,这些都可以根据自己的需求自己封装,可以以我封装的setOption进行更改就行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值