echarts中国地图二级联动且多条数据展示

本文介绍了如何使用echarts的map类型在vue.js项目中实现中国地图的二级联动效果,并展示了如何根据数据动态渲染地图颜色。通过监听地图点击事件,切换省级地图并自定义显示样式。同时,注意到防止事件叠加导致的性能问题,每次更新前需取消原有绑定事件。

echarts的map类型使用

  • 最近笔者的公司提出了新的需求,要求将对应的数据呈现在地图上,将对应省份的数据渲染出来(之前是表格的来)。

  • 既然是要画图,那自然是得用到echarts,至少我用的来的就只有这个,其他的也未曾深入研究。而我打开它的文档,随意一翻就发现居然有map的类型,这不正是我想要的嘛。

  1. 首先第一个问题就是:省级地图不能动态引入,因为笔者用的是 vue 的项目,所以目前还没想到动态引入的 js 的只能将所有的省全部引入,然后依次再按需切换 echarts 的 mapType。
  2. 第二个呢就是说如何联动,通过 echarts 的自带事件监听器,绑定点击事件,监听点击的省份,然后根据点击的内容重新绘制对应的省级地图。
  3. 鼠标移入的多项数据展示,option 中有对应的属性可以自定义展示样式和格式,tooltip貌似就是用来做这个的。
tooltip: {
            trigger: 'item',
            formatter: function(params) {
              var toolTiphtml = ''
              for(var i = 0;i<seriesData.length;i++){
                if(params.name==seriesData[i].name){
                  toolTiphtml += seriesData[i].name+':<br/>'
                  for(var j = 0;j<seriesData[i].topT.length;j++){
                    toolTiphtml+=seriesData[i].topT[j].name+':'+seriesData[i].topT[j].value+"<br/>"
                  }
                }
              }
              return toolTiphtml;
            }
          },
  1. 根据不同的内容渲染地图的颜色。这个也可通过dataRange 来设置。而且因为笔者有对应的排序需求,所以还得根据用户的点击来切换不同的颜色排序。
