专栏首页个推技术学院个推数据可视化之人群热力图、消息下发图前端开发实践
原创

个推数据可视化之人群热力图、消息下发图前端开发实践

随着互联网在各行各业的影响不断深入,数据规模越来越大,各企业也越来越重视数据的价值。作为一家专业的数据智能公司,个推从消息推送服务起家,经过多年的持续耕耘,积累沉淀了海量数据,在数据可视化领域也开展了深入的探索和实践。

个推的数据可视化探索和应用由需求出发,从基于开源平台到结合个性化需求进行定制化开发,打造出个推实时消息推送下发图,人群分布热力图等优秀数据可视化作品。这一过程中,个推积累沉淀了大量的数据可视化组件,打磨了自己的数据可视化技术能力。其中,个推热力图正应用在智慧城市、人口空间规划、公共服务等领域,为其提供强大的数据支撑。

个推消息下发图
个推打造的湖滨商圈区域人口热力图

本文就和大家分享一下个推的数据可视化实践、遇到的问题及解决思路,希望大家能从中有所受益。

一、数据可视化的构成

数据可视化由四类可视化元素构成:背景信息、标尺、坐标系、视觉暗示。

1.1 背景信息

背景信息就是标题、度量单位、注释等附加类的信息。主要是为了帮助大屏受众更好地理解相关背景信息,即5W信息:何人(who)、何事(what)、何时(when)、何地(where)、为何(why)。

1.2 标尺

标尺主要用来衡量不同方向和维度上的数据大小,常用的有数字标尺、分类标尺、时间标尺等,类似我们熟悉的刻度。

1.3 坐标系

坐标系有一个结构化的空间,还有指定图形和颜色画在哪里的规则,用于编码数据的时候,将物体放到该空间中的某一特定位置,它赋予X、Y坐标或经纬度以意义。常见的坐标系有直角坐标系、极坐标系、地理坐标系。饼图里面用的是极坐标系;柱状图里面有X轴、Y轴,就是直角坐标系;热力图里面用的则是地理坐标图。

1.4 视觉暗示

视觉暗示则是用来编码数据的元素,如位置、长度、大小、方向等。1985年,贝尔实验室发布了视觉元素的暗示排序清单。如清单所示,从上往下,大脑感知系统对这些符号、位置感知有不同的敏感程度,从最高到最低依次是:位置、长度、角度、方向、形状、面积/体积、色相与饱和度。

贝尔实验室于1985年发布的视觉元素暗示排序清单

二、数据可视化的应用

根据不同的数据结构类型,数据可视化的应用也不同,常用的有统计数据图表、关系数据图表、地理空间数据图表。

2.1 统计数据图表

常用的统计数据图表有线形图、柱状图、饼图、雷达图。其中,线形图中的视觉元素为方向,我们从中感知到的是变化趋势;柱状图中的视觉元素为长度,我们从中感知到的是数据所代表的值的大小;而饼图和雷达图中的视觉元素则分别是角度和面积。

2.2 关系数据图表

常用的关系数据图表有关系图、流程图、树图和桑基图。关系数据图表最重要的就是关系。从渲染层面来说,关系图存在两个最重要的难点:布局和聚类。布局意即如何分布要展现的数据,关系图、流程图、树图等,都只是布局不同;聚类则是要将真实的关系进行聚类模拟和可视化呈现出来,比如,哪些实体属于同一类别、相距比较近、或有从属关系等。

2.3 地理空间数据图表

地理空间数据可视化图表有散点图、路径图、热力图、下发图等。地理空间数据图表的特点就是基于地理坐标系。

现在业内对地理空间数据可视化的研究非常多,像高德地图的Loca、Uber联合mapbox推出的kepler.gl等,都是非常优秀的地理空间数据可视化应用案例。

英国某城市间工作跟住宅的通勤地图,运用了方向和颜色的视觉暗示
kepler.gl中展示的某城市地震密度图,运用了位置、时间和颜色的视觉暗示

