你不知道的前端算法之热力图的实现
本文作者:TalkingData 可视化工程师李凤禄
编辑:Aresn
inMap 是一款基于 canvas 的大数据可视化库,专注于大数据方向点线面的可视化效果展示。目前支持散点、围栏、热力、网格、聚合等方式;致力于让大数据可视化变得简单易用。
GitHub 地址:https://github.com/TalkingData/inmapinmap
热力图这个名字听起来很高大上,其实等同于我们常说的密度图。
如图表示,红色区域表示分析要素的密度大,而蓝色区域表示分析要素的密度小。只要点密集,就会形成聚类区域。 看到这么炫的效果,是不是自己也很想实现一把?接下来手把手实现一个热力(带你装逼带你飞、 哈哈),郑重声明:下面代码片段均来自 inMap。
准备数据
inMap 接收的是经纬度数据,需要把它映射到 canvas 的像素坐标,这就用到了墨卡托转换,墨卡托算法很复杂,以后我们会有单独的一篇文章来讲讲他的原理。经过转换,你得到的数据应该是这样的:
好了,我们得到转换后的像素坐标数据(x、y),就可以做下面的事情了。
创建 canvas 渐变填充
创建一个由黑到白的渐变圆
createRadialGradient() 创建线性的渐变对象
addColorStop() 定义一个渐变的颜色带
效果如图:
那么问题就来了,如果每个数据权重值 count 不一样,我们该如何表示呢?
设置 globalAlpha
根据不同的count值设置不同的Alpha,假设最大的count的Alpha等于1,最小的count的Alpha为0,那么我根据count求出Alpha。
然后我们代码如下:
效果跟上一个截图有很大区别,可以对比一下透明度的变化。
(这么黑乎乎的一团,跟热力差距好大啊)
重置 canvas 画布颜色
getImageData() 复制画布上指定矩形的像素数据
putImageData() 将图像数据放回画布:
getImageData()返回的数据格式如下:
返回的数据是一维数组,每四个元素表示一个像素(rgba)值。
实现热力原理:读取每个像素的alpha值(透明度),做一个颜色映射。
代码如下:
创建颜色映射,一个好的颜色映射决定最终效果。 inMap 创建一个长256px的调色面板:
inMap 默认颜色如下:
将gradient颜色设置到调色面板对象中
返回调色面板的像素点数据:
创建出来的调色面板效果图如下:(看起来像一个渐变颜色条)
最终我们实现的热力图如下:
下节预告
下一节,我们将重点介绍 inMap 文字避让算法的实现。
- 在PowerShell中使用curl(Invoke-WebRequest)
- linux centos中添加删除修改环境变量,设置java环境变量
- CentOS7下安装mysql5.6修改字符集为utf8并开放端口允许远程访问
- CentOS7下mysql5.6修改默认编码
- 在idea中maven项目jdk编译version总是跳到1.5
- 命令行打印文件树列表: tree
- JavaScript 获取鼠标及元素在页面上的位置
- Spring cache简单使用guava cache
- SpringMVC参数校验(针对`@RequestBody`返回`400`)
- Java8学习(3)- Lambda 表达式
- Java8 in action(1) 通过行为参数化传递代码--lambda代替策略模式
- java中byte, iso-8859-1, UTF-8,乱码的根源
- 如何启动一个本地静态服务器
- Hello ReactJS
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【python-leetcode92-翻转链表】反转链表2
- 细品Redis高性能数据结构之hash对象
- pyspark之常用算子
- linux之shell综合例子之定时任务
- spring之配置单例的集合bean,以供多个bean进行引用
- 【python-leetcode25-翻转链表】K 个一组翻转链表
- spring之通过实例工厂方法配置Bean
- 细品redis分布式锁
- 【python-leetcode102-树的宽度遍历】二叉树的层次遍历
- 【python-树的宽度遍历】二叉树的反向层次遍历
- 基于TypeScript封装Axios笔记(二)
- redis高性能数据结构之有序集
- spring之通过静态工厂方法配置Bean
- 【python-leetcode107-树的宽度遍历】二叉树的层次遍历Ⅱ
- spring之通过注解方式配置Bean(一)