您好,登錄后才能下訂單哦!
怎么在html5中使用canvas實(shí)現(xiàn)一個(gè)動(dòng)態(tài)畫餅狀圖?很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
1.先用canvas畫實(shí)心圓
//偽代碼 var canvas = document.createElement("canvas"); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,開始角,結(jié)束角); ctx.fillStyle = 'green'; ctx.closePath(); ctx.fill();
2.根據(jù)不同顏色繪制餅狀圖
//偽代碼 var canvas = document.createElement("canvas"); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,綠色開始角,綠色結(jié)束角); ctx.fillStyle = 'green'; ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,紅色開始角,紅色結(jié)束角); ctx.fillStyle = 'red'; ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,黃色開始角,黃色結(jié)束角); ctx.fillStyle = 'yellow'; ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,紫色開始角,紫色結(jié)束角); ctx.fillStyle = 'purple'; ctx.closePath(); ctx.fill();
3.動(dòng)態(tài)繪制餅狀圖
動(dòng)態(tài)繪制圓網(wǎng)上普遍推薦三種方法:requestAnimationFrame、setInterval(定時(shí))、還有動(dòng)態(tài)算角度的。
這里我用的是第一種requestAnimationFrame方式。
在編寫的過程中發(fā)現(xiàn)一個(gè)問題,就是動(dòng)態(tài)畫圓時(shí)并不是以圓心的坐標(biāo)畫的。為了解決這一問題,需要在每次畫圓時(shí)重新將canvas的畫筆的坐標(biāo)定義為最初圓心的坐標(biāo)。
<!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":"產(chǎn)品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":"產(chǎn)品2","sales":[122.41 ,133.16 ,145.65 ,158.00 ,164.84 ,178.62 ,185.70 ,190.13 ,195.53 ,198.88 ,204.32 ,210.91]}, {"product":"產(chǎn)品3","sales":[170.30 ,175.00 ,170.79 ,165.10 ,165.62 ,160.92 ,155.92 ,145.77 ,145.17 ,140.27 ,135.99 ,130.33]}, {"product":"產(chǎn)品4","sales":[165.64 ,170.15 ,175.10 ,185.32 ,190.90 ,190.01 ,187.05 ,183.74 ,177.24 ,181.90 ,179.54 ,175.98]} ] var dom_circle = document.getElementById('circle'); if(dom_circle != undefined && dom_circle != null) { var canvas = document.createElement("canvas"); dom_circle.appendChild(canvas); var ctx = canvas.getContext('2d'); var defaultStyle = function(Dom,canvas){ if(Dom.clientWidth <= 300) { canvas.width = 300; Dom.style.overflowX = "auto"; } else{ canvas.width = Dom.clientWidth; } if(Dom.clientHeight <= 300) { canvas.height = 300; Dom.style.overflowY = "auto"; } else { canvas.height = Dom.clientHeight; } //坐標(biāo)軸區(qū)域 //注意,實(shí)際畫折線圖區(qū)域還要比這個(gè)略小一點(diǎn) return { p1:'green', p2:'red', p3:'yellow', p4:'purple', x: 0 , //坐標(biāo)軸在canvas上的left坐標(biāo) y: 0 , //坐標(biāo)軸在canvas上的top坐標(biāo) maxX: canvas.width , //坐標(biāo)軸在canvas上的right坐標(biāo) maxY: canvas.height , //坐標(biāo)軸在canvas上的bottom坐標(biāo) r:(canvas.width)/2, //起點(diǎn) ry:(canvas.height)/2, //起點(diǎn) cr: (canvas.width)/4, //半徑 startAngle:-(1/2*Math.PI), //開始角度 endAngle:(-(1/2*Math.PI)+2*Math.PI), //結(jié)束角度 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 = ds.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>
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。