除以上四种常用的数据可视化图表之外,其实还有很多其他类型的图表,像词云图、时间序列数据图等,这里就不再一一赘述。

三、地图的基本原理

在对地理空间数据进行可视化的实践中,对地图的渲染是非常重要的一步。

地图渲染步骤

上面这张图清晰地呈现了地图渲染的步骤:

· 首先,将地球通过墨卡托投影变成平面地图;

· 然后,将平面地图根据现实场景,分成一层层不同精度的地图,排列成为一个金字塔状;

· 最终,将拼凑起这张地图的细节分割成为一张张地图瓦片。

地图渲染涉及到两个重要名词:地图投影和地图瓦片,下面对这两个名词进行了详细解释:

3.1 地图投影

按照投影形式的不同,地图投影有圆锥投影、圆柱投影、方位投影三种;根据投影方向的位置又可以分为正轴投影、横轴投影、斜轴投影三种。这里要说的是,因为投影,地图就不可能被精准还原,投影展开后的平面地图肯定会有一个变形,根据变形又可以分为等角投影、等面积投影、任意投影等。

根据不同的地图使用场景,需要选择不同的投影算法,现在很多投影算法都是现成的,不需要自己手动写。其中,等角投影是用得比较普遍的一种,其中的墨卡托投影,则是现在地图厂商使用较多的一种地图投影算法。

不同的地图投影方式

3.2 地图瓦片

经过Web墨卡托投影后,地图就变为平面的一张地图。因为有时候我们需要看宏观的地图信息(如世界地图里每个国家的国界),有时候又要看很微观的地图信息(如导航时道路的路况信息)。为此,我们需要对这张地图进行等级切分。

地图瓦片的金字塔坐标体系

在最高级(zoom=0),需要的信息最少,只需保留最重要的宏观信息,因此用一张256x256像素的图片表示即可;在下一级(zoom=1),信息量变多,用一张512x512像素的图片表示;以此类推,级别越低的像素越高,下一级的像素是当前级的4倍。这样,从最高层级往下到最低层级就形成了一个金字塔坐标体系。

对每张图片,我们将其切分为256x256的图片,成为瓦片(Tile)。这样,在最高级(zoom=0)时,只有一个瓦片;在下一级(zoom=1)时,有4个瓦片;在下一级(zoom=2)时,有16个瓦片,以此类推。

四、个推数据可视化实践

个推的数据可视化建设有下发图、热力图等。

1) 个推消息下发图 实时展现了个推当天累计消息下发量、应用下发群体画像(包括性别比例、年龄段分布、当日应用下发城市Top5等)。

个推消息下发图

2) 个推区域人口热力图 则对区域人口分布、人口性别比例、人口年龄段等进行了数据可视化呈现。

个推打造的湖滨商圈区域人口热力图

接下来,就以下发图和热力图为例,来为大家剖析下个推的数据可视化实践过程。

4.1 前期技术选型

从效率和经济角度考虑,我们首先调研了一下现成的方案是否能满足需求。

方案一:地图应用 前面讲过,地图是以地图瓦片的形式渲染出来的,地图应用不能实现设计稿中的效果,所以该方案不可行。

方案二:图表应用 ECharts这类综合的图表库,能基本实现一些地图的效果,并且能切换视角,配置简单;但ECharts中线的效果非常有限,达不到设计稿中想要的渐变以及落地效果,也只能被忍痛放弃。

方案三:D3.js D3.js非常优秀,我们称它是图表界的jQuery,基本能实现我们想要的效果。但是,它也存在一个问题,即它是使用SVG的。SVG是一种矢量图格式,可以保护图片呈现时不失真,但是如果用来实现动画效果,则存在性能问题。

这里,我们将SVG和Canvas进行了性能对比:当飞行数量达到100时,SVG的动画帧数FPS只有12-43,CPU占用很高;Canvas则好很多,基本上是42-60FPS,CPU占用率是20%-30%,在内存占用等各方面都完胜。

