前回の記事のヒートマップはSVGを用いて描画しました。ウェブブラウザではSVG以外にもピクセル単位でグラフィックを描画できるCanvasや、3D描画が可能なWebGL(Canvas 3D)があります。これまではSVGを使った記事を上げてきました。ですが、Canvasに描画したいこともあります。特に処理速度が問題となる場合には、SVGよりCanvasを利用した方が良い場合もあります。
サンプルコードの実行結果はこちら
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <head> <meta charset="utf-8"> <title>ヒートマップをCanvasに表示してみる</title> <script src="../js/d3.js"></script> <style> svg{ width:160px; height:240px; border:1px solid black;} .block{ stroke:black; fill:none;} canvas{width:160px; height:240px; border:1px solid red;} </style> </head> <body> <h1>ヒートマップをCanvasに表示</h1> <svg id="graph"></svg> <canvas id="canvas" width="160" height="240"></canvas> <script src="test.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
/* ヒートマップをCanvasに表示 */ // HTMLファイルで設定した#graphの幅、高さを取得する var svgEle = document.getElementById("graph"); var svgWidth = getComputedStyle( svgEle, null) .getPropertyValue("width"); var svgHeight = getComputedStyle( svgEle, null) .getPropertyValue("height"); svgWidth = parseFloat( svgWidth ); // 整数に変換する svgHeight = parseFloat( svgHeight ); // 整数に変換する var blockSize = 20; var arrData = []; for( var i = 0 ; i < 96 ; i++){ // 0~9までの値のどれかを格納 arrData[i] = Math.floor( Math.random() * 10 ); } var maxVal = d3.max( arrData ); var color = d3.interpolateRgb("blue","yellow"); var heatMap = d3.select("#graph") .selectAll("rect") .data(arrData) /* Canvasに描画を行いたいとき、最初にコンテキスト(オブジェクト)を 取得する必要があります。ピクセル単位で描画するだけなので 3Dを利用せず、2D(2次元)での描画をします。 また、node()メソッドのあとにgetContext()メソッドがないと動きません。 canvasのコンテキスト取得 */ var context = d3.select("#canvas").node().getContext("2d"); heatMap.enter() .append("rect") .attr("class","block") .attr("x", function(d,i){ return ( i % 8 ) * blockSize; }) .attr("y", function(d,i){ return Math.floor( i / 8 ) * blockSize; }) .attr("width", function(d,i){ return blockSize; }) .attr("height", function(d,i){ return blockSize; }) .style("fill", function(d,i){ return color( d / maxVal ); }) setInterval(function(){ for( i = 0 ; i < arrData.length ; i++){ // -2 ~ 0 の値をnに代入する var n = ( (Math.random() * 3 ) | 0 ) - 2; arrData[i] = arrData[i] + n; if( arrData[i] < 0 ) arrData[i] = 0; if( arrData[i] > maxVal ) arrData[i] = maxVal; } // 更新したデータをセットする heatMap.data(arrData) .style("fill", function(d,i){ var x = ( i % 8 )* blockSize; // X座標値 var y = Math.floor( i / 8 ) * blockSize; // Y座標値 /* 塗り潰す色を設定 fillStyle = カラーコード コンテキスト(オブジェクト)のメソッド、 プロパティとして指定します。 */ context.fillStyle = color( d / maxVal ); /* 塗り潰された四角形を描画 fillRect(X座標,Y座標,幅,高さ) コンテキスト(オブジェクト)のメソッド、 プロパティとして指定します。 */ context.fillRect( x, y, blockSize, blockSize); // SVG要素の塗りを返す return color( d / maxVal ); }) },1000); |