canvas饼状图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <canvas width="600" height="400" style="border: 1px solid #ccc"></canvas>
    <script>
        var PieChart = function () {
            this.ctx = document.querySelector('canvas').getContext('2d');
            // 获取画布的中心
            this.x0 = this.ctx.canvas.width / 2;
            this.y0 = this.ctx.canvas.height / 2;
            // 获取半径
            this.radius = 150;
            // 标题伸出去的距离
            this.outLine = 20;
            // 小矩形距横向间距
            this.spaceX = 10;
            // 小矩形距纵向间距
            this.spaceY=20;
            // 小矩形的宽度
            this.smallW=30;
            // 小矩形的高度
            this.smallH=15;
        }
        // 初始化饼状图
        PieChart.prototype.init = function () {
            this.drawPie();
        }
        // 添加饼图
        PieChart.prototype.drawPie = function () {
            var angleList = this.drawAngle();
            var start = 0; // 开始弧度
            angleList.forEach((item,i) =>{
                var end = item.angle + start;
                this.ctx.beginPath();
                this.ctx.moveTo(this.x0,this.y0);
                this.ctx.arc(this.x0, this.y0, this.radius, start, end);
                this.ctx.fillStyle = this.randomColor();
                this.ctx.fill();

                // 调用标题方法
                this.drawTitle(start, item, this.ctx.fillStyle);
                this.drawInfo(i, item.title, this.ctx.fillStyle)

                start = end;
            });
        }
        // 绘制标题
        PieChart.prototype.drawTitle = function (start, item, color) {
            // 斜边的长度
            var edge = this.radius + this.outLine;
            // x轴方向直角边
            var edgeX = edge * Math.cos(start + item.angle / 2);
            // y轴方向直角边
            var edgeY = edge * Math.sin(start + item.angle / 2);
            // 伸出去的x,y轴横纵坐标
            var outX = this.x0 + edgeX;
            var 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();

            // 添加字体
            var align = outX > this.x0 ? 'left' : 'right';
            this.ctx.font = "15px 微软雅黑";
            this.ctx.textAlign = align;
            this.ctx.baseline = 'bottom';
            this.ctx.fillStyle = color;
            this.ctx.fillText(item.title,outX,outY);

            //添加文字下面的线
            var textW = this.ctx.measureText(item.title).width;
            this.ctx.moveTo(outX, outY);
            outX = outX > this.x0 ? outX + textW : outX - textW;
            this.ctx.lineTo(outX, outY);
            this.ctx.stroke();
        }
        // 信息展示
        PieChart.prototype.drawInfo = function (index, text, color){
            this.ctx.beginPath();
            // 画小矩形
            this.ctx.fillRect(this.spaceX, this.spaceY * (index+1), this.smallW, this.smallH);
            this.ctx.font = "12px 微软雅黑";
            this.ctx.fillStyle = color;
            this.ctx.textAlign="left";
            this.ctx.fillText(text,this.spaceX*2+this.smallW,this.spaceY * (index+1)+this.smallH);
        }
        // 将数据转换为弧度
        PieChart.prototype.drawAngle = function () {
            var total = 0;
            data.forEach(function (item, index) {
                total += Number(item.num);
            })
            // 获取每条数据的弧度
            data.forEach(function (item, index) {
                var angle = Number(item.num) / total * Math.PI * 2;
                item.angle = angle;
            })
            return data;
        }
        // 随机颜色
        PieChart.prototype.randomColor = 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 + ")";
        }
        //创建数据
        var data = [
            {title: "20岁以下", num: 100},
            {title: "20-25岁", num: 200},
            {title: "25-30岁", num: 200},
            {title: "30岁以上", num: 100},
        ];

        var pieChart = new PieChart();
        pieChart.init();//初始化
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值