实现echarts中国地图迁徙图

最近做的项目需要实现一个中国地图上烟草流动走向的需求,因为之前没有做过,遇到了不少问题,因此将过程记录下来
首先安装echarts,可以参考另一篇博文,链接如下:
angular项目中使用echarts

安装好以后测试一下页面中是否可以正常使用,就可以开始实现迁徙图了,
在这里插入图片描述
第一步,首先要将中国地图显示出来,即引入china.js文件,因为echarts现在不提供地图文件了,所以我使用了网上大佬提供的china.js文件,放到你的工具文件夹下面,然后在页面中引入,比如在ts文件里如下引入,
我使用的require,当然也可以使用import
目录结构

require('../../shared/util/china');

第二步,文件引入后就可以开始初始化地图了,

        let option = {
          tooltip: {
            extraCssText:
              'border:0;background: linear-gradient(180deg, rgba(7, 37, 115, 0.7) 0%, rgba(1, 13, 60, 0.8) 100%);box-shadow:0px 0px 11px 0px rgba(96, 150, 255, 0.7);color:#fff',
            trigger: 'item',
            formatter: function(params) {
              if (params.componentSubType === 'lines') {
                var res = params.data.fromName + '-' + params.data.toName + '<br/>' + params.data.numValue;
                return res;
              } else if (params.componentSubType === 'effectScatter') {
                var res = '流入' + params.data.eValue + '<br/>' + '流出' + params.data.value[2];
                return res;
              }
            }
          },
          geo: {
            map: 'china',    //说明你的地图类型
            scaleLimit: 3,   
            zoom: 1.2,    // 放大倍数
            top: 60,
            label: {
              emphasis: {
                show: false
              }
            },
            roam: true,   //是否可以缩放和拖拽
            itemStyle: {
              normal: {
                areaColor: '#041E87',
                borderColor: '#0F72B1',
                borderWidth: 2
              },
              emphasis: {
                areaColor: '#041b75'
              }
            }
          },
          series: series   // 数据数组
        };
        this.chart3 = echarts.init(document.getElementById('echart3'));
        this.chart3.setOption(option, true);
        this.chart3.resize();

可以先将series设为空数组看一下地图效果,具体样式和色调可以在itemStyle里设置,

第三步,这个时候就要看具体的数据结构了,
迁徙图的数据结构一般分为三层,一层是线,一层是点,一层是线上的动画,所以每一个数据都由三个对象构成
也就是series的数据结构是这样的,
(迁徙图其实就是两个点两个点连起来的轨迹,一条轨迹为一个单位,一个单位需要定义三个对象,datac是原始数据,大家的原始数据都不一样,处理方法也不同,我会附上我的原始数据)

        let dataC = [
          [
            '广东省揭阳市',
            [
              [
                { xy: ['116.37851218033846', '23.555740488275587'], name: '广东省揭阳市' },
                { xy: ['118.80242172124585', '32.06465288561847'], name: '南京市', value: 1 }
              ],
              [
                { xy: ['116.37851218033846', '23.555740488275587'], name: '广东省揭阳市' },
                { xy: ['118.80441263574761', '32.05475668294885'], name: '玄武区', value: 1 }
              ],
              [
                { xy: ['116.37851218033846', '23.555740488275587'], name: '广东省揭阳市' },
                { xy: ['118.7765189920351', '32.07240516055662'], name: '鼓楼区', value: 7 }
              ]
            ]
          ],
          ['广东省汕头市潮南区', [Array(2)]],
          ['福建省泉州市鲤城区', [Array(2)]]
        ];