飞行数量达100时SVG和Canvas性能对比

综合来看,以上三种方案都不完美。所以,最终,我们决定用自己的方式来实现。

4.2 第一步:分层

首先,如下图,在对地理数据进行渲染之前,我们先根据数据类型进行了分层:

1) 地图底层;

2) 热力图层;

3) 飞线层;

4) 其他任何地理空间数据层,比如柱状图、交通图等。

根据数据类型进行分层

4.3 第二步:地图底层的实现

1) 数据&配置:从阿里云DataV拿到中国地图的数据,再通过墨卡托投影算法得到转换后的数据。

2) Canvas渲染:把数据渲染到Canvas上,这里用的是D3.js的墨卡托转换函数,再用.context方法渲染到Canvas上。

3) 调整效果:渲染完地图后,调整效果,比如阴影、边框、变形等。

4.4 第三步:热力图的实现

热力图以特殊高亮的形式显示访客热衷的页面区域和访客所在的地理区域。

热力图有两个重要的参数:Max(阈值)和Radius(半径)。

· Max:即阈值,就是刚才讲到的标尺,告诉我们某个颜色段的含义。这张图里面0表示透明度值最低,颜色最浅;然后100则表示透明度值为1,颜色最深。

· Radius:即半径,代表数据的有效范围和影响力。

而热力图的具体实现过程,大家可参考个推之前推送的一篇文章:数据可视化:浅谈热力图如何在前端实现

4.5 第四步:飞线层的实现

分线层的实现可以拆开为曲线、动画、光效三部分。

关于飞线层的具体实现,大家可以点击查看:数据可视化之下发图实践,篇幅有限,这里就不再重复叙述啦。

五、遇到的问题

个推在开展数据可视化实践的过程中,也遇到了一些问题。这里主要和大家分享两个问题:跨级别热力图的渲染卡顿问题和样式变形后数据图层的对应问题。

问题1:跨级别热力图的渲染卡顿问题

由于热力图的数据本身很大,当发生视图级别跨越的时候,数据量级成倍增长,这对性能是一个很大的考验,最终数据可视化呈现的效果会有卡顿的问题存在。

为了解决该问题,我们做了几步优化:

  • 请求优化:首先我们将请求分成了6块,根据可视窗口进行切割,类似图片的懒加载。
  • 缓存、防抖:然后是缓存和防抖,我们将转换过的热力图数据缓存了下来,对频繁操作进行了防抖,以避免请求堵塞。
  • 数据聚合:最后,我们还对拿到的数据做了聚合处理。热力图本身就是一个数据融合的过程,那么,我们是否有必要再去做一个聚合?事实证明,我们做了这个聚合之后,对于数据量大或者级别过深的热力图,确实是有效果的。

其中,对于数据聚合,我们研究了四种方案:Kmeans、网格法、距离法、网格距离法。

  • Kmeans:首先随机选取n个聚类质心点,然后遍历每个点到每个聚类的距离并归类,再不断地迭代再归类。但这个方案对于热力图是不适用的,更适合关系图。
  • 网格法:网格法比较简单,网格法是把屏幕里面的每个区域画成一个个格子,看哪个数据在这个格子里面,把点聚合到格子的中心,有个别点的偏差会比较大。
  • 距离法:距离法是通过迭代每一个点、设置点的外包正方形去碰撞,若相交,则把该点聚合到该聚合点中,所以每次聚合的结果都不一样。
  • 网格距离法:还有一个是网格距离法,顾名思义,就是前面两个方法的结合。首先迭代格子,算出网格质心,再次迭代聚合后的点,通过距离法再算一次质心。相对来讲,网格距离法会比网格法和距离法,在算法时间上多一点,但是它的结果会更准确一点。我们也正是使用该方法,使数据卡顿的问题不那么明显。

