二. 绘制
问题描述:
假设有一块画布,1200px*2000px尺寸,一组坐标数据,格式为[x,y]二维数组,量级为10000~100000,采样粒度为7*7。依据点坐标的分布密度绘制热力图
方法一
思路:使用canvas元素标签将所有点绘制到画布上,每个点给予较低的透明度。然后获取画布每个点的位数据,根据其alpha值(alpha ∈ [0, 255])的大小计算每一位的r,g,b的值,得出所有新的位数据之后,重新绘制。使之呈现为红色↔蓝色渐变。
代码:
/*假设点坐标为aXY,二维数组*/ var aXY = [[x1, y1], [x2, y2], [x3, y3], [x4, y4]...]; //获取canvas的context var context = canvas.getContext('2d'); var pi2 = Math.PI * 2; //设置填充样式,透明度为0.1 context.fillStyle = 'rgba(255,30,0,0.1)'; for (var i = 0, len = aXY.length; i < len; i++) { var x = aXY[i][0], y = aXY[i][1]; context.beginPath(); //绘制圆点 context.arc(x, y, 6, 0, pi2, true); context.closePath(); context.fill(); } //获取这个画布的位数据 var imgd = context.getImageData(0, 0, 1200, 2000); var pix = imgd.data; // 循环计算rgb,使之根据alpha值映射到红蓝渐变 for (var i = 0, n = pix.length; i < n; i += 4) { //位数据的格式为[rgbargbargba……],每个rgba代表了每个点的rgba四个通道的值 var a = pix[i+3]; //alpha //red pix[i ] = 128 * Math.sin((1 / 256 * a - 0.5 ) * Math.PI ) + 200; //green pix[i+1] = 128 * Math.sin((1 / 128 * a - 0.5 ) * Math.PI ) + 127; //blue,128之后直接衰减为0 pix[i+2] = 256 * Math.sin((1 / 256 * a + 0.5 ) * Math.PI ); pix[i+3] = pix[i+3] * 0.8; } context.putImageData(imgd, 0, 0);
上面的代码将会呈现:

显而易见,这并不是热力图,但是可以精确反映每个点的分布密度,红色表示在该区域的点数据较多,浅,蓝色表示密度小。那么如何改进? 使用径向渐变代替圆点的绘制,用以表示每一个点向周围的点的辐射,渐变色的叠加可以展现梯度变换的效果。
出处:百度泛用户体验
责任编辑:bluehearts
上一页 基于Canvas的热力图绘制方法 [1] 下一页 基于Canvas的热力图绘制方法 [3]
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|