ECharts绘制世界地图并在tooltips显示多条数据

221900239_张书旖 学生 2022-06-26 22:51:36

目录

  • 一、技术概述
  • 1.1 为什么会有这样的需求
  • 1.2 学习该技术的原因
  • 1.3 实现的难点
  • 1.4 实现效果展示
  • 二、技术详述
  • 2.1 实现思路概述
  • 2.2 地图资源的引入
  • 2.3 获取后端接口数据
  • 2.4 进行数据的映射
  • 2.5 自定义toolstrip标签格式
  • 三、技术使用过程中遇到的问题和解决过程
  • 四、总结
  • 参考博客

一、技术概述

1.1 为什么会有这样的需求

  • 我的软工实践作业要求我们在网页中以世界地图的形式直观地展示某比赛中各个参赛国家的奖牌数,在鼠标移动时在地图中高亮显示参赛国家的名称、奖牌总数、金银铜牌数等多条信息

1.2 学习该技术的原因

  • ECharts中鼠标移动时出现的组件toolstrip默认只能展示name和value两条数据,这不能满足我们的需求。

1.3 实现的难点

  • 难点主要是后台数据的映射和toolstrip中多条数据的展示

1.4 实现效果展示

  • 最后的动态效果图

    在这里插入图片描述


二、技术详述

2.1 实现思路概述

  • 奖牌地图使用ECharts第三方数据可视化库导入world.js实现
  • 通过axios向后台发送GET请求获取奖牌榜数据
  • 将获取到的数据作为地图参数seriesdata属性值。
  • 通过修改tooltip对象的formatter参数值更改鼠标悬浮时的标签格式。

2.2 地图资源的引入

  • 地图的展示需要引入echarts.jsworld.js地图资源包,可以在官网下载资源导入也可以在线引入资源

  • 这里我介绍在线引入的方式,浏览器将从网上获取echart包,不需要配置任何环境。引入的时候需要注意,要先引入echarts.min.js,不然会出错

    <head>
         ...
      <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
      <script type="text/javascript" src="https://assets.pyecharts.org/assets/maps/world.js"></script>
    </head>
    
  • 配置好资源包后在需要展示地图的地方定义一个图表容器存放需要展示的地图,可以根据需要设置地图的长度和宽度:

    <div id="medalsMap" style="width:73.125rem; height:40.5rem;">
    
  • 然后就可以引入世界地图对应的js代码,地图中的数据以及显示的效果的相关参数都在这里修改

    <script>
         //定义一个名为option的变量,后面花括号内容代表我们需要作图的参数设置
           var option={
              // 默认的颜色数组 (如果不明确设置每个数据项的颜色,则会采用默认的数组
                 "color": ["#ac6767","#1d953f","#6950a1","#918597"],
           "series": [
             {
                 // 图标类型为 地图
                 "type": "map",
                 "name": "test",
                 "label": {
                     "show": false,
                     "position": "top",
                     "margin": 8
                 },
                 "mapType": "world",  // 地图类型为 世界地图
                 // data里的每一个{}中,是一项数据整体,标明了该项数据的名称,值,以及颜色等参数
                 "data": [ //图表数据来源
                     {
                         // ItemStyle 中设置每一个数据项的颜色
                         "name": "United States", "value": 43,
                         'itemStyle':{'color':"#c23531"}
                     },
                     {
                         "name": "Japan","value": 17, // 注意项与项之间的逗号
                         'itemStyle':{'color':"#CD8500"}
                     },
                     {
                         "name": "France","value": 7,
                         'itemStyle':{'color':"#EE2C2C"}
                     },
                     {
                         "name": "Italy","value": 6,
                         'itemStyle':{'color':"#918597"}
                     },
                     {
                         "name": "Canada","value": 5,
                         'itemStyle':{'color':"#bda29a"}
                     },
                     {
                         "name": "United Kingdom","value": 4,
                         'itemStyle':{'color':"#6950a1"}
                     },
                     {
                         "name": "Spain","value": 4,
                         'itemStyle':{'color':"#1d953f"}
                     },
                     {
                         "name": "Holland","value": 4,
                         'itemStyle':{'color':"#2f4554"}
                     },
                     {
                         "name": "Belgium","value": 3,
                         'itemStyle':{'color':"#EEAD0E"}
                     }
    ,                    {
                         "name": "Germany","value": 2,
                         'itemStyle':{'color':"#607B8B"}
                     },
                     {
                         "name": "Austria","value": 2,
                         'itemStyle':{'color':"#5CACEE"}
                     },
                 ],
                 "roam": false, //关闭鼠标缩放和平移漫游
                 "zoom": 1, //设置地图缩放大小
             }
         ],
    
         // 鼠标悬浮,单击产生的效果(在网页上可以动态显示)
         "tooltip": {
             "show": true,
             "trigger": "item", //触发器
             "triggerOn": "mousemove|click", //触发事件为鼠标单击或悬浮
             "axisPointer": {
                 "type": "line"
             },
             "textStyle": {
                 "fontSize": 14
             },
             "borderWidth": 0
         }
        }
             var mainBox=new Vue({
                 el:"#medalsMap",
                 data(){
                     return {
                         chart:{},
                     }
                 },
                 mounted(){
                     this.chart= echarts.init(
                             document.getElementById('medalsMap'), 'white', {renderer: 'canvas'});
                      this.chart.setOption(option);   //设置地图的相关参数
                 },
             });
    
     </script>
    
  • 此时页面中将显示你引入的地图信息,如下所示:

    在这里插入图片描述

  • 至此,你已经成功地在网页中引入了世界地图。需要注意的是,上述展示的数据均为静态的数据。若需要显示动态数据需要连接后端接口获取

