JavaScript练手小技巧:用Canvas绘制饼图

最近上课讲到了 Canvas,就写了 demo 练练手。

做一个数据饼图。

饼图是数据可视化很重要的一个组成部分。这个案例虽然没有 Echarts 那么好看,但是作为了解Canvas的基础案例,还是很有必要练习下。

 数据 JSON:name为销售品名; money 为销售额; color 为饼图色彩。

let data = [
    {
        name:"水果",
        moneny:11200,
        color:"#229322"
    },
    {
        name:"电器",
        moneny:36277,
        color:"#2562d9"
    },
    {
        name:"数码",
        moneny:87451,
        color:"#25d98b"
    },
    {
        name:"厨具",
        moneny:47854,
        color:"#d925a6"
    },
    {
        name:"服装",
        moneny:117854,
        color:"#d99125"
    },
];

要获取每个数据的占比,首先要获取销售总额。

// 计算总销售额
let totalMoney = 0;
for(let i=0; i<=data.length-1; i++){
    totalMoney += data[i].moneny ;
}

这个案例的核心是利用 canvas 的 arc() 方法绘制扇形。

cx ,cy 圆心坐标; radius 圆的半径;start,end 是弧的起始和终止弧度。

注意:是弧度,不是 360度的度数。

 ctx.arc(cx,cy,radius,start, end );  // 画弧

这个案例的难点是确定起始弧度结束弧度。

  • 每个扇形弧度为 hudu,其值为 2*Math.PI 的基于数据的分割;
  • 第一个扇形的start 是 -Math.PI/2;end 为 start+ hudu。
  • 后面扇形的 start,就是上一个扇形的 end;end 一直都是 start+hudu

完整代码:

<canvas id="myCan" width="600" height="400"></canvas>
<script>
let data = [
    {
        name:"水果",
        moneny:11200,
        color:"#229322"
    },
    {
        name:"电器",
        moneny:36277,
        color:"#2562d9"
    },
    {
        name:"数码",
        moneny:87451,
        color:"#25d98b"
    },
    {
        name:"厨具",
        moneny:47854,
        color:"#d925a6"
    },
    {
        name:"服装",
        moneny:117854,
        color:"#d99125"
    },
];
    let myCan = document.getElementById("myCan");  // 获取canvas ID
    let ctx = myCan.getContext("2d");  // 获取绘图上下文(环境)
    let radius = 150 ;   // 半径
    let [cx,cy] = [myCan.width/2, myCan.height/2];  // 圆心坐标
    // 计算总销售额
    let totalMoney = 0;
    for(let i=0; i<=data.length-1; i++){
        totalMoney += data[i].moneny ;
    }
    // 绘图
    let start = -Math.PI/2 ;   // 默认开始弧度
    for(let i=0; i<=data.length-1; i++){
        // 结束弧度: start+当前所占的弧度
        let end =start + data[i].moneny/totalMoney*2*Math.PI ;
        ctx.fillStyle = data[i].color ;
        // 画饼图
        ctx.beginPath();
        ctx.moveTo(cx,cy);
        ctx.arc(cx,cy,radius,start, end );  // 画弧
        ctx.fill();
        // 下一个start 是这次的 end。
        start = end ;
    } 
</script>

猜你喜欢

转载自blog.csdn.net/weixin_42703239/article/details/128259441