dataRange: {
              show: true,
              x: '0px', //图例横轴位置
              y: '30px', //图例纵轴位置
              splitList: sort === 'chain' ? [
                  { start: 80, end: 100, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 50, end: 80, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 0, end: 50, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: -500, end: 0, color: 'rgb(147, 224, 255)' },        // dd
                  { start: -9999999, end: -500, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ] : sort === 'money' ? [
                  { start: 100000, end: 9999999, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 50000, end: 100000, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 10000, end: 50000, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: 2000, end: 10000, color: 'rgb(147, 224, 255)' },        // dd
                  { start: 0, end: 2000, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ] : [
                  { start: 1000, end: 999999, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 500, end: 1000, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 100, end: 500, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: 10, end: 100, color: 'rgb(147, 224, 255)' },        // dd
                  { start: 0, end: 10, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ]
          }

最后的完整代码就是这样的

init (mapName, sort, showWhat) {
      if (!showWhat) {
        let seriesData = this.value.seriesData;
        seriesData.forEach(item => {
          this.provinceNumber.forEach((a, index) => {
            if (item.province && item.province === a) {
              item.name = this.provincesText[index];
              if (sort) {
                item.value = sort === 'money' ? item.money : sort === 'count' ? item.count : item.chain
              } else {
                item.value = item.count
              }
              item.topT = [{
                name: '项目数量(宗)',
                value: item.count}, {
                name: '委托金额(万元)',
                value: item.money}, {
                name: '环比',
                value: `${item.chain} %`}]
            }
          })
        })
        let option = {
          title: {
            text: '全国地区维度数据',
            left: 'center'
          },
          tooltip: {
            trigger: 'item',
            formatter: function(params) {
              var toolTiphtml = ''
              for(var i = 0;i<seriesData.length;i++){
                if(params.name==seriesData[i].name){
                  toolTiphtml += seriesData[i].name+':<br/>'
                  for(var j = 0;j<seriesData[i].topT.length;j++){
                    toolTiphtml+=seriesData[i].topT[j].name+':'+seriesData[i].topT[j].value+"<br/>"
                  }
                }
              }
              return toolTiphtml;
            }
          },
          legend: {
            orient: 'vertical',
            left: 'left',
            data: []
          },
          series: [
            {
              name: '中国',
              type: 'map',
              mapType: mapName,
              // roam: true,
              zoom: 1,
              selectedMode: false,
              label: {
                normal: {
                    show: true,//显示省份标签
                    color: 'auto',
                    formatter: '{b}',
                    textStyle:{color:"#fff"},//省份标签字体颜色
                    backgroundColor: 'auto'
                },
                emphasis: {//对应的鼠标悬浮效果
                    show: false,
                    textStyle:{color:"#000"},
                    backgroundColor: 'auto'
                }
              },
              itemStyle: {
                normal: {
                    borderWidth: .5,//区域边框宽度
                    borderColor: '#0550c3',//区域边框颜色
                    areaColor:"#808695",//区域颜色
                },
                emphasis: {
                    borderWidth: .5,
                    borderColor: '#4b0082',
                    areaColor:"#44ff1a",
                }
              },
              data: seriesData
            }
          ],
          dataRange: {
              show: true,
              x: '0px', //图例横轴位置
              y: '30px', //图例纵轴位置
              splitList: sort === 'chain' ? [
                  { start: 80, end: 100, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 50, end: 80, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 0, end: 50, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: -500, end: 0, color: 'rgb(147, 224, 255)' },        // dd
                  { start: -9999999, end: -500, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ] : sort === 'money' ? [
                  { start: 100000, end: 9999999, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 50000, end: 100000, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 10000, end: 50000, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: 2000, end: 10000, color: 'rgb(147, 224, 255)' },        // dd
                  { start: 0, end: 2000, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ] : [
                  { start: 1000, end: 999999, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 500, end: 1000, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 100, end: 500, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: 10, end: 100, color: 'rgb(147, 224, 255)' },        // dd
                  { start: 0, end: 10, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ]
          },
        }
        this.dom = echarts.init(this.$refs.dom, 'tdTheme')
        this.dom.setOption(option)
        this.dom.off('click');
        this.dom.on('click', (e) => {
          this.provincesText.forEach((item, index) => {
            if (e.data && item === e.name) {
              this.$router.push(`/trend/area/${e.data.province}`)
              this.dom = null;
              this.changMapP = this.provinces[index];
              let option1 = {
                title: {
                  text: `${e.name}维度数据`,
                  left: 'center'
                },
                tooltip: {
                  trigger: 'item'
                },
                legend: {
                  orient: 'vertical',
                  left: 'left',
                  data: []
                },
                series: [
                  {
                    name: '中国',
                    type: 'map',
                    mapType: this.changMapP,
                    zoom: 1,
                    selectedMode: false,
                    label: {
                      normal: {
                          show: true,//显示省份标签
                          textStyle:{color:"white"}//省份标签字体颜色
                      },
                      emphasis: {//对应的鼠标悬浮效果
                          show: true,
                          textStyle:{color:"#323232"}
                      }
                    },
                    itemStyle: {
                      normal: {
                          borderWidth: .5,//区域边框宽度
                          borderColor: '#0550c3',//区域边框颜色
                          areaColor:"#22b1e3",//区域颜色

                      },
                      emphasis: {
                          borderWidth: .5,
                          borderColor: '#4b0082',
                          areaColor:"#ece39e",
                      }
                    },
                    data: seriesData
                  }
                ]
              }
              this.dom = echarts.init(this.$refs.dom, 'tdTheme')
              this.dom.setOption(option1)
            }
          })
        })
        on(window, 'resize', this.resize)
      } else {
        let seriesData = this.cityData;
        seriesData.forEach(item => {
          item.name = item.areaName;
          item.topT = [{
            name: '项目数量(宗)',
            value: item.yprojecttotal}, {
            name: '委托金额(万元)',
            value: item.ypricetotal}, {
            name: '环比',
            value: `${item.chain} %`
          }]
          if (sort) {
            item.value = sort === 'money' ? item.ypricetotal : sort === 'count' ? item.yprojecttotal : item.chain
          } else {
            item.value = item.yprojecttotal
          }
        })
        let option = {
          title: {
            text: `${this.topName}地区维度数据`,
            left: 'center'
          },
          tooltip: {
            trigger: 'item',
            formatter: function(params) {
              var toolTiphtml = ''
              for(var i = 0;i<seriesData.length;i++){
                if(params.name==seriesData[i].name){
                  toolTiphtml += seriesData[i].name+':<br/>'
                  for(var j = 0;j<seriesData[i].topT.length;j++){
                    toolTiphtml+=seriesData[i].topT[j].name+':'+seriesData[i].topT[j].value+"<br/>"
                  }
                }
              }
              return toolTiphtml;
            }
          },
          legend: {
            orient: 'vertical',
            left: 'left',
            data: []
          },
          series: [
            {
              name: '中国',
              type: 'map',
              mapType: mapName,
              // roam: true,
              zoom: 1,
              selectedMode: false,
              label: {
                normal: {
                    show: true,//显示省份标签
                    color: 'auto',
                    formatter: '{b}',
                    textStyle:{color:"#fff"},//省份标签字体颜色
                    backgroundColor: 'auto'
                },
                emphasis: {//对应的鼠标悬浮效果
                    show: false,
                    textStyle:{color:"#000"},
                    backgroundColor: 'auto'
                }
              },
              itemStyle: {
                normal: {
                    borderWidth: .5,//区域边框宽度
                    borderColor: '#0550c3',//区域边框颜色
                    areaColor:"#808695",//区域颜色
                },
                emphasis: {
                    borderWidth: .5,
                    borderColor: '#4b0082',
                    areaColor:"#44ff1a",
                }
              },
              data: seriesData
            }
          ],
          dataRange: {
              show: true,
              x: '0px', //图例横轴位置
              y: '30px', //图例纵轴位置
              splitList: sort === 'chain' ? [
                  { start: 80, end: 100, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 50, end: 80, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 0, end: 50, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: -500, end: 0, color: 'rgb(147, 224, 255)' },        // dd
                  { start: -9999999, end: -500, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ] : sort === 'money' ? [
                  { start: 100000, end: 9999999, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 50000, end: 100000, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 10000, end: 50000, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: 2000, end: 10000, color: 'rgb(147, 224, 255)' },        // dd
                  { start: 0, end: 2000, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ] : [
                  { start: 1000, end: 999999, color: 'rgb(255, 66, 93)' },     // 红色
                  { start: 500, end: 1000, color: 'rgb(92, 167, 186)' },       // 深蓝色
                  { start: 100, end: 500, color: 'rgb(175, 215, 237)' },       // 蓝色
                  { start: 10, end: 100, color: 'rgb(147, 224, 255)' },        // dd
                  { start: 0, end: 10, color: 'rgb(199, 237, 233)' },          // 浅蓝色
              ]
          },
        }
        this.dom = echarts.init(this.$refs.dom, 'tdTheme')
        this.dom.setOption(option)
        this.dom.off('click');
        this.dom.on('click', (e) => {
          if (e.data) {
            this.$router.push(`projectdt?id=${e.data.city}&Num=${this.$route.params.id}&year=${this.yearNum}&pro=${e.name}`)
          }
        })
        on(window, 'resize', this.resize)
      }
    },

因为俺们么得UI,所以这些颜色什么的,都是自己在网上找的。
对了,切记每次都要this.dom.off('click'); 取消绑定事件,每次on之前都要先off,否则会有很多次事件的叠加。一次比一次卡。

最后是效果图。

这是某一排序下的效果,移入为绿色,且会有对应的展示,没有则为灰色

over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值