饼状图
less代码
成图效果,先上代码:
/*
@r,@ul-color,@part,@color-list
可以自己换着玩,试试看
@part是累计百分比的数组,因为less不支持变量的递归定义,所以只能妥协用这种方法
函数的变量的定义涉及到角度计算和边框计算
*/
// 圆的半径
@r:200px;
//底色
@ul-color: #73859F;
//各部分所占的累加百分比(0.1,0.5,0.1,0.2,0.1)
@part:0,0.1,0.6,0.7,0.9,1;
//各个扇形的颜色
@color-list:yellow,blue,red,#fff,rgb(37, 201, 64);
* {
margin: 0;
padding: 0;
}
ul {
width: @r*2;
height: @r*2;
margin: auto;
background-color: @ul-color;
margin-top: 100px;
border-radius: 50%;
position: relative;
overflow: hidden;
li {
list-style: none;
margin: auto;
position: absolute;
border: @r solid transparent;
span {
position: absolute;
font-size: 14px;
top:-@r;
}
}
.fn(@part, @color-list, @r);
}
//绘制函数
.fn(@part-list,@color-list,@r,@i:1) when (@i<length(@part-list)){
//数组中累计百分比的当前值
@acc:extract(@part-list,@i);
//扇形所占的百分比
@rate:extract(@part-list,@i+1) - @acc;
//li元素的边框的宽度
@x:abs(@r*tan(@rate*pi()));
//扇形的颜色
@color:extract(@color-list,@i);
li:nth-child(@{i}){
.sector-fn(@rate,@x,@acc,@color);
}
.fn(@part-list,@color-list,@r,@i+1);
}
//扇形函数
.sector-fn(@rate,@x,@acc,@color) when not(@rate=0.5){
@tag: if((@rate<0.5),0.5*@rate + @acc,0.5*(1 - @rate)+@acc);
left: 50%;
margin-left: -@x;
border-left-width: @x;
border-right-width: @x;
border-top-color: if((@rate<0.5),@color,transparent);
transform: rotate(@tag*360deg);
}
.sector-fn(@rate,@x,@acc,@color) when(@rate=0.5){
border-radius: 50%;
border-top-color: @color;
border-right-color: @color;
transform: rotate(@acc*360deg + 45deg);
}
html 代码:
<ul>
<li><span>10%</span></li>
<li><span>50%</span></li>
<li><span>10%</span></li>
<li><span>20%</span></li>
<li><span>10%</span></li>
</ul>
less安装
less 的安装和使用请参考 less 官网
绘制方法
这段代码花了我好几天时间,具体的操作日后再写。
原理很简单,就是用画三角形的方法画一个个扇形,然后计算所需的旋转角度。画三角形的方法就是设置盒子的 width 和 height 为0,计算边框的宽度画出对应的三角形,麻烦的就是应该怎么去旋转这个扇形。
less 转译后的 css 代码
<style>
* {
margin: 0;
padding: 0;
}
ul {
width: 400px;
height: 400px;
margin: auto;
background-color: #73859F;
margin-top: 100px;
border-radius: 50%;
position: relative;
overflow: hidden;
}
ul li {
list-style: none;
margin: auto;
position: absolute;
border: 200px solid transparent;
}
ul li span {
position: absolute;
font-size: 14px;
top: -200px;
}
ul li:nth-child(1) {
left: 50%;
margin-left: -64.98393925px;
border-left-width: 64.98393925px;
border-right-width: 64.98393925px;
border-top-color: yellow;
transform: rotate(18deg);
}
ul li:nth-child(2) {
border-radius: 50%;
border-top-color: blue;
border-right-color: blue;
transform: rotate(81deg);
}
ul li:nth-child(3) {
left: 50%;
margin-left: -64.98393925px;
border-left-width: 64.98393925px;
border-right-width: 64.98393925px;
border-top-color: red;
transform: rotate(234deg);
}
ul li:nth-child(4) {
left: 50%;
margin-left: -145.3085056px;
border-left-width: 145.3085056px;
border-right-width: 145.3085056px;
border-top-color: #fff;
transform: rotate(288deg);
}
ul li:nth-child(5) {
left: 50%;
margin-left: -64.98393925px;
border-left-width: 64.98393925px;
border-right-width: 64.98393925px;
border-top-color: #25c940;
transform: rotate(342deg);
}
</style>