找回密码
 立即注册

QQ登录

只需一步,快速开始

James.Lv 讲师达人认证 悬赏达人认证 活字格认证 Wyn认证
超级版主   /  发表于:2020-8-2 22:49  /   查看:5431  /  回复:2
本帖最后由 Bella.Yuan 于 2023-1-5 18:21 编辑

在数据可视化中,地图可视化是高频应用的一种。我们在一些新闻报道和商业杂志上,会经常看到运用地图来分析展示商业现象,这样的利用地图来反映和分析数据的形式叫数据地图。数据地图可以最直观的表达出数据之间的空间关系,因此在很多数据分析场景中被广泛应用。流向地图也是地图可视化的一种,本文来分享Vue项目中流向地图使用技巧。

什么是流向地图?
流向地图在地图上显示信息或物体从一个位置到另一个位置的移动及其数量。
通常用来显示人物、动物和产品的迁移数据。单一流向线所代表的移动规模或数量由其粗细度表示,有助显示迁移活动的地理分布。
流向地图多应用于区际贸易、交通流向、人口迁移、购物消费行为、通讯信息流动、航空线路等场景,也可应用企业货物运输,供应链管理。
143249ljnnjt5ea3z3nj6l.gif

如何快速在Vue项目中实现流向图迁徙图?
一、利用Echarts实现
Echarts百度的开源图表库,是一个纯Java的图表库,因此使用Echarts进行地图可视化会稍显复杂,需要有一定JS基础才能较为轻松地上手。
1. 首先打开vue项目,cmd进入命令安装echarts依赖包,默认下载最新版本
  1. npm install echarts --save
复制代码
2.进入src目录里的main.js全局引入echarts,以及引入中国地图文件,这样就可以在任何组件中使用了
  1. import * as echarts from 'echarts';
  2. import "echarts/map/js/china.js";
