本文章将通过一个简单易懂的实例来想大家阐述如何利用html5的canvas来绘制一个跟随json数据的饼状图,稍作移植,它就可以作为一个轻量级的js饼状图框架。下面让我们来看看示例运行效果:
画饼图重在理解如何计算每块的起始弧度和结束弧度,下面我们通过我的一个示例代码来展示(
欢迎大家提出改进建议
)
Html5部分:
<!DOCTYPE HTML>
<html>
<head>
<title>简单化饼图</title>
<meta charset="utf-8"/>
</head>
<body>
<canvas id="cav" width="800" height="800">
对不起,您的浏览器版本过低,不支持HTML5.
</canvas>
</body>
</html>
var jsondata=[{name:"技术部",num:95},{name:"研发部",num:3},{name:"市场部",num:50},{name:"攻关部",num:20},{name:"信息产业部",num:35},{name:"宣传部",num:50}];
var colors=["#cb4539","#fec655","#feff63","#2ba54e","#2b81b0","#053249","#053649"];
var sum = 0;
var lastsum=0;
window.onload = function(){
var canvas = document.getElementById("cav");
if(cav==null)return;
ctx = canvas.getContext("2d");
sumData();
drawChart();
}
//求数据总和
function sumData(){
for(var i=0;i<jsondata.length;i++){
sum+=jsondata[i].num;
};
}
//下一个起始
function lastSum(i){
lastsum=0;//重置为0
for (var j = 0; j < i; j++) {
lastsum+=jsondata[j].num;
};
}
//画饼图
//半径
var radius=200;
function drawChart(){
for (var i = 0; i < jsondata.length;i++) {
lastSum(i);//上一个结束弧度就是下一个起始弧度
var startAngle= (Math.PI*2)*(lastsum/sum);//起始弧度
lastSum(i+1);
var endAngle=(Math.PI*2)*(lastsum/sum);//结束弧度
ctx.save();
ctx.fillStyle=this.colors[i];
ctx.beginPath();
ctx.moveTo(400,400);
ctx.arc(400,400,radius,startAngle,endAngle,false);
ctx.closePath();
ctx.fill();
ctx.restore();
drawText(startAngle,endAngle,jsondata[i].name,jsondata[i].num/sum);
};
}
//绘制文本和线段
function drawText(s,e,jn,jsm){
//文字的x,y坐标计算
var x = Math.cos((s+e)/2)*(radius+60)+400;
var y = Math.sin((s+e)/2)*(radius+60)+400;
ctx.fillStyle="blue";
ctx.fillText(jn,x,y);
ctx.fillStyle="red";
//百分比精确到小数后两位
ctx.fillText((parseInt(jsm*10000)/100)+"%",x,y+20);
//绘制由每个饼指向文字的线段
ctx.beginPath();
//各端点坐标由每块的起始弧度和结束弧度求平均后计算得出
ctx.moveTo(Math.cos((s+e)/2)*radius+400,Math.sin((s+e)/2)*radius+400);
ctx.lineTo( Math.cos((s+e)/2)*(radius+40)+400, Math.sin((s+e)/2)*(radius+40)+400);
ctx.closePath();
ctx.fillStyle="red";
ctx.stroke();
}
上面就是画饼图的基本思路了,谢谢观赏,祝大家工作顺利!