美文网首页工作生活
canvas之饼状图

canvas之饼状图

作者: 小透明进击战 | 来源:发表于2019-06-30 16:29 被阅读0次
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        canvas {
            border: 1px dashed pink;
            display: block;
            margin: 100px auto;
        }
    </style>
</head>
<body>
<canvas width="600px" height="400px"></canvas>
<script>
    var myCanvas=document.querySelector('canvas');
    var ctx=myCanvas.getContext('2d');
    //构造函数
    var PieChart=function(ctx){
//        获取画布和上下文
        this.ctx = ctx||document.querySelector('canvas').getContext('2d');
//        获取画布的宽高
        this.w=this.ctx.canvas.width;
        this.h=this.ctx.canvas.height;
        //圆心点
        this.x0=this.w/2+60;
        this.y0=this.h/2;
        //半径
        this.radius=150;
        //超出饼状图的线
        this.outline=20;
        //矩形说明距离画布左边和上边的的宽度
        this.space=20;
        //矩形说明的宽度
        this.rectW=30;
        //矩形说明的高度
        this.rectH=16;

    };
    //初始化
    PieChart.prototype.init=function(data){
        //调用函数画饼状图
        this.drawPie(data);

    };
    //画饼状图
    PieChart.prototype.drawPie=function(data){
//        转化弧度,包含三个属性的数字
        var angleList=this.transformAngle(data);
        //画饼状图
        var startAngle=0;
        var that=this;
        angleList.forEach(function(item,i){
            var endAngle=startAngle+item.angle;
            that.ctx.beginPath();
            that.ctx.moveTo(that.x0,that.y0);
            that.ctx.arc(that.x0,that.y0,that.radius,startAngle,endAngle);
            //为弧度添加随机颜色
            var color=that.ctx.fillStyle=that.getRandomColor();
            //不要忘记填充。。。。
            that.ctx.fill();
            that.addTitle(startAngle,item.angle,color,item.title);
            that.addRect(i,item.title);
            //这次结束弧度是下次弧度的开始
            startAngle=endAngle;

        })


    };
    //添加标题
    PieChart.prototype.addTitle=function(startAngle,angle,color,title){
        //从圆心拉一条线出来
        var slash=this.radius+this.outline;
        //找出斜线和饼状图的焦点
        var slashX=this.x0+Math.cos(startAngle+angle/2)*slash;
        var slashY=this.y0+Math.sin(startAngle+angle/2)*slash;
        //将点连成线
        this.ctx.beginPath();
        this.ctx.moveTo(this.x0,this.y0);
        this.ctx.lineTo(slashX,slashY);
        this.ctx.strokeStyle=color;
        //改变文字的大小
        this.ctx.font='14px';
        //画文字下面的一条线
        var textLength=this.ctx.measureText(title).width;
//        如果伸出去的横坐标在圆心的右边,就加,如果在左边,就减
        if(slashX>this.x0){
            var textX=slashX+textLength;
            var textY=slashY;
            this.ctx.lineTo(textX,textY);
            this.ctx.textAlign='left';
        }else{
            var textX=slashX-textLength;
            var textY=slashY;
            this.ctx.lineTo(textX,textY);
            this.ctx.textAlign='right';
        }

        this.ctx.stroke();
        this.ctx.textBaseline='bottom';
        this.ctx.fillText(title,slashX,slashY);

    };
    //添加左边说明
    PieChart.prototype.addRect=function(index,title){
        this.ctx.fillRect(this.space,this.space+index*(this.space+this.rectH),this.rectW,this.rectH);
        //重新开启一个路径
        this.ctx.beginPath();
        this.ctx.textAlign='left';
        this.ctx.textBaseline='top';
        this.ctx.fillText(title,this.space+this.rectW+10,this.space+index*(this.space+this.rectH));

    };
    //将数据转换成弧度
    PieChart.prototype.transformAngle=function(data){
        //计算总人数
        var sum=0;
        data.forEach(function(item,i){
            sum+=item.num;
        });
        //按比例分弧度
        data.forEach(function(item,i){
            var angle=item.num/sum*Math.PI*2;
            //将弧度添加到数组中,作为他的属性
            item.angle=angle;
        });
        return data;
    };
    //添加随机颜色
    PieChart.prototype.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+')';

    };
    var data=[
        {
            title:'15-20岁之间',
            num:6
        },
        {
            title:'20-25岁之间',
            num:30
        },
        {
            title:'25-30岁之间',
            num:10
        },
        {
            title:'30岁以上',
            num:8
        }
    ];
    var pieObj=new PieChart(ctx);
    pieObj.init(data);

</script>
</body>
</html>

相关文章

网友评论

    本文标题:canvas之饼状图

    本文链接:https://www.haomeiwen.com/subject/ymybcctx.html