canvas绘制饼状图

标签: canvas

canvas绘制饼状图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>绘制饼状图</title>
    <style>
        canvas {
            border: 1px solid #ccc;
            display: block;
            margin: 100px auto;
        }
    </style>
</head>
<body>
    <canvas width="600" height="400"></canvas>

    <script>
        //1、绘制饼状图
        //2、绘制饼状图标题
        //3、绘制说明

        //创建构造函数
        let PieChart = function () {
            this.ctx = document.querySelector("canvas").getContext("2d");
            //获取画布的宽高
            this.canvasW = this.ctx.canvas.width;
            this.canvasH = this.ctx.canvas.height;
            //获取圆心
            this.x0 = this.canvasW / 2 + 60;
            this.y0 = this.canvasH / 2;
            this.radius = 150;
            //设置伸出的线
            this.outLine = 20;
            //设置矩形的宽高
            this.rectW = 30;
            this.rectH = 15;
            //设置离画布的间距
            this.space = 20;
        };

        PieChart.prototype = {
            //初始化饼状图
            init: function (data) {
                this.drawPie(data);
            },
            //绘制饼图
            drawPie: function (data) {
                //1、准备数据
                let angleList = this.drawAngle(data);
                let that = this;
                //声明一个起始弧度
                let startAngle = 0;
                angleList.forEach(function (item, index) {
                    //结束弧度
                    let endAngle = item.angle + startAngle;
                    that.ctx.beginPath();
                    that.ctx.moveTo(that.x0, that.y0);
                    that.ctx.arc(that.x0, that.y0, that.radius, startAngle, endAngle);
                    that.ctx.closePath();
                    //设置随机颜色
                    let color = that.getColor();
                    that.ctx.fillStyle = color;
                    that.ctx.fill();

                    that.drawTitle(startAngle, endAngle, color, item.title);
                    that.drawDesc(index, item.title, color);
                    startAngle = endAngle;
                })
            },
            //绘制标题
            drawTitle: function (startAngle, endAngle, color, title) {
                //确定从圆心到外面这条线的长度   r + 20
                //计算伸出去点的坐标
                //正弦边 = 斜边 * sin(角度)
                //余弦边 = 斜边 * cos(角度)
                //确定弧度 = (扇形的起始弧度 + 对应弧度)/ 2
                //伸出去的点的坐标  x = x0 + 余弦边     y = y0 + 正弦边

                //斜边的长度
                let edge = this.radius + this.outLine;
                //X轴方向
                let edgeX = edge * Math.cos((startAngle + endAngle) / 2);
                //Y轴方向
                let edgeY = edge * Math.sin((startAngle + endAngle) / 2);
                //伸出去的坐标
                let outX = this.x0 + edgeX;
                let outY = this.y0 + edgeY;
                this.ctx.beginPath();
                this.ctx.moveTo(this.x0, this.y0);
                this.ctx.lineTo(outX, outY);
                this.ctx.strokeStyle = color;
                this.ctx.stroke();

                //画文字和下划线
                //1、判断线的方向
                //设置文字字体
                this.ctx.font = '14px serif';
                let textW = this.ctx.measureText(title).width;
                this.ctx.textBaseline = "bottom";
                //判断
                if (outX > this.x0) {
                    this.ctx.lineTo(outX + textW, outY);
                    this.ctx.textAlign = 'left';
                } else {
                    this.ctx.lineTo(outX - textW, outY);
                    this.ctx.textAlign = 'right';
                }
                this.ctx.fillText(title, outX, outY);
                this.ctx.stroke();
            },
            //绘制说明
            drawDesc: function (index, title, color) {
                // this.ctx.fillStyle = color;
                this.ctx.fillRect(this.space, this.space * (index+1), this.rectW, this.rectH);

                this.ctx.textAlign = "left";
                this.ctx.textBaseline = "top";
                this.ctx.fillText(title, this.space + this.rectW + 10 , this.space * (index+1));

            },
            drawAngle: function (data) {
                let total = 0;
                data.forEach(function (item, index) {
                    total += item.num;
                });
                data.forEach(function (item, index) {
                    let angle = item.num / total * 2 * Math.PI;
                    item.angle = angle;
                });
                return data;
            },
            getColor: function () {
                let r = Math.random() * 256;
                let g = Math.random() * 256;
                let b = Math.random() * 256;
                return "rgb(" + r + "," + g + "," + b + ")";
            }
        };

        let data = [
            {title: "20岁以下", num: 6},
            {title: "30岁以下", num: 19},
            {title: "40岁以下", num: 22},
            {title: "50岁以下", num: 10},
            {title: "60岁以下", num: 2},
        ];

        let pieChart = new PieChart();
        pieChart.init(data);
    </script>
</body>
</html>

效果如图:

饼状图

原文链接:加载失败,请重新获取