用原型的方式使用canvas来绘制饼状图

这篇博客介绍了如何利用canvas来绘制饼状图,讲解了弧度的概念以及arc()方法的参数,提供了一种初始化和更新饼状图的方法,并展示了如何模拟数据、转化弧度以及生成随机颜色。通过这些步骤,可以实现每次刷新时饼状图数据和颜色的动态变化。

涉及到的知识
弧度:两条射线从圆心射出形成的一个夹角,夹角所正对的线段就叫弧度 当这个弧长等于圆的半径时,两条射线的夹角为1
一个角有多少弧度 2πr/r=2π 一个圆的角度是360°
一个角度等于多少弧度 2π/360=π/180
用到的方法

  • arc(x,y,r,startAngle ,endAngle,anticlockwise )
  • 参数
    • x 圆心横坐标
    • y 圆心纵坐标
    • r 半径
    • startAngle 开始角度
    • endAngle 结束角度
    • anticlockwise 是否逆时针方向绘制(默认false表示顺时针;true表示逆时针)

开始绘制饼状图

定义一个按方法

 function PieVhart() {
        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;
        //    定义左上角说明的矩形
        //x坐标
        this.declarationX = 20;
       // y坐标
        this.declarationY = 10;
        //宽度
        this.declarationW = 25;
        //高度
        this.declarationH = 15;
    }

初始化饼状图


       PieVhart.prototype.init = function () {
            this.drawPie();
        }

//添加饼图

PieVhart.prototype.drawPie = function () {
        //1.转化为弧度
        var angelList = this.drawAngel();
        var start = 0;//记录开始弧度
        angelList.forEach(function (item, i) {
            var end = start + item.angle;
            this.ctx.beginPath();
            this.ctx.moveTo(this.X0, this.Y0);
            this.ctx.arc(this.X0, this.Y0, this.radius, start, end);
            //设置扇形的随机颜色
            var colors = this.ctx.fillStyle = this.randomColor();
            this.ctx.fill();
            //调用标题的方法
            this.drawTitle(start, item.angle, colors, item.title);
            this.drawText(item.title, i);
            start = end;
        }.bind(this))
    }

//添加标题

PieVhart.prototype.drawTitle = function (start, angel, colors, title) {
        //1.确定伸出去的线=半径+伸出去的小线段(自定义)
        //2.确定对边  即Y轴方向的长度=斜边*sin(角度)
        //3.邻边  即x方向的长度=斜边*cos(角度)
        //4.伸出去的点的横纵坐标
        //    outX=x0+(radius+outLine)*cos(角度)
        //    outY=y0+(radius+outLine)*sin(角度)
        //5.角度在canvas用弧度=当前扇形的起始弧度+对应弧度的一半
        //斜边的长度
        var edge = this.radius + this.outline;
        //x轴方向的直角边
        var edgeX = edge * Math.cos(start + angel / 2);
        //y轴方向的直角边
        var edgeY = edge * Math.sin(start + angel / 2);
        //伸出去的横坐标
        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.font = "14px 微软雅黑";
        var textW = this.ctx.measureText(title).width;
        this.ctx.textBaseline = "bottom"
        //判断
        if (outX > this.X0) {
            this.ctx.fillText(title, outX, outY);
            this.ctx.moveTo(outX, outY);
            this.ctx.lineTo(outX + textW, outY);
        }
        if (outX < this.X0) {
            this.ctx.fillText(title, outX - textW, outY);
            this.ctx.moveTo(outX, outY);
            this.ctx.lineTo(outX - textW, outY);
        }
        this.ctx.strokeStyle = colors;
        this.ctx.stroke();
    }

//添加说明

 PieVhart.prototype.drawText = function (title, i) {
        i *= 2
        this.ctx.fillRect(this.declarationX, this.declarationY * i + this.declarationY, this.declarationW, this.declarationH);
        console.log(this.declarationY * i + this.declarationY);
        this.ctx.font = "14px 幼圆"
        this.ctx.textBaseline = "bottom"
        this.ctx.fillText(title, this.declarationX + this.declarationW + 10, this.declarationY * i + this.declarationY+15);
        console.log( this.declarationY * i + this.declarationY)
    }

模拟数据

 var data = [
        {title: "20岁以下", num: 6},
        {title: "20-25岁", num: 30},
        {title: "25-30岁", num: 20},
        {title: "30岁以上", num: 4},
    ]

转化为弧度的方法

 PieVhart.prototype.drawAngel = function () {
        //获取数据的总和
        var total = 0;
        data.forEach(function (item, i) {
            total += item.num;
        })
        //获取每条数据的弧度
        data.forEach(function (item, i) {
            var angel = item.num / total * 2 * Math.PI;
            item.angle = angel;
        })
        return data;
    };

封装转化为弧度的函数

 PieVhart.prototype.drawAngel = function () {
        //获取数据的总和
        var total = 0;
        data.forEach(function (item, i) {
            total += item.num;
        })
        //获取每条数据的弧度
        data.forEach(function (item, i) {
            var angel = item.num / total * 2 * Math.PI;
            item.angle = angel;
        })
        return data;
    };

封装产生随机颜色的函数

 PieVhart.prototype.randomColor = function () {
        var r = Math.floor(Math.random() * 250);
        var g = Math.floor(Math.random() * 250);
        var b = Math.floor(Math.random() * 250);
        return 'rgb(' + r + ',' + g + ',' + b + ')'
    }

调用原型里面方法

 var pieVhart = new PieVhart();
    pieVhart.init();

最终效果图 每次刷新相对应的都数据都可以相应的改变颜色
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值