//大数组中包含所有的点,每个点又是一个数组包含点的名字,和所有流出的轨迹组成的数组。一个轨迹又是一个数组,包含两个对象,一个起点信息,一个终点信息
// 我的原始数据结构比较复杂,实际开发可以跳过这段介绍
        dataC.forEach(function(item, i) {
          series.push(
            {
              name: item[0] + ' Top10',
              type: 'lines',      //这层是线上的特效
              zlevel: 1,
              effect: {
                show: true,
                period: 6,
                trailLength: 0.7,
                color: '#fff',
                symbolSize: 3
              },
              lineStyle: {
                normal: {
                  color: function(params) {
                    var num = params.data.numValue;
                    if (num >= 0 && num <= 100) {
                      return '#94F522';
                    } else if (num > 100 && num <= 200) {
                      return '#FFE43E';
                    } else if (num > 200 && num <= 300) {
                      return '#FF864A';
                    } else {
                      return '#FF2F49';
                    }
                  },
                  width: 1,
                  curveness: 0.2
                }
              },
              data: that.convertData(item[1])   // 这里是线条需要的数据结构
            },
            {
              name: item[0] + ' Top10',
              type: 'lines',   //这层是线
              zlevel: 2,
              lineStyle: {
                normal: {
                  color: function(params) {
                    var num = params.data.numValue;
                    if (num > 0 && num <= 100) {
                      return '#94F522';
                    } else if (num > 100 && num <= 200) {
                      return '#FFE43E';
                    } else if (num > 200 && num <= 300) {
                      return '#FF864A';
                    } else {
                      return '#FF2F49';
                    }
                  },
                  width: 1,
                  opacity: 0.4,
                  curveness: 0.2
                }
              },
              data:that.convertData(item[1])    // 这里同样是线条需要的数据结构,文章最后附有具体函数
            },
            {
              name: item[0] + ' Top10',
              type: 'effectScatter',   // 这层是点,其实就是散点图
              coordinateSystem: 'geo',
              zlevel: 3,
              rippleEffect: {
                brushType: 'stroke'
              },
              symbol: 'emptyCircle',
              label: {
                normal: {
                  show: true,
                  position: 'right',
                  formatter: '{b}'
                }
              },
              itemStyle: {
                normal: {
                  color: '#a6c84c'
                }
              },
              data: datapop  // 这里是散点需要的数据结构
            }
          );
        });
[
{fromName: "广东省揭阳市", toName: "南京市", numValue: 1, coords: [["116.37851218033846", "23.555740488275587"],["118.80242172124585", "32.06465288561847"]]},
{fromName: "广东省揭阳市", toName: "玄武区", numValue: 1, coords: Array(2)},
{fromName: "广东省揭阳市", toName: "鼓楼区", numValue: 7, coords: Array(2)},
]
// 线的数据结构dataline
[
{ name: '北京', value: [116.46, 39.92, 36006], eValue: 7878 }, // value里面的数字是这个城市所有流出的
{ name: '上海', value: [121.48, 31.22, 454545], eValue: 7878 }, // evalue里面的数字是这个城市所有流入的 可能需要循环遍历处理一下
{ name: '广州', value: [113.23, 23.16, 234234], eValue: 7878 } // 暂时写死
]
// 点的数据结构datapop ,value[0]和value[1]是经纬度。剩下的自由定义

第四步,数据定义好以后基本上地图就可以出来了,剩下的就是一些调整的问题了,要注意经纬度如果是可枚举的话,前端可以写个文件,列出所有经纬度,这样在循环的时候可以直接获取经纬度,比如
在这里插入图片描述

convertData(data) {
    var res = [];
    for (var i = 0; i < data.length; i++) {
      var dataItem = data[i];
      var fromCoord = this.geoCoord.getData()[dataItem[0].name]; //出发地坐标获取
      var toCoord = this.geoCoord.getData()[dataItem[1].name]; //目的地坐标获取
      if (fromCoord && toCoord) {
        res.push({
          fromName: dataItem[0].name, //出发地名称
          toName: dataItem[1].name, //目的地名称
          numValue: dataItem[1].value, //数值
          coords: [fromCoord, toCoord]
        });
      }
    }
    return res;
  }

ok,结束

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值