2.3 获取后端接口数据

  • 因为上述地图中展示的是静态的数据,作业要求我们动态获取奖牌数量信息。所以我们需要从后端接口中获取需要展示的数据。
  • 先在vue data中声明一个数组medalData来存放后端传递的数据
    data(){
        return {
            medalData: [],
           chart:{},
        }
    },
    
  • 此处通过axios向后台发送GET请求获取奖牌榜数据,
    mounted(){
         this.chart= echarts.init(
         document.getElementById('medalsMap'), 'white', {renderer: 'canvas'});
         this.getData(); //从后端接口中获取数据
     },
     methods:{
         getData(){
         axios({
             url:"...", //接口地址
             method:'get',
         }).then(response=>{
            this.medalData = response.data.medallist;
           });
        });
      },
    

2.4 进行数据的映射

  • 为了正确地将数据显示至地图中,我们需要使用map方法将数据处理并映射至数组中。 这里要注意,新组成的数组一定要包含namevalue两个字段,否则ECharts会报错
        this.medalData = response.data.medallist.map((item) => {
               let medal =new Object();
               //根据接口数据设置奖牌数据对象的值
               medal.name = item.country;
               medal.countryname = item.countryname;
               medal.value = item.total;
               medal.level=item.level;
               //...
               return medal;
            });
    
  • 处理好数据后,我们要设置地图的数据源为从接口获取的数据
        getData(){
             //其余代码为获取接口数据代码,已省略
            //设置地图的数据源为获得的奖牌数据
            option.series[0].data=this.medalData; 
            this.chart.setOption(option);
         });    
    
  • 同时要在option对象的series参数中设置data字段为数组
    series: [
     {
          // 其他参数已省略,请自行添加
          data:[],
     }
    ]
    
  • 此处完整代码如下:
    mounted(){
        this.chart= echarts.init(
        document.getElementById('medalsMap'), 'white', {renderer: 'canvas'});
        this.getData(); //从后端接口中获取数据
    },
    methods:{
        getData(){
        axios({
            url:"...", //接口地址
            method:'get',
        }).then(response=>{
           this.medalData = response.data.medallist.map((item) => {
               let medal =new Object();
               //根据接口数据设置奖牌数据对象的值
               medal.name = item.country;
               ...
               return medal;
            });
            //设置地图的数据源为获得的奖牌数据
            option.series[0].data=this.medalData; 
            this.chart.setOption(option);
         });
     },
    

2.5 自定义toolstrip标签格式

  • 完成接口数据的映射后,我们就可以使用获取的数据在formatter字段自定义toolstrip标签的格式。通过数据处理时的键值来获取数组中对应的数据
      tooltip : {
          show : true,
          trigger : "item", //触发器
          triggerOn : "mousemove|click", //触发事件为鼠标单击或悬浮
          //悬浮框文本
          formatter: function(params) {
               if (params['data']!=null){ //相应国家的奖牌数据不为空
                   var medal="";
                   //按照指定格式输出奖牌信息
                   medal+='<strong>'+params['data'].countryname+'</strong><br/>金牌榜第'+params['data'].level+'名<br/>金牌:'+params['data'].gold+'<img src="image/goldlogo.png"  style="width:20px; vertical-align: middle;float:right;">';
                   medal+='<br/>银牌:'+params['data'].silver+'<img src="image/silverlogo.png"  style="width:20px; vertical-align: middle;float:right"><br/>';
                   medal+='铜牌:'+params['data'].bronze+'<img src="image/bronzelogo.png" style="width:20px; vertical-align: middle;float:right;">';
                   return medal;
               }
           },
           textStyle : { ... },
           ... //其余样式信息
      },
    

三、技术使用过程中遇到的问题和解决过程

ECharts的data数据undefined的问题: 在将后台的奖牌榜数据显示到地图的过程中,发现在映射的步骤正确的情况,tooltip中的数据一直是undefined状态,无法将奖牌榜数据输出。我搜索了很多教程依然百思不得其解,最后尝试将国家名称修改为英文后数据就出现了。原来问题出现的原因是item对象的name属性的中英文问题。我从后台获取的数据是中文的国家名称,而世界地图中的name属性是英文的国家名称,这导致ECharts始终无法通过键值找到name属性对应的数据。
解决过程:

  • 为了数据能够成功映射到地图上,我将数据的name属性设置为国家的英文名,与地图的每个模块相对应。再用一个新的字段存储中文的国家名,这样就解决了地图的映射问题。
    //用name存储英文名
     medal.name = item.country;
    //用countryname存储中文名
     medal.countryname = item.countryname;
    
  • 也可以定义一个中英文名映射的数组,就可以实现name属性的中英文转换。
    let nameMap = {
             Afghanistan: '阿富汗',
             Singapore: '新加坡',
             Angola: '安哥拉',
             Albania: '阿尔巴尼亚',
             'United Arab Emirates': '阿联酋',
             Argentina: '阿根廷',
             Armenia: '亚美尼亚',
             'French Southern and Antarctic Lands':
                 '法属南半球和南极领地',
             Australia: '澳大利亚',
             Austria: '奥地利',
             Azerbaijan: '阿塞拜疆',
             Burundi: '布隆迪',
             Belgium: '比利时',
             Benin: '贝宁',
             //...
    }            
    
    注:以上数据参考了这位大佬的博客,完整的映射数组可以到他的博客中获取

四、总结

通过本次作业,我可以说对ECharts的使用已经了如指掌了 (被bug磨练) ,于是决定总结一下自己所理解的流程,留给给后面需要的同学,希望大家能收获知识!


参考博客


...全文
345 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
发帖
2022年福大-软件工程、实践-W班

136

社区成员

2022年福大-软件工程;软件工程实践-W班
软件工程 高校
社区管理员
  • FZU_SE_teacherW
  • 丝雨_xrc
  • Lyu-
加入社区
帖子事件
编辑了帖子 (查看)
2022-06-27 00:04
编辑了帖子 (查看)
2022-06-27 00:00
编辑了帖子 (查看)
2022-06-27 00:00
编辑了帖子 (查看)
2022-06-26 23:57
编辑了帖子 (查看)
2022-06-26 22:54
创建了帖子
2022-06-26 22:51
社区公告
暂无公告