本文介紹了利用html5 canvas動態畫餅狀圖的範例程式碼,分享給大家,具體如下:
先來看效果圖
這裡並沒引用jquery等第三方函式庫,只是用dom操作和canvas的特性寫的。
canvas畫圓大體分為實心圓和空心圓。
根據需求分析知道該圓為實心圓。
1.先用canvas畫實心圓
//偽代碼var canvas = document.createElement(canvas);var ctx = canvas.getContext('2d');ctx.beginPath();ctx.arc(圓心x軸座標,圓心y軸座標,半徑,開始角,結束角);ctx.fillStyle = 'green';ctx.closePath();ctx.fill();
2.根據不同顏色繪製餅狀圖
//偽代碼var canvas = document.createElement(canvas);var ctx = canvas.getContext('2d');ctx.beginPath();ctx.arc(圓心x軸座標,圓心y軸座標,半徑,綠色開始角,綠色結束角);ctx.fillStyle = 'green';ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(圓心x軸座標,圓心y軸座標,半徑,紅色開始角,紅色結束角);ctx.fillStyle = 'red';ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(圓心x軸座標,圓心y軸座標,半徑,黃色開始角,黃色結束角);ctx.fillStyle = 'yellow';ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(圓心x軸座標,圓心y軸座標,半徑,紫色開始角,紫色結束角);ctx.fillStyle = 'purple';ctx.closePath();ctx.fill();
3.動態繪製餅狀圖
動態繪製圓網上普遍推薦三種方法:requestAnimationFrame、setInterval(定時)、還有動態算角度的。
這裡我用的是第一種requestAnimationFrame方式。
在編寫的過程中發現一個問題,就是動態畫圓時並不是用圓心的座標畫出來的。為了解決這個問題,需要在每次畫圓時重新將canvas的畫筆的座標定義為最初圓心的座標。
<!DOCTYPE html><html><head> <meta charset=utf-8> <title></title> <style> #graph {/* border: 1px solid black; height: 100%; width: 100%; box-sizing: border-box;*/ } </style></head><body><div id=circle style=width: 500px;float: left;></div></body></html><script type=text/javascript>(function(window,undefined){ var data = [ {product:產品1,sales:[192.44 , 210.54 ,220.84 ,230.11 ,220.85 ,210.59 ,205.49 ,200.55 ,195.71 ,187.46 ,180.66 ,170.90]}, {product:產品2,sales:[122.41 ,133.16 ,145.65 15.008, 18.084,720,084 17. ,190.13 ,195.53 ,198.88 ,204.32 ,210.91]}, {product:產品3,sales:[170.30 ,175.00 ,170.79 ,165.10 165. ,145.17 ,140.27 ,135.99 ,130.33]}, {product:產品4,sales:[165.64 ,170.15 ,175.10 ,185.32 ,190.90.190. ,181.90 ,179.54 ,175.98]} ] var dom_circle = document.getElementById('circle'); if(dom_circle != undefined && dom_circle != nullull) { var canvass = docm. dom_circle.appendChild(canvas); var ctx = canvas.getContext('2d'); var defaultStyle = function(Dom,canvas){ if(Dom.clientWidth <= 300) { canvas.width = 300X.stylestyle. = auto; } else{ canvas.width = Dom.clientWidth; } if(Dom.clientHeight <= 300) { canvas.height = 300; Dom.style.overflowY = auto; } else { canvas.height = Dom.clientHeight; } //座標軸區域//注意,實際畫折線圖區域還要比這個略小一點return { p1:'green', p2:'red', p3:'yellow', p4:'purple', x: 0 , //座標軸在canvas上的left座標y: 0 , //座標軸在canvas上的top座標maxX: canvas.width , //座標軸在canvas上的right座標maxY: canvas.height , //座標軸在canvas上的bottom座標r:(canvas.width)/2, //起點ry:(canvas.height)/2, //起點cr: (canvas.width)/4, //半徑startAngle:-(1/2*Math.PI), //開始角度endAngle:(-(1/2*Math.PI)+2*Math.PI), / /結束角度xAngle:1*(Math.PI/180) //偏移}; } //畫圓var tmpAngle = -(1/2*Math.PI); var ds = null; var sum = data[0]['sales'][0]+data[0]['sales'][1]+data[0]['sales'][2]+data[0]['sales'][3 ] var percent1 = data[0]['sales'][0]/sum * Math.PI * 2 ; var percent2 = data[0]['sales'][1]/sum * Math.PI * 2 + percent1; var percent3 = data[0]['sales'][2]/sum * Math.PI * 2 + percent2; var percent4 = data[0]['sales'][3]/sum * Math.PI * 2 + percent3; console.log(percent1); console.log(percent2); console.log(percent3); console.log(percent4); var tmpSum = 0; var drawCircle = function(){ if(tmpAngle >= ds.endAngle) { return false; } else if(tmpAngle+ ds.xAngle > ds.endAngle) { tmpAngle = .xAngle > ds.endAngle) { tmpAngle = . endAngle; } else{ tmpAngle += ds.xAngle; tmpSum += ds.xAngle } // console.log(ds.startAngle+'***'+tmpAngle); // console.log(tmpSum); // ctx.clearRect(ds.x,ds.y,canvas. width,canvas.height); if(tmpSum > percent1 && tmpSum <percent2) { ctx.beginPath(); ctx.moveTo(ds.r,ds.ry); ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle+percent1,tmpAngle); ctx.fillStyle = ds.p2; } else if( tmpSum > percent2 && tmpSum <percent3) { ctx.beginPath(); ctx.moveTo(ds.r,ds.ry); ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle+percent2,tmpAngle); ctx.fillStyle = ds.p3; } else if( tmpSum > percent3 ) { ctx.beginPath(); ctx.moveTo(ds.r,ds.ry); ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle+percent3,tmpAngle); ctx.fillStyle = ds.p4; } else{ ctx.beginPath(); ctx.moveTo(ds.r, ds.ry); ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle,tmpAngle); ctx.fillStyle = ds.p1; } ctx.closePath(); ctx.fill(); requestAnimationFrame(drawCircle); } this.toDraw = function(){ ds= defaultStyle(dom_circle,canvas); // console.log( tmpAngle); // console.log(ds.xAngle) ctx.clearRect(ds.x,ds.y,canvas.width,canvas.height); drawCircle(); } this.toDraw(); var self = this; window.onresize = function(){ self.toDraw() } }})(window); </script>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。