最近项目中遇到一些占比环形图的需求(如图 ),初始设计方案定为: 1. svg , 2.css3, 3. canvas 。 最终调研后决定使用svg
,业务逻辑更加清晰及技术成本更低一些。
正文
使用 svg
画这种图,肯定就需要用到 svg
的 <path>
元素的椭圆弧指令(A)
SVG椭圆弧路径指令说明:
如此, 我们的实现逻辑就出来了: 把每个占比用 path
元素实现,每一段拼接(因为每个数据占比%最后之后肯定为100%)即可形成一个环形圆
具体逻辑为:
- 最后得到的是一个环形圆,所以椭圆的长短半轴rx, ry在这里就是最后圆的半径
- x-axis-rotation 是占比对应的度数,也就是 2 * PI * per(对应占比 %)
- large-arc-flag: 如果旋转度数(deg) 超过了180度 则为1 否则为 0 ,这里也就表示 如果占比超过50%则为1, 否则为0
- sweep-flag 表示是否为 顺时针 画图, 我们在这里认定 顺时针即可
- 圆弧的终点(x, y) ,这里的逻辑需要通过数学公式需要计算出终点,这里要提醒一点,其实本次的终点就是下一段的起点,这一点很有用
接下来请拿起小本本记下来,这是重点,必考,5分爱要不要~
已知圆心,半径,角度,求圆上的点坐标
圆心坐标:(x0,y0) 半径:r 角度:deg 单位:°
圆周率: PI
则圆上任一点为:(x1,y1)
x1 = x0 + r * cos(deg)
y1 = y0 + r * sin(deg)
这里还有一点:
数学中,我们的坐标系为这样(左),但是在业务中我们需要这样(右)
这里调整很简单,只需要给svg画布 设置一个旋转就好
transform: rotate(-90deg);
复制代码
代码
基本业务逻辑及注意点已经梳理完,接下来就是代码部分
为了简单方便,我通过cdn引入了vue.js
js
// doughnut.js
let vm = new Vue({
el: '#app',
data: {
list: [ // 占比列表
'30%',
'20%',
'