vue+echarts 实现地图tooltip点击事件;toolTip数据动态渲染;同时鼠标滑过涟漪点时实现地图多区域联动

2023-11-13

最终做出来的效果是这样的:

最近做项目时,遇到这样的需求:

        1、toolTip上的数据根据后台动态渲染

        2、鼠标移入地图涟漪点时显示tootTip,点击toolTip上的文字,携带动态数据id进行路由跳转

        3、鼠标移入地图涟漪点,与涟漪点相关的省份多区域联动高亮

   这么多问题,不要慌,办法都是人想出来的,我们先从第一个问题来开整:

一、众所周知,echart的toolTip有自己的显示样式,但是在实际开发中需要自定义html结构才能满足需求,如我遇到的动态渲染,于是我这样做:

let initOption = {
tooltip: {
          show: false, // 提示框
          triggerOn: "mousemove|click", //必须使用这种方式,因为tooltip需要有点击事件,同时移入effectScatter点区域联动
          extraCssText: "border:none;",//清除tooltip自带的边框颜色
          // alwaysShowContent: true,//提示框不消失
          hideDelay: 2000, //提示框移出或点击2秒后消失
     },
       //使用这种方式添加tooltip的formatter,便于点击事件的获取
      initOption.tooltip.formatter = function (params) {
        if (params.seriesType === `effectScatter`) {
          this.proviesName = [];
          const theData = params.data?.theData;
          //省份集合value
          let provies = [];
          theData.map((item) => {
            provies.push(...item.businessArea.split(","));
          });
          //遍历匹配得到省份合集
          provies?.map((item) => {
            mapCenterData.map((ite) => {
              if (item == ite.value) this.proviesName.push(ite.name);
            });
          });
          //数组去重
          this.proviesName = Array.from(new Set(this.proviesName));

          let before = "";
          let center = "";
          // 格式化提示框信息
          theData.map((item) => {
            item.recruitmentInfoList.map((ite) => {
              center += `
                      <div style="width: 15vw;display: flex;justify-content: space-between;padding: 0 10px; font-size: 14px; margin: 10px 0;">
                          ${ite.title}
                      </div> 
                `;
            });
            before +=
              `
                  <div style="position: relative;z-index: 100000000000000000000000;">
                    <div style="font-weight: bold;display: flex;padding: 0 5px;justify-content: space-between;margin-bottom: 20px;">
                      <div style="font-weight: bold;color: #348df2;font-size: 16px;z-index:100;">${item.shortName}</div>
                      </div>` +
              center +
              `
                      <div style="width: 15vw;display: flex;justify-content: flex-end;padding: 0 10px; font-size: 14px;" >
                          <div style="align-items: flex-end;display: flex;align-items: center;color:#3da2ff;pointer-events: auto;" class="toJoin-${
                            item.id
                          }">
                            <p οnclick="${this.getMoreJob(item.id)}">更多</p>
                            <svg style="width:20px;height:20px;margin-left: 10px;" t="1672020296882" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2518" width="200" height="200"><path d="M1024.2048 512c0 6.656-2.4576 13.2608-7.5264 18.2784l-325.8368 325.8368a25.6 25.6 0 1 1-36.1984-36.1984l282.5216-282.5216H25.8048a25.6 25.6 0 1 1 0-51.2h910.9504l-282.112-282.112a25.6 25.6 0 1 1 36.1984-36.1984l325.8368 325.8368c4.608 4.608 7.5264 11.008 7.5264 18.0736V512z" fill="#3ca1fe" p-id="2519"></path></svg>
                          </div>
                        </div>
                      </div>
                        `;
          });

          return before;
        }
      }.bind(this);
}

tooTip对象是放在初始化的echart对象中,相信聪明的你肯定知道。这样写就能实现toolTip中html自定义。

二、点击文字,携带参数的路由跳转,由于tooltip中不能使用vue语法,只能使用原生点击事件(onclick),大家可以参考上面代码

<p οnclick="${this.getMoreJob(item.id)}">更多</p> //这里可以获取到定义在vue中的方法

三、移入地图涟漪点省份区域联动,实现思路就是在initOption对象中添加:

let initOption = {
    // 设置高亮颜色
        dataRange: {
          show: false,
          x: "left",
          y: "bottom",
          splitList: [
            { start: 5, end: 5, color: "#007aff" }, //当值为5时,区域背景(值随便设置)
          ],
        },
}

