2021-12-24
Heatmap.js 是目前应用最广的web动态热图javaScript库。heatmap使用 canvas 进行绘制。
Heatmap官网:https://www.patrick-wied.at/static/heatmapjs/
github下载: https://github.com/pa7/heatmap.js
二、代码结构
1、整个js库包裹在一个立即执行的匿名函数里,以避免污染全局命名空间。这也是很多js库的常见写法。
2、核心对象有三个:Store(数据)、Canvas2dRenderer(绘制工具)、HeatMap(构建器)。
3、通过global['h337']暴露创建工厂。
三、热力图渲染原理
以 heatmap.js v2.0.5 为例子; heatmap使用 canvas 进行绘制。
Heatmap.js 最重要的4个点: _getPointTemplate, _getColorPalette , _drawAlpha , _colorize
3.1、点模板 _getPointTemplate,设置单点渲染模板
点模板对应热力图数据点。它是一个圆点,根据可配置的模糊因子(blurFactor,默认.85),可使圆点带有模糊效果(借助createRadialGradient)。
主要是调用 canvas 的 createRadialGradient 方法。核心方法是canvas的createRadialGradient方法,每个点设置渲染半径,由渐变因子 blur 确定内圆比例,内圆与外圆的圆周间进行无色的放射渐变,达到中间透明度高,边缘透明度低的效果。这个无色的透明度渐变的圆形即为点的模板。
var _getPointTemplate = function(radius, blurFactor) { var tplCanvas = document.createElement('canvas'); var tplCtx = tplCanvas.getContext('2d'); var x = radius; var y = radius; tplCanvas.width = tplCanvas.height = radius*2; if (blurFactor == 1) { tplCtx.beginPath(); tplCtx.arc(x, y, radius, 0, 2 * Math.PI, false); tplCtx.fillStyle = 'rgba(0,0,0,1)'; tplCtx.fill(); } else { var gradient = tplCtx.createRadialGradient(x, y, radius*blurFactor, x, y, radius); gradient.addColorStop(0, 'rgba(0,0,0,1)'); gradient.addColorStop(1, 'rgba(0,0,0,0)'); tplCtx.fillStyle = gradient; tplCtx.fillRect(0, 0, 2*radius, 2*radius); } return tplCanvas; };
用 html canvas代码测试效果,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>_getPointTemplate</title> <style> /*canvas {border:1px solid black;}*/ </style> </head> <body> <div class="heatmap"> </div> <script> window.onload = function () { var container = document.querySelector('.heatmap'); var p1 = _getPointTemplate(40, 0.85); //document.body.appendChild(p1); container.appendChild(p1); } var _getPointTemplate = function(radius, blurFactor) { var tplCanvas = document.createElement('canvas'); var tplCtx = tplCanvas.getContext('2d'); var x = radius; var y = radius; tplCanvas.width = tplCanvas.height = radius*2; if (blurFactor == 1) { tplCtx.beginPath(); tplCtx.arc(x, y, radius, 0, 2 * Math.PI, false); tplCtx.fillStyle = 'rgba(0,0,0,1)'; tplCtx.fill(); } else { var gradient = tplCtx.createRadialGradient(x, y, radius*blurFactor, x, y, radius); gradient.addColorStop(0, 'rgba(0,0,0,1)'); gradient.addColorStop(1, 'rgba(0,0,0,0)'); tplCtx.fillStyle = gradient; tplCtx.fillRect(0, 0, 2*radius, 2*radius); } return tplCanvas; }; </script> </body> </html>