复制代码
3.引入相关文件后就开始创建地图实例。在Echarts中,数据需要预先进行清洗,再放入代码中。代码块主要分为三部分:字段定义地理位置、字段赋值以及图表框架搭建,部分代码如下所示:
image.png298588866.png
(模拟数据)
  1. public render() {      //图表绘制方法
  2.     this.chart.clear();
  3.     const isMock = !this.items.length;
  4.     const items = isMock ? Visual.mockItems : this.items;
  5.     this.container.style.opacity = isMock ? '0.3' : '1';
  6.     const options = this.properties;
  7.     let planePath = options.effect ? options.symbol : options.symbolStyle;
  8.     let departureValue = isMock ? ['北京', '上海', '广州市'] : this.legendData;
  9.     let color = isMock ? ['#a6c84c', '#ffa022', '#46bee9'] : options.palette;
  10.     var series = [];
  11.     items.map((item: any, i: number) => {
  12.       if (item.length) {
  13.         let j = i % color.length;
  14.         series.push({
  15.             name: item[0].fromName,
  16.             type: 'lines',
  17.             zlevel: 1,
  18.             effect: {
  19.               show: true,
  20.               period: options.period,
  21.               trailLength: 0.7,
  22.               color: color[j],
  23.               symbolSize: 4},
  24.             lineStyle: {
  25.               normal: {
  26.                 color: color[j],
  27.                 width: 0.1,
  28.                 curveness: 0.2 } },
  29.             data: item },
  30.           {
  31.             name: item[0].fromName,
  32.             type: 'lines',
  33.             zlevel: 2,
  34.             symbol: ['none', 'arrow'],
  35.             symbolSize: 10,
  36.             effect: {
  37.               show: true,
  38.               period: options.period,
  39.               trailLength: 0,
  40.               symbol: planePath,
  41.               symbolSize: options.symbolSize },
  42.             lineStyle: {
  43.               normal: {
  44.                 color: color[j],
  45.                 width: 1,
  46.                 opacity: 0.6,
  47.                 curveness: 0.2 } },
  48.             data: item},
  49.           {
  50.             name: item[0].fromName,
  51.             type: 'effectScatter',
  52.             coordinateSystem: 'geo',
  53.             zlevel: 2,
  54.             rippleEffect: {
  55.               brushType: 'stroke' },
  56.             label: {
  57.               normal: {
  58.                 show: true,
  59.                 position: "right", //显示位置
  60.                 offset: [5, 0], //偏移设置
  61.                 formatter: "{b}" //圆环显示文字 },
  62.               emphasis: {
  63.                 show: true  } },
  64.             symbolSize: options.pointSize,
  65.             itemStyle: {
  66.               normal: {
  67.                 color: color[j]  }  },
  68.             data: this.parseData(item)  }  );  } });
  69.     var option = {
  70.       tooltip: {
  71.         trigger: 'item',
  72.         formatter: function (params, ticket, callback) {
  73.           if (params.seriesType == "lines") {
  74.             return params.data.fromName + " --> " + params.data.toName + "<br />" + params.data.value;
  75.           } else {
  76.             return params.name; }  } },
  77.       legend: {
  78.         show: options.showLegend,
  79.         orient: 'vertical',
  80.         top: 'bottom',
  81.         left: 'right',
  82.         data: departureValue,
  83.         textStyle: {
  84.           color: '#fff'   },
  85.         selectedMode: 'multiple',   },
  86.       geo: {
  87.         map: options.mapName,
  88.         label: {
  89.           emphasis: {
  90.             sfalsehow: true,
  91.             color: '#fff'  } },
  92.         roam: options.roam,
  93.         layoutCenter: ["50%", "50%"], //地图位置
  94.         layoutSize: "125%",
  95.         itemStyle: {
  96.           normal: {
  97.             borderColor: options.borderColor,
  98.             borderWidth: 1,
  99.             areaColor: {
  100.               type: 'radial',
  101.               x: 0.5,
  102.               y: 0.5,
  103.               r: 0.8,
  104.               colorStops: [{
  105.                 offset: 0,
  106.                 color: options.startColor // 0% 处的颜色
  107.               }, {
  108.                 offset: 1,
  109.                 color: options.endColor // 100% 处的颜色  }], },
  110.             shadowColor: options.shadowColor,
  111.             shadowOffsetX: -2,
  112.             shadowOffsetY: 2,
  113.             shadowBlur: 10  },
  114.           emphasis: {
  115.             areaColor: options.emphasisColor,
  116.             borderWidth: 0  }   }  },
  117.       series: series   };
  118.     this.chart.setOption(option);  }
复制代码
写了大约300多行代码,完成了Echarts的流向地图,效果如下
1.gif
总结
代码开发的特点让Echarts在实现地图可视化的过程中具有极大的自由度(任何用代码开发的操作都是如此)。简单的JS稍微学习下都能很快掌握,但要深入做一些和数据的交互,会有难度,不仅仅是前端的事情了。总体来看,Echarts作为一款国产工具,可以说瑕不掩瑜,比较推荐有编程基础的读者使用。用于集成一些图表应用。
二、可视化软件做流向地图
除了Echarts之外,还有更快的数据地图制作方法,那就是利用一些可视化地图制作软件,比如一些BI工具Wyn Enterprise、tableau等。比如我要分析一个企业的区域贸易的销量情况,这里我就用Wyn Enterprise给大家实操一下。
下面是原始数据:
image.png66648253.png
导入数据之后,创建新的仪表板,然后拖拽数据字段制作图表。这里有两种方式来识别地理信息: 一种是让系统根据位置名称来识别,只绑定位置名称,系统会自动根据位置名称识别对应的经纬度,另一种是直接通过经纬度数据来识别,绑定数据系统会自动识别一键生成流向地图
2.gif
这样简单的拖拽就实现了一个流向地图,自动支持数据过滤,钻取联动分析等,还可以根据自己的个人爱好或者分析目标、设置图表颜色或者其他酷炫的动态效果。

最后呢只需要在VUE项目里调用这个仪表板地址即可实现项目需求。
流向地图在Wyn Enterprise可视化大屏中的一个示例:
image.png685156554.png

2 个回复

倒序浏览
火神的光茫
注册会员   /  发表于:2021-12-3 14:35:46
沙发
你展示的源码不全,能不能给出一份完整的呢?
回复 使用道具 举报
Bella.YuanWyn认证
超级版主   /  发表于:2021-12-3 17:50:13
板凳
火神的光茫 发表于 2021-12-3 14:35
你展示的源码不全,能不能给出一份完整的呢?

您好,参考附件

流向地图.rar

2.58 MB, 下载次数: 778

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部