问题2:样式变形后数据图层的对应问题

第二个问题是样式变形后数据图层的对应问题。

因为对地图进行渲染的时候,我们用了一个CSS变形,模拟了一个透视效果,根据这个效果,我们渲染出来的效果如下图。

热力图和地图因为是平面效果,可以用样式变形来模拟透视效果;可是飞线和点,却是3D的效果。想象下,看烟花的时候,烟花正对我们视角的时候是不是一条直线,而呈90度角的时候,是不是正好可以看到飞线角度。

这其实正好印证了余弦定律,所以从模拟的角度来讲,这个效果已经达到了,只要我们把曲线的曲率根据视角的角度配合余弦定律转换一下。

但是这样的办法不够准确,比如曲线的控制点会不会随视角的转换而转换?

再来看一张图,我们之所以能模拟3D的效果渲染在屏幕上,是因为眼睛会骗人。所以,只要画出一张图跟实际看到的物体一样,我们就认为是3D的。

在地图中,我们则用样式变形,通过设置rotate X、rotate Y、rotate Z等三个参数进行转换,可以看出,旋转其实就是一系列的三角函数变换。

Perspective,即假定我们坐在屏幕前面的距离一定,有了这个设定的值,就能模拟出CSS的样式变形。

当然,透视的算法非常复杂,有单点透视、两点透视以及散点透视等。这里我们只是简单地把模型映射到屏幕。

六、结语

数据可视化以直观、高度视觉冲击力的方式向受众揭示数据背后隐藏的规律,传达数据价值。视觉效果的背后,个推数据可视化实践的核心依托于自身海量数据的积累和数据智能技术的沉淀。

目前,个推热力图正应用于智慧城市、人口空间规划、公共服务等领域,为其提供强大的数据支撑。未来,个推还将持续探索将数据智能的技术应用到各垂直行业中,探索用数据智能带来产业智变。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在 Vue.js 中使用无状态组件[每日前端夜话0xB9]

    同时,Vue 实例是一个 ViewModel,它包含的选项包括表示元素的模板、要安装的元素、方法和初始化时的生命周期钩子。

    疯狂的技术宅
  • React Hooks vs React Component

    是不是简单多了!可以看到, Example变成了一个函数,但这个函数却有自己的状态(count),同时它还可以更新自己的状态(setCount)。这个函数之所以...

    javascript.shop
  • Vuejs开发过程中一些常见问题的解决方法

    在看demo的时候看到在vue-router写着keep-alive,keep-alive的含义: 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新...

    javascript.shop
  • 几个小处理提高前端性能

    javascript.shop
  • will-change提高动画性能与页面滚动性能

    视差滚动现在不是挺流行的嘛,然后Chris Ruppel当其使用background-attachment: fixed实现背景图片不随滚动条滚动而滚动效果的时...

    javascript.shop
  • React性能优化三篇之二

    React仅仅专注于UI层;它使用虚拟DOM技术,以保证它UI的高速渲染;它使用单向数据流,因此它数据绑定更加简单;那么它内部是如何保持简单高效的UI渲染呢?

    javascript.shop
  • React源码解析之ReactDOM.render()

    一、React更新的方式有三种: (1)ReactDOM.render() || hydrate(ReactDOMServer渲染) (2)setState (...

    进击的小进进
  • React学习记录

    1、React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了...

    Tiffany_c4df
  • VUE开发一个组件——Vue PC城市选择控件

    前面用vue开发了三四个组件了,都是H5的,现在来看看PC是如何玩转组件的?其实和H5相同,样式不同而已。

    Javanx
  • absolute/display隐藏与回流等性能实验测试(转)

    1. 关于demo Opera是个性能相当不错的浏览器,要想制作一个可以显示出时间的demo可不是件容易的事情,简单的几个div层的reflow时间必然是0ms...

    javascript.shop

扫码关注云+社区

领取腾讯云代金券