canvas实现饼状图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        canvas{
            border: 1px solid #ccc;
            display: block;
            margin: 50px auto;
        }
    </style>
</head>
<body>
    <canvas width="600" height="400"></canvas>
    <script>
        //1.构造函数
        function PieChart() {
            this.ctx = document.querySelector('canvas').getContext('2d');
            //圆心坐标
            this.x0 = this.ctx.canvas.width/2+60;
            this.y0 = this.ctx.canvas.height/2;
            //半径
            this.radius = 150;
            this.outLine = 20;
            // 空隙
            this.space = 20;
            //矩形宽高
            this.rectW = 30;
            this.rectH = 15;
        }
        //2.原型方法
        PieChart.prototype = {
            //初始化
            init: function(){
                this.drawPie(data);
            },
            //绘制饼状图
            drawPie: function(data){
                var angleList = this.changeAngle(data);
                var that = this;
                var startLine = 0;
                angleList.forEach(function(item,i){
                    var endLine = item.angle + startLine;
                    that.ctx.beginPath();
                    that.ctx.moveTo(that.x0,that.y0);
                    that.ctx.arc(that.x0,that.y0,that.radius,startLine,endLine);
                    var color = that.ctx.fillStyle = that.random();
                    that.ctx.fill();
                    that.drawTitle(color,startLine,endLine,item.title);
                    that.drawExplain(i,item.title)
                    that.ctx.stroke();
                    startLine = endLine;
                })
            },
            //绘制title
            drawTitle: function(color,startLine,endLine,title){
                //圆外点坐标
                var outX = (this.radius + this.outLine) * Math.cos((startLine+endLine)/2)+this.x0;
                var outY = (this.radius + this.outLine) * Math.sin((startLine+endLine)/2)+this.y0;
                this.ctx.moveTo(this.x0,this.y0);
                this.ctx.lineTo(outX,outY);
                this.ctx.strokeStyle = color;
                this.ctx.stroke();

                //文字,下划线
                this.ctx.font = '14px 宋体';
                var textW = this.ctx.measureText(title).width;
                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.textBaseline = 'bottom';
                this.ctx.fillText(title,outX,outY-5);
                this.ctx.stroke();
            },
            //绘制说明
            drawExplain: function(i,title){
                this.ctx.beginPath();
                this.ctx.textAlign = 'left';
                this.ctx.textBaseline = 'top';
                this.ctx.fillRect(  this.space,
                                    this.space + i*(this.rectH+10),
                                    this.rectW,
                                    this.rectH);
                //绘制文本
                this.ctx.fillText(title,
                                this.rectW+this.space+10,
                                this.space + i*(this.rectH+10));
            },
            //产生随机颜色
            random: 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+')';
            },
            //装换成弧度
            changeAngle: function(data){
                //求和
                var total = 0;
                data.forEach(function(item,i){
                    total += item.num;
                })
                // console.log(total);
                data.forEach(function(item,i){
                    var angle = item.num/total * 2 *Math.PI;
                    item.angle = angle;
                })
                return data;
            },
        }
        //准备数据
        var data = [
            {
                title:'20岁以下',
                num:15
            },
            {
                title:'20岁-25岁',
                num:36
            },
            {
                title:'25岁-30岁',
                num:29
            },
            {
                title:'30岁-35岁',
                num:11
            },
            {
                title:'35岁-40岁',
                num:10
            },
            {
                title:'40岁以上',
                num:5
            },
        ]
        //3.实例化对象
        var pieChart = new PieChart();
        pieChart.init();
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值