二. 繪制
問題描述:
假設(shè)有一塊畫布,1200px*2000px尺寸,一組坐標(biāo)數(shù)據(jù),格式為[x,y]二維數(shù)組,量級(jí)為10000~100000,采樣粒度為7*7。依據(jù)點(diǎn)坐標(biāo)的分布密度繪制熱力圖
方法一
思路:使用canvas元素標(biāo)簽將所有點(diǎn)繪制到畫布上,每個(gè)點(diǎn)給予較低的透明度。然后獲取畫布每個(gè)點(diǎn)的位數(shù)據(jù),根據(jù)其alpha值(alpha ∈ [0, 255])的大小計(jì)算每一位的r,g,b的值,得出所有新的位數(shù)據(jù)之后,重新繪制。使之呈現(xiàn)為紅色↔藍(lán)色漸變。
代碼:
/*假設(shè)點(diǎn)坐標(biāo)為aXY,二維數(shù)組*/ var aXY = [[x1, y1], [x2, y2], [x3, y3], [x4, y4]...]; //獲取canvas的context var context = canvas.getContext('2d'); var pi2 = Math.PI * 2; //設(shè)置填充樣式,透明度為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(); //繪制圓點(diǎn) context.arc(x, y, 6, 0, pi2, true); context.closePath(); context.fill(); } //獲取這個(gè)畫布的位數(shù)據(jù) var imgd = context.getImageData(0, 0, 1200, 2000); var pix = imgd.data; // 循環(huán)計(jì)算rgb,使之根據(jù)alpha值映射到紅藍(lán)漸變 for (var i = 0, n = pix.length; i < n; i += 4) { //位數(shù)據(jù)的格式為[rgbargbargba……],每個(gè)rgba代表了每個(gè)點(diǎn)的rgba四個(gè)通道的值 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);
上面的代碼將會(huì)呈現(xiàn):
顯而易見,這并不是熱力圖,但是可以精確反映每個(gè)點(diǎn)的分布密度,紅色表示在該區(qū)域的點(diǎn)數(shù)據(jù)較多,淺,藍(lán)色表示密度小。那么如何改進(jìn)? 使用徑向漸變代替圓點(diǎn)的繪制,用以表示每一個(gè)點(diǎn)向周圍的點(diǎn)的輻射,漸變色的疊加可以展現(xiàn)梯度變換的效果。
出處:百度泛用戶體驗(yàn)
責(zé)任編輯:bluehearts
上一頁 基于Canvas的熱力圖繪制方法 [1] 下一頁 基于Canvas的熱力圖繪制方法 [3]
◎進(jìn)入論壇網(wǎng)頁制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|