环形图
假如咱们当初有一组数据:
var data = [{type: "苹果",number: 124},
{type: "香蕉",number: 56},
{type: "栗子",number: 310}
];
咱们心愿采纳环形图来显示,最终的成果如下:
繁多的状况
咱们先不思考边缘的提醒文字和折线,只思考两头的环形如何绘制。
首先,咱们须要求解出数值的和,这样能力会绘制的时候晓得每个环的占比:
var sum = 0;
for (var i = 0; i < data.length; i++) sum += data[i].number;
当初,就能够通过循环的形式一个个绘制圆环了:
// beginDeg 示意以后绘制的环的开始弧度,咱们从 -0.5PI 的中央开始绘制
var beginDeg = -Math.PI * 0.5, deg;
for (var i = 0; i < data.length; i++) {
// 计算占比和和 2PI 相乘得出以后环的弧度
deg = data[i].number / sum * Math.PI * 2;
// 以 (200, 200) 为圆心,内外半径别离是 100 和 200,从弧度 beginDeg 开始,绘制弧度 deg 的圆弧
painter.fillArc(200, 200, 100, 200, beginDeg, deg);
beginDeg += deg; // 计算下一个环的开始弧度
}
具体代码请看评论区的【代码一】
带提醒折线文字
能够发现,折线和文字的绘制关键点在于每个圆弧对应的折线的那三个点的地位,对于地位的计算,咱们借助 rotate 来计算。语法如下:
var dot = $$.rotate(cx, cy, deg, x, y);
点(x,y)围绕核心(cx,cy)旋转 deg 度,最初返回一个长度为 2 的一维数组,示意旋转后点的地位。
基于此,咱们思考如果有一个弧形的核心弧度恰好位于 0 度的状况。那么,连线的前两个点(第三个点基于第二个点就很容易得出了)就天然应该是:[cx+radius,cy]、[cx+radius+10,cy]
,这里假如每段的长度为 10。
对应到具体的代码就是:
var beginDeg = -Math.PI * 0.5, deg;
for (var i = 0; i < data.length; i++) {deg = data[i].number / sum * Math.PI * 2;
var dot1 = $$.rotate(cx, cy, beginDeg + deg * 0.5, cx + radius, cy);
var dot2 = $$.rotate(cx, cy, beginDeg + deg * 0.5, cx + radius + 10, cy);
beginDeg += deg;
}
而对于第三个点,通过察看能够发现:如果第二个位于圆心的左边,就是第二个点右挪动 10,否则左挪动 10。由此可得:
var dot3=[dot2[0]>cx ? dot2[0]+10 : dot2[0]-10 , dot2[1] ];
由此失去了三个点的地位,对于折线而言,间接连接起来即可:
painter
.beginPath()
.moveTo(dot1[0], dot1[1]).lineTo(dot2[0], dot2[1])
.lineTo(dot3[0], dot3[1])
.stroke();
对于文字而言,间接在 dot3 的地位绘制即可,只不过,须要思考到文字是左对齐还是右对齐,和第三个点的求法相似,间接看代码即可:
painter
.config('textAlign' , dot2[0]>cx ? "left" : "right")
.fillText(data[i].type, dot3[0], dot3[1]);
具体代码请看评论区的【代码二】