Canvas(3)---繪製餅狀圖

雨點的名字發表於2020-04-24

Canvas(3)---繪製餅狀圖

有關canvas之前有寫過兩篇文章

1、Canvas(1)---概述+簡單示例

2、Canvas(2)---繪製折線圖

在繪製餅狀圖之前,我們先要理解什麼是圓弧,如何在畫布中繪製文字等等。所以這裡將繪製餅狀圖理解拆分成以下幾個步驟:

1、理解圓弧
2、繪製一段圓弧
3、繪製一個扇形
4、繪製一個六等圓
5、繪製一個根據資料的餅圖
6、繪製在畫布中心的一段文字
7、繪製完整餅狀圖

什麼是弧度 弧度是一種長度的描述單位, 一個半徑的長度就表示一弧度,所以一個圓有2*π個弧度。

一、繪製一段圓弧

效果

Canvas(3)---繪製餅狀圖

程式碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas {
            border: 1px solid #00CED1;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');
    /*引數*/
    /*座標 x y 確定圓心  */
    /*確定圓半徑  r */
    /*確定起始繪製的位置和結束繪製的位置 Math.PI=π 也就是180度*/
    /*取得繪製的方向 direction 預設是順時針 false 逆時針 true */
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    ctx.arc(w/2,h/2,150,Math.PI/2,Math.PI,false);
    ctx.stroke();
</script>
</body>
</html>

思考 為什麼這裡四分之一的弧度是這個方向的,那是因為canvas指定了規則

Canvas(3)---繪製餅狀圖

所以上面 Math.PI/2Math.PI,且是 順時針 的。由這兩點最終繪製的就是上面的效果了。


二、繪製一個扇形

效果

Canvas(3)---繪製餅狀圖

程式碼

<!-- 上面部分程式碼和上面一致,這裡就不重複寫了 -->
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');
    /*在中心位置畫一個半徑150px的圓弧右上角 扇形  邊  填充 */
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    /*把起點放到圓心位置*/
    ctx.moveTo(w/2,h/2);
    ctx.arc(w/2,h/2,150,0,-Math.PI/2,true);
    //注意這裡採用的是填充 ,而不是閉合 ctx.closePath()
    ctx.fill();
</script>

三、繪製一個圓分成六等分顏色隨機

效果

Canvas(3)---繪製餅狀圖

程式碼

<!-- 上面部分程式碼和上面一致,這裡就不重複寫了 -->
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    var w = ctx.canvas.width;
    var h = ctx.canvas.height;

    /*分成幾等分*/
    var num = 6;
    /*一份多少弧度*/
    var angle = Math.PI * 2 / num;
    /*原點座標*/
    var x0 = w / 2;
    var y0 = h / 2;

    /*獲取隨機顏色*/
    var getRandomColor = function () {
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
        return 'rgb(' + r + ',' + g + ',' + b + ')';
    }
    /*上一次繪製的結束弧度等於當前次的起始弧度*/
    for (var i = 0; i < num; i++) {
        var startAngle = i * angle;
        var endAngle = (i + 1) * angle;
        ctx.beginPath();
        ctx.moveTo(x0, y0);
        ctx.arc(x0, y0, 150, startAngle, endAngle);
        /*隨機顏色*/
        ctx.fillStyle = getRandomColor();
        ctx.fill();
    }
</script>

四、繪製一個根據資料的餅圖

上面是平均分成了6等分,這裡是根據具體的資料來按比例分成若干份。

效果

Canvas(3)---繪製餅狀圖

程式碼

<!-- 上面部分程式碼和上面一致,這裡就不重複寫了 -->
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    //資料
    var data = [5, 10, 15, 20];
    /*1.需要把資料轉出弧度 先計算總數*/
    var total = 0;
    data.forEach(function (item, i) {
        total += item;
    });
    //2、計算每個資料所佔的弧度
    var angleList = [];
    data.forEach(function (item, i) {
        var angle = Math.PI * 2 * (item/total);
        angleList.push(angle);
    });
   /* 3、獲取隨機顏色*/
    var getRandomColor = function () {
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
        return 'rgb(' + r + ',' + g + ',' + b + ')';
    }
    /*4.根據弧度繪製扇形*/
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    var x0 = w/2;
    var y0 = h/2;
    var startAngle = 0;
    angleList.forEach(function (item,i) {
        /*上一次繪製的結束弧度等於當前次的起始弧度*/
        var endAngle = startAngle + item;
        ctx.beginPath();
        ctx.moveTo(x0,y0);
        ctx.arc(x0,y0,150,startAngle,endAngle);
        ctx.fillStyle = getRandomColor();
        ctx.fill();
        /*記錄當前的結束位置作為下一次的起始位置*/
        startAngle = endAngle;
    });
</script>

五、繪製在畫布中心的一段文字

效果

Canvas(3)---繪製餅狀圖

程式碼

<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        canvas {
            border: 1px solid #00CED1;
            display: block;
            margin: 100px auto;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');
    /*1.在畫布的中心繪製一段文字*/
    /*2.申明一段文字*/
    var str = '武漢加油';
    /*3.確定畫布的中心*/
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    /*4.畫一個十字架在畫布的中心*/
    ctx.beginPath();
    ctx.moveTo(0, h / 2);
    ctx.lineTo(w, h / 2);
    ctx.moveTo(w / 2, 0);
    ctx.lineTo(w / 2, h);
    ctx.strokeStyle = '#eee';
    ctx.stroke();
    /*5.繪製文字*/
    ctx.beginPath();
    ctx.strokeStyle = '#000';
    var x0 = w/2;
    var y0 = h/2;
    /*注意:起點位置在文字的左下角*/
    /*有文字的屬性  尺寸 字型  左右對齊方式  垂直對齊的方式*/
    ctx.font = '40px Microsoft YaHei';
    /*左右對齊方式 (center left right start end) 基準起始座標*/
    ctx.textAlign = 'center';
    /*垂直對齊的方式 基線 baseline(top,bottom,middle) 基準起始座標*/
    ctx.textBaseline = 'middle';
    //ctx.direction = 'rtl';
    //ctx.strokeText(str,x0,y0);
    ctx.fillText(str,x0,y0);
    /*6.畫一個下劃線和文字一樣長*/
    ctx.beginPath();
    /*獲取文字的寬度*/
    console.log(ctx.measureText(str));
    var width = ctx.measureText(str).width;
    ctx.moveTo(x0-width/2,y0 + 20);
    ctx.lineTo(x0+width/2,y0 + 20);
    ctx.stroke();
</script>
</body>
</html>

六、繪製完整餅狀圖

上面所做的都是為了整個餅狀圖做鋪墊的。

效果

Canvas(3)---繪製餅狀圖

程式碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas {
            border: 1px solid #00CED1;
            display: block;
            margin: 100px auto;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    /*1.在畫布的中心繪製一段文字*/
    /*2.申明一段文字*/
    var str = '武漢加油';
    /*3.確定畫布的中心*/
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    /*4.畫一個十字架在畫布的中心*/
    ctx.beginPath();
    ctx.moveTo(0, h / 2);
    ctx.lineTo(w, h / 2);
    ctx.moveTo(w / 2, 0);
    ctx.lineTo(w / 2, h);
    ctx.strokeStyle = '#eee';
    ctx.stroke();
    /*5.繪製文字*/
    ctx.beginPath();
    ctx.strokeStyle = '#000';
    var x0 = w/2;
    var y0 = h/2;
    /*注意:起點位置在文字的左下角*/
    /*有文字的屬性  尺寸 字型  左右對齊方式  垂直對齊的方式*/
    ctx.font = '40px Microsoft YaHei';
    /*左右對齊方式 (center left right start end) 基準起始座標*/
    ctx.textAlign = 'center';
    /*垂直對齊的方式 基線 baseline(top,bottom,middle) 基準起始座標*/
    ctx.textBaseline = 'middle';
    //ctx.direction = 'rtl';
    //ctx.strokeText(str,x0,y0);
    ctx.fillText(str,x0,y0);
    /*6.畫一個下劃線和文字一樣長*/
    ctx.beginPath();
    /*獲取文字的寬度*/
    console.log(ctx.measureText(str));
    var width = ctx.measureText(str).width;
    ctx.moveTo(x0-width/2,y0 + 20);
    ctx.lineTo(x0+width/2,y0 + 20);
    ctx.stroke();
</script>
</body>
</html>


別人罵我胖,我會生氣,因為我心裡承認了我胖。別人說我矮,我就會覺得好笑,因為我心裡知道我不可能矮。這就是我們為什麼會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(11)

相關文章