大家好,我是梦辛工作室的灵,近期在制作数据统计类的软件,所以会用到许多的图形和图表,下面我就来说明下饼图的绘制方法,依旧老规矩,先上效果图=-=:
看上去还是可以的吧,下面直接来看代码,我为了提供代码的阅读性写了不少变量,不然不好阅读啊:
function drawCircelChart(that){
let width = app.globalData.width; //手机宽度
let height = app.globalData.height; //手机高度
let data = [ //绘制数据
{
name:"1号",
pre:10,
},
{
name:"2号",
pre:5,
},
{
name:"3号",
pre:20,
},
{
name:"4号",
pre:30,
},
{
name:"5号",
pre:10,
},
{
name:"6号",
pre:25,
},
];
let rectWidth = width * 0.9; //定义画布宽度
let rectHeight = height * 0.26; //定义画布高度
let circlePath = width * 0.2; //定义圆的半径
let ringWidth = 20; //定义 外环的宽度
let centerPoint = { //计算中心中标(圆点)
x:rectWidth / 2,
y:rectHeight / 2
}
let ctx = wx.createCanvasContext('cchart');
ctx.translate(0,40); //画布下移动
ctx.setFontSize(12); //字体大小
let colorArray = ["#FFC655","#FADD15","#FD7170","#B391DD","#00A0F8","#5DC97D","#50D2C2"
,"#FADB15","#AABD15","#FCDD55","#CB5D15"]; //颜色数组
let preEndAngel = 0; //上一个数据的结束时的角度
for(var x in data){
//处理数据
//计算当前数据的开始角度和结束角度
let roateAngel = {
start:preEndAngel,
end:preEndAngel + data[x].pre / 100 * 2 * Math.PI,
}
//绘制圆弧
ctx.beginPath();
ctx.moveTo(centerPoint.x,centerPoint.y);
ctx.arc(centerPoint.x, centerPoint.y, circlePath, roateAngel.start,roateAngel.end);
ctx.setFillStyle(colorArray[x] || "#000");
ctx.fill();
preEndAngel = roateAngel.end;
ctx.setFillStyle("#000");
//下面就有点点难度了,其实只要你三角函数学 的号也没撒,
//下面代码就是绘制每个模块的位置
//需要分四种类型,即四象限,不知道大家还记得否
//然后就是已知角度,计算当前圆弧中心点和圆的交点坐标
let halfAngel = (roateAngel.end - roateAngel.start) / 2;
let centerAngel = roateAngel.start + halfAngel;
let offset = {
x:10,
y:10
}
let textPoint = {
x:0,
y:0
}
if(centerAngel <= Math.PI / 2){
textPoint.x = centerPoint.x + circlePath * Math.cos(centerAngel) + offset.x;
textPoint.y = centerPoint.y + circlePath * Math.sin(centerAngel) + offset.y;
ctx.setTextAlign("left");
if(centerAngel == Math.PI / 2){
ctx.setTextAlign("center");
textPoint.y = centerPoint.y + circlePath * Math.sin(centerAngel) + offset.y * 2;
}
ctx.setTextBaseline("top");
ctx.fillText(data[x].pre + "%", textPoint.x,textPoint.y);
ctx.setTextBaseline("bottom");
ctx.fillText(data[x].name,textPoint.x,textPoint.y);
} else if(centerAngel < Math.PI){
textPoint.x = centerPoint.x - circlePath * Math.cos(Math.PI - centerAngel) - offset.x * data[x].name.length / 2;
textPoint.y = centerPoint.y + circlePath * Math.sin(Math.PI - centerAngel) + offset.y * data[x].name.length / 2;
ctx.setTextAlign("center");
ctx.setTextBaseline("top");
ctx.fillText(data[x].pre + "%",textPoint.x,textPoint.y);
ctx.setTextBaseline("bottom");
ctx.fillText( data[x].name ,textPoint.x,textPoint.y);
} else if(centerAngel < Math.PI * 3 / 2){
textPoint.x = centerPoint.x - circlePath * Math.cos(centerAngel - Math.PI) - offset.x * data[x].name.length / 2;
textPoint.y = centerPoint.y - circlePath * Math.sin(centerAngel - Math.PI) - offset.y * data[x].name.length / 2;
ctx.setTextAlign("right");
//ctx.setTextBaseline("middle");
ctx.setTextBaseline("top");
ctx.fillText( data[x].pre + "%",textPoint.x,textPoint.y);
ctx.setTextBaseline("bottom");
ctx.fillText(data[x].name ,textPoint.x,textPoint.y);
} else {
textPoint.x = centerPoint.x + circlePath * Math.cos(Math.PI * 2 - centerAngel) + offset.x;
textPoint.y = centerPoint.y - circlePath * Math.sin(Math.PI * 2 - centerAngel) - offset.y;
ctx.setTextAlign("left");
ctx.setTextBaseline("top");
ctx.fillText( data[x].pre + "%",textPoint.x,textPoint.y);
ctx.setTextBaseline("bottom");
ctx.fillText(data[x].name ,textPoint.x,textPoint.y);
}
}
//最后再在中心绘制一个白圆,这样就是上面的效果啦
ctx.beginPath();
ctx.setFillStyle("#FFFFFF");
ctx.moveTo(centerPoint.x,centerPoint.y);
ctx.arc(centerPoint.x, centerPoint.y, circlePath - ringWidth,0,2 * Math.PI);
ctx.fill();
ctx.draw();
}