溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在html5中使用canvas實(shí)現(xiàn)一個(gè)動(dòng)態(tài)畫餅狀圖

發(fā)布時(shí)間:2021-04-14 15:45:45 來源:億速云 閱讀:245 作者:Leah 欄目:web開發(fā)

怎么在html5中使用canvas實(shí)現(xiàn)一個(gè)動(dòng)態(tài)畫餅狀圖?很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

1.先用canvas畫實(shí)心圓

怎么在html5中使用canvas實(shí)現(xiàn)一個(gè)動(dòng)態(tài)畫餅狀圖

//偽代碼
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è)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(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)容。

AI