然后在ehcart的移入事件中这么写:

       //移入显示区域联动
      this.chart.on("mouseover", (params) => {
        if (params.seriesType == "effectScatter") {
          this.seriesData = [];
          this.proviesName.map((item) => {
            this.seriesData.push({
              name: item + "省",//这里名字得与联动的省份的名字对应,不然没效果
              value: 5, //随便写的值,主要是与dataRange中设置的值相对应,这样就能实现区域联动高亮
            });
            this.chart.setOption({ series: [{}, { data: this.seriesData }] });
          });
        }
      });

鼠标移出还得操作一手,为了除高亮:

//鼠标移出,清除联动高亮
      this.chart.on("mouseout", (params) => {
        if (params.seriesType == "effectScatter") {
          this.seriesData = [];
          this.chart.setOption({ series: [{}, { data: this.seriesData }] });
        }
      });

最后,废话不多说,上完整代码:

 //初始化图表
    initChart() {
      this.chart = echarts.init(this.$refs.map);
      let initOption = {
        grid: {
          bottom: "0%",
          top: "10%",
          left: "10%",
          right: "10%",
        },
        // 设置高亮颜色
        dataRange: {
          show: false,
          x: "left",
          y: "bottom",
          splitList: [
            { start: 5, end: 5, color: "#007aff" }, //当值为5时,区域背景
          ],
        },
        tooltip: {
          show: false, // 提示框
          triggerOn: "mousemove|click", //必须使用这种方式,因为tooltip需要有点击事件,同时移入effectScatter点区域联动
          extraCssText: "border:none;",//清除tooltip自带颜色
          // alwaysShowContent: true,//提示框不消失
          hideDelay: 2000, //提示框2秒后小时
        },
        geo: {
          show: true,
          map: "china",
          zoom: 1.1, // 地图比例
          label: {
            normal: {
              show: false,
            },
            emphasis: {
              show: false,
            },
          },

          roam: false,
          itemStyle: {
            normal: {
              areaColor: "#01215c",
              borderWidth: 5, //设置外层边框
              borderColor: "transparent",
              shadowColor: "#add7ff",
              shadowBlur: 30,
              shadowOffsetX: 0,
              shadowOffsetY: 15,
            },
          },
        },
        series: [
          {
            type: "effectScatter",
            coordinateSystem: "geo",
            showEffectOn: "render",
            rippleEffect: {
              brushType: "stroke",
              scale: 5,
              period: 2, // 秒数
            },
            symbolSize: 12,
            hoverAnimation: true,
            label: {
              normal: {
                formatter: "{b}",
                position: "right",
                show: true,
              },
            },
            zlevel: 1,
            tooltip: {
              show: true, // 提示框
              triggerOn: "click",
            },
          },

          {
            type: "map",
            map: "china",
            aspectScale: 0.75,
            zoom: 1.1, // 地图比例
            itemStyle: {
              normal: {
                areaColor: "#ebf6fd",
                borderColor: "#a1cffb",
                shadowColor: "rgba(255, 230, 175,0.5)",
                borderWidth: 1,
              },
              emphasis: {
                areaColor: "#52C5F7",
              },
            },
            emphasis: {
              label: {
                show: true,
              },
            },
          },
        ],
      };
      //添加tooltip对象
      initOption.tooltip.formatter = function (params) {
        if (params.seriesType === `effectScatter`) {
          this.proviesName = [];
          const theData = params.data?.theData;
          //省份集合value
          let provies = [];
          theData.map((item) => {
            provies.push(...item.businessArea.split(","));
          });
          //遍历匹配得到省份合集
          provies?.map((item) => {
            mapCenterData.map((ite) => {
              if (item == ite.value) this.proviesName.push(ite.name);
            });
          });
          //数组去重
          this.proviesName = Array.from(new Set(this.proviesName));

          let before = "";
          let center = "";
          // 格式化提示框信息
          theData.map((item) => {
            item.recruitmentInfoList.map((ite) => {
              center += `
                      <div style="width: 15vw;display: flex;justify-content: space-between;padding: 0 10px; font-size: 14px; margin: 10px 0;">
                          ${ite.title}
                      </div> 
                `;
            });
            before +=
              `
                  <div style="position: relative;z-index: 100000000000000000000000;">
                    <div style="font-weight: bold;display: flex;padding: 0 5px;justify-content: space-between;margin-bottom: 20px;">
                      <div style="font-weight: bold;color: #348df2;font-size: 16px;z-index:100;">${item.shortName}</div>
                      </div>` +
              center +
              `
                      <div style="width: 15vw;display: flex;justify-content: flex-end;padding: 0 10px; font-size: 14px;" >
                          <div style="align-items: flex-end;display: flex;align-items: center;color:#3da2ff;pointer-events: auto;" class="toJoin-${
                            item.id
                          }">
                            <p οnclick="${this.getMoreJob(item.id)}">更多</p>
                            <svg style="width:20px;height:20px;margin-left: 10px;" t="1672020296882" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2518" width="200" height="200"><path d="M1024.2048 512c0 6.656-2.4576 13.2608-7.5264 18.2784l-325.8368 325.8368a25.6 25.6 0 1 1-36.1984-36.1984l282.5216-282.5216H25.8048a25.6 25.6 0 1 1 0-51.2h910.9504l-282.112-282.112a25.6 25.6 0 1 1 36.1984-36.1984l325.8368 325.8368c4.608 4.608 7.5264 11.008 7.5264 18.0736V512z" fill="#3ca1fe" p-id="2519"></path></svg>
                          </div>
                        </div>
                      </div>
                        `;
          });

          return before;
        }
      }.bind(this);
      this.chart.setOption(initOption);
      //移入显示区域联动
      this.chart.on("mouseover", (params) => {
        if (params.seriesType == "effectScatter") {
          this.seriesData = [];
          this.proviesName.map((item) => {
            this.seriesData.push({
              name: item + "省",
              value: 5,
            });
            this.chart.setOption({ series: [{}, { data: this.seriesData }] });
          });
        }
      });
      //鼠标移出,清除联动高亮
      this.chart.on("mouseout", (params) => {
        if (params.seriesType == "effectScatter") {
          this.seriesData = [];
          this.chart.setOption({ series: [{}, { data: this.seriesData }] });
        }
      });
    },

        注意:初始化图表的数据都来原于后台接口请求,涟漪点的数据,与地图每个区域的数据,需要各位根据实际情况渲染到地图上,然后才会有上面的3个问题的出现

        最后:原创不易,转载请注明出处

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue+echarts 实现地图tooltip点击事件;toolTip数据动态渲染;同时鼠标滑过涟漪点时实现地图多区域联动 的相关文章

随机推荐

  • 数据安全风险分析及应对策略研究

    报告从理论与实践层面对当前企业面临的内外部数据安全风险进行分析与研究 完成了以下几方面的探索 一是梳理了当前数据安全面临的突出问题 二是提出了数据安全体系建设的行动思路和关键举措 三是提出了数据安全建设发展建议 关注公众号 互联互通社区 回
  • angular自动化测试--protractor

    前戏 面向模型编程 测试驱动开发 先保障交互逻辑 再调整细节 by 雪狼 为什么要自动化测试 1 提高产出质量 2 减少重构时的痛 反正我最近重构多了 痛苦经历多了 3 便于新人接手 angular自动化测试主要分 端到端测试和单元测试 很
  • 专访戴文渊:第四范式(现在)是一家怎样的公司?

    李根 发自 凹非寺 量子位 报道 公众号 QbitAI 第四范式创始人及CEO戴文渊 第四范式是一家备受关注的公司 仅创始团队成员来看 哪一个不是计算机 机器学习领域响当当的名字 戴文渊是ACM2005全球冠军 百度机器学习系统带队打造者
  • RecyclerView中item布局的"match_parent"属性失效--LayoutInflate的深入了解

    用recyclerview 给item布局使用了match parent属性 运行后不起作用 查了下 是在onCreateViewHolder中加载布局时候出了问题 一开始用的View Inflate方法 查看源码后 发现View infl
  • Java学生个人信息录入

    编写 Java 程序显示学生的个人信息 定义类Student 该类中应该有三个私有属性 姓名 name 年龄 age 性别 sex 输入 第一行为一个数 表示录入学生个数 第二行依次为学生姓名 年龄 性别 最后一行输入一个学生的姓名 输出
  • 【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案...

    我一直在思考第一个博客应该写什么 然后我就解决了开通博客后解决的第一个问题 择题不如撞题 如果大多数人和我一样 接触python selenium unittest是从selenium IDE开始的话 你也一定会遇到这样的问题 我们写了5个
  • 论文阅读_大模型_ToolLLM

    英文名称 ToolLLM Facilitating Large Language Models to Master 16000 Real world APIs 中文名称 TOOLLLM 帮助大语言模型掌握16000多个真实世界的API 文章
  • telnet出现Connection closed by foreign host

    2018 10 26 执行命令 telnet smtp exmail qq com 465 出现信息 root pengman Desktop telnet 10 223 30 128 7027 Tring 10 223 30 128 70
  • 50 道 Java 基础编程练习题

    https gold xitu io post 58a4276f61ff4b006c899609
  • CMake 入门实战(精)

    http www hahack com codes cmake 从实例入手 讲解 CMake 的常见用法 Contents 什么是 CMake 入门案例 单个源文件 多个源文件 自定义编译选项 安装和测试 支持 gdb 添加环境检查 添加版
  • Java/JDK 21正式发布!15个特性一览

    订阅专栏 JDK 21已经于2023年9月19日正式发布 本文总结了JDK 21发布的新特性 发布版本说明 根据发布的规划 这次发布的 JDK 21 将是一个长期支持版 LTS 版 LTS 版每 2 年发布一个 上一次长期支持版是 21 年
  • s24服务器维护时长,服务器维护:艾锑人告诉您Mbps和mb/s换算知识

    影响我们一生百倍差距的四大效应 观察者效应 你的世界是什么样是由你的观察决定的 这个效应是在 潜能突破 研习营课堂上发现的 我们有个练习叫三生万物 每个人都会成为一次观察者角色 当大家在成为其他角色时 他们总是发现不了自己的问题 无论我们怎
  • 7.opencv——边缘检测( 拉普拉斯(Laplacian),Sobel,Canny边缘检测)

    边缘检测 边缘检测 拉普拉斯 Laplacian 边缘检测 Sobel边缘检测 Canny边缘检测 拉普拉斯 Laplacian Sobel Canny对比 边缘检测 qquad 各类图像中 由于不同物体对电磁波的反射特性不同 在物体与背景
  • Windows中使用GCC介绍

    Windows中使用GCC介绍 GCC介绍 GCC是由许多组件组成的 GCC原名为GNU C语言编译器 GNU C Compiler 只能处理C语言 但其很快扩展 变得可处理C 后来又扩展为能够支持更多编程语言 如Fortran Pasca
  • display:inline-block元素之间空隙的产生原因和解决办法

    display inline block是一种布局方法 它相比于与浮动 定位最大的不同就是其没有父元素的匿名包裹特性 这使得display inline block属性的使用非常自由 可与文字 图片混排 可内嵌block属性元素 可以置身于
  • h2事务与mysql_mysql、h2插入性能对比

    2013 01 05 更新 导致循环调用save插入慢的问题是我循环调用了service方法 而不是在service内部循环 而事物是在service级别 所以相当于每次插入都提交事物 所以慢了 同样是插入 差别咋就这大呢 操作系统 wub
  • 【WPF动画】实现从鼠标点击中心开始的波纹扩散特效

    效果图 实现原理 Storyboard组合动画实现 核心代码 1 获取点击区域 确定扩散圆形辐射范围等属性 var ellipse new Ellipse Width 10 Height 10 Fill Brushes LightBlue
  • ASP.NET的优点

    ASP NET 是一个统一的 Web 开发平台 它提供开发人员创建企业级 Web 应用程序所需的服务 尽管 ASP NET 的语法基本上与 ASP 兼容 但是它还提供了一个新的编程模型和基础结构以提高应用程序的安全性 缩放性和稳定性 通过逐
  • Qt信号与槽原理

    Qt信号与槽原理 本文为原创文章 转载请注明出处 或注明转载自 黄邦勇帅 原名 黄勇 本文出自本人原创著作 Qt5 10 GUI完全参考手册 网盘地址 https pan baidu com s 1iqagt4SEC8PUYx6t3ku39
  • vue+echarts 实现地图tooltip点击事件;toolTip数据动态渲染;同时鼠标滑过涟漪点时实现地图多区域联动

    最终做出来的效果是这样的 最近做项目时 遇到这样的需求 1 toolTip上的数据根据后台动态渲染 2 鼠标移入地图涟漪点时显示tootTip 点击toolTip上的文字 携带动态数据id进行路由跳转 3 鼠标移入地图涟漪点 与涟漪点相关的