用CSS和SVG制作饼图,设计一个心灵手巧的

用CSS和SVG制作饼图

2015/08/10 · CSS ·
SVG

原稿出处: Lea
Verou   译文出处:lulux的博客   

在关乎到CSS技术时,没有人会比Lea
Verou更执着、然则又丰硕聪明,努力去找寻难题的各类解决方案。目前,Lea自己创作、设计和出版了一本书——CSS
Secrets,那本书那一个有趣,包蕴一些CSS小技巧以及解决广大难题的技艺。若是您觉得温馨的CSS技术还不错,看看那本书,你会大吃一惊的。在那篇小说中,大家宣布了书里的一对有的,那也被登载在Lea最近在SmashingConf
New
York的演说内容中——用CSS设计简约的饼图。注意,因为浏览器的辅助少数,有些demo可能无法健康运作。——编辑

饼图,即便是最简便的唯有三种颜色的款式,用Web技术创立也并不简单,尽管都是有些大面积的新闻内容,从不难的总括到进度条目标还有计时器。常常是利用外部图像编辑器来分别为七个值创立八个图像来贯彻,或是使用大型的JavaScript框架来设计更复杂的图形。

尽管这一个东西并不像它早已看起来那么难以达成,不过也从没怎么间接并且简单的措施。可是,现在早已有为数不少更好、更便于维护的不二法门来落到实处它。


用 CSS3 绘制你需求的几何图形

2016/08/12 · CSS

原文出处: 流浪的作家   

1、圆形

示例:亚洲必赢官网 1

思路:给其余正方形元素设置一个十足大的 border-radius
,就足以把它成为一个圆形.代码如下:

html:

XHTML

<div class=”size example1″></div>

1
<div class="size example1"></div>

css:

CSS

.size{ width:200px; height: 200px; background: #8BC34A; } .example1{
border-radius:100px; }

1
2
3
4
5
6
7
8
.size{
    width:200px;
    height: 200px;
    background: #8BC34A;
}
.example1{
    border-radius:100px;
}

2、自适应椭圆

亚洲必赢官网 2

思路:border-radius
那一个特性还有其余一个无人问津的精神,它不仅可以承受长度值,仍是可以接受百分比率。这几个百分比值会基于元素的尺寸进行解析.那意味着相同的比重可能会推测出不一致的水平和垂直半径。代码如下:

html:

XHTML

<div class=”example3″></div>

1
<div class="example3"></div>

css:

CSS

.example3{ width:200px; height: 150px; border-radius:50%; background:
#8BC34A; }

1
2
3
4
5
6
.example3{
    width:200px;
    height: 150px;
    border-radius:50%;
    background: #8BC34A;
}

3、自适应的半椭圆:沿横轴劈开的半椭圆

亚洲必赢官网 3

思路:border-radius 的语法比大家想像中灵活得多。你也许会好奇地觉察
border-radius
原来是一个简写属性。第一种办法就是行使它所对应的逐条展开式属性:

  • „ border-top-left-radius
  • „ border-top-right-radius
  • „ border-bottom-right-radius
  • „ border-bottom-left-radius

俺们甚至可以为具有五个角提供完全两样的水准和垂直半径,方法是在斜杠前点名
1~4 个值,在斜杠后指定别的 1~4 个值。举例来说,当 border-radius
的值为10px / 5px 20px 时,其意义一定于 10px 10px 10px 10px / 5px 20px
5px 20px 。

为 border-radius 属性分别指定4、3、2、1
个由空格分隔的值时,那个值是以如此的法则分配到多少个角上的(请留心,对椭圆半径来说,斜杠前和斜杠后最多可以各有四个参数,那两组值是以平等的主意分配到种种角的)

亚洲必赢官网 4

代码如下:自适应的半椭圆:沿横轴劈开的半椭圆

html:

XHTML

<div class=”example4″></div>

1
<div class="example4"></div>

css:

CSS

.example4{ width:200px; height: 150px; border-radius: 50% / 100% 100% 0
0; background: #8BC34A; }

1
2
3
4
5
6
.example4{
    width:200px;
    height: 150px;
    border-radius: 50% / 100% 100% 0 0;
    background: #8BC34A;
}

4、自适应的半椭圆:沿纵轴劈开的半椭圆

亚洲必赢官网 5

思路:自适应的半椭圆:沿纵轴劈开的半椭圆

代码如下:

html:

XHTML

<div class=”example5″></div>

1
<div class="example5"></div>

css:

CSS

.example5{ width:200px; height: 150px; border-radius: 100% 0 0 100% /
50%; background: #8BC34A; }

1
2
3
4
5
6
.example5{
    width:200px;
    height: 150px;
    border-radius: 100% 0 0 100% / 50%;
    background: #8BC34A;
}

5、四分之一椭圆

思路:其中一个角的水平和垂直半径值都亟待是100%,而其余三个角都无法设为圆角。

亚洲必赢官网 6

代码如下:

html:

XHTML

<div class=”example6″></div>

1
<div class="example6"></div>

css:

CSS

.example6{ width:160px; height: 100px; border-radius: 100% 0 0 0;
background: #8BC34A; }

1
2
3
4
5
6
.example6{
    width:160px;
    height: 100px;
    border-radius: 100% 0 0 0;
    background: #8BC34A;
}

 6、用椭圆绘制opera浏览器的logo

亚洲必赢官网 7

思路:绘制opera浏览器的logo,分析起来简单,就唯有三个图层,一个是最尾部的扁圆形,一个是最上边那层的椭圆。先确定一下最底部的扁圆形宽高,量了一晃,水平大幅度为258px,垂直中度为275px,因为其是一个对称的扁圆形,没有倾斜度,故4个角均为水平半径为258px,垂直半径为275px的4个极度椭圆,用相同的不二法门规定最里面的扁圆形的半径,由此,多少个角均为水平半径120px,垂直半径为229px的扁圆形,代码如下:

html:

XHTML

<div class=”opera”> <div class=”opera-top”></div>
</div>

1
2
3
<div class="opera">
        <div class="opera-top"></div>
</div>

css:

CSS

.opera{ width:258px; height: 275px; background: #F22629;
border-radius:258px 258px 258px 258px /275px 275px 275px 275px;
position: relative; } .opera-top{ width: 112px; height: 231px;
background: #FFFFFF; border-radius: 112px 112px 112px 112px/231px 231px
231px 231px; position: absolute; left: 50%; right: 50%; top: 50%;
bottom: 50%; margin-left: -56px; margin-top: -115px; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.opera{
    width:258px;
    height: 275px;
    background: #F22629;
    border-radius:258px 258px 258px 258px /275px 275px 275px 275px;
    position: relative;
}
.opera-top{
    width: 112px;
    height: 231px;
    background: #FFFFFF;
    border-radius: 112px 112px 112px 112px/231px 231px 231px 231px;
    position: absolute;
    left: 50%;
    right: 50%;
    top: 50%;
    bottom: 50%;
    margin-left: -56px;
    margin-top: -115px;
}

 7、平行四边形

亚洲必赢官网 8

思路:伪元素方案:是把装有样式(背景、边框等)应用到伪元素上,然后再对
伪元素举行变形。因为我们的始末并不是带有在伪元素里的,所以内容并不会受到变形的熏陶。代码如下:

html:

XHTML

<div class=”button”>transform:skew()</div>

1
<div class="button">transform:skew()</div>

css:

CSS

.button { width:200px; height: 100px; position: relative; left: 100px;
line-height: 100px; text-align: center; font-weight: bolder; }
.button::before { content: ”; /* 用伪元素来生成一个矩形 */
  position: absolute;   top: 0; right: 0; bottom: 0; left: 0;
  z-index: -1;   transform: skew(45deg);   background: #8BC34A; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.button {
    width:200px;
    height: 100px;
    position: relative;
    left: 100px;
    line-height: 100px;
    text-align: center;
    font-weight: bolder;
}
.button::before {
   content: ”; /* 用伪元素来生成一个矩形 */
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: -1;
  transform: skew(45deg);
  background: #8BC34A;
}

技巧统计:这一个技能不仅对 skew()
变形来说很有用,还适用于此外任何变形样式,当大家想变形一个元素而不想变形它的内容时就足以用到它。

8、菱形

亚洲必赢官网 9

思路:大家把这么些技术针对 rotate()
变形样式稍稍调整一下,再用到一个正方形元素上,就可以很简单地收获一个菱形。代码如下:

html:

XHTML

<div class=”example1″>transform:rotate()</div>

1
<div class="example1">transform:rotate()</div>

css:

CSS

.example1 { width:140px; height: 140px; position: relative; left: 100px;
line-height: 100px; text-align: center; font-weight: bolder; }
.example1::before { content: ”; position: absolute; top: 0; right: 0;
bottom: 0; left: 0; z-index: -1; transform: rotate(45deg); background:
#8BC34A; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.example1 {
    width:140px;
    height: 140px;
    position: relative;
    left: 100px;
    line-height: 100px;
    text-align: center;
    font-weight: bolder;
}
.example1::before {
    content: ”;
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: -1;
    transform: rotate(45deg);
    background: #8BC34A;
}

技术总括:那几个技术的关键在于,我们应用伪元素以及定位属性发生了一个四方,
然后对伪元素设置样式,并将其放置在其宿主元素的下层。这种思路同样可以利用在其余场景中,从而得到各个各类的法力。

9、菱形图片

亚洲必赢官网 10

思路:基于变形的方案,
大家想让图片的拉长率与容器的对角线相等,而不是与边长相等。需求采取勾股定理,那个定律告诉大家,一个正方形的对角线长度等于它的边长乘以根号2,相当于1.414 213 562
 。因此,把 max-width 的值设置为根号2加倍100%相当于 414.421 356 2%
是很客观的,或者把那个值向上取整为 142% ,因为我们不指望因为总结的舍入难点导致图片在骨子里突显时稍小(但稍大是没难题的,反正我们都是在裁切图片嘛)

代码如下:

html:

XHTML

<div class=”picture”> <img src=”./imgs/7.jpg”> </div>

1
2
3
<div class="picture">
    <img src="./imgs/7.jpg">
</div>

css:

CSS

用CSS和SVG制作饼图,设计一个心灵手巧的。.picture { width: 200px; transform: rotate(45deg); overflow: hidden;
margin: 50px; } .picture img { max-width: 100%; transform:
rotate(-45deg) scale(1.42); z-index: -1; position: relative; }

1
2
3
4
5
6
7
8
9
10
11
12
.picture {
    width: 200px;
    transform: rotate(45deg);
    overflow: hidden;
    margin: 50px;
}
.picture img {
    max-width: 100%;
    transform: rotate(-45deg) scale(1.42);
    z-index: -1;
    position: relative;
}

技术总计:大家愿意图片的尺寸属性保留 100% 那几个值,那样当浏览器不帮衬变
形样式时依然可以拿走一个客观的布局。 „ 通过 scale()
变形样式来缩放图片时,是以它的主导点进展缩放的 (除非大家非凡指定了
transform-origin 样式) 。通过 width 属性
来推广图片时,只会以它的左上角为原点举办缩放,从而迫使我们动用额外的负外边距来把图片的岗位调整回来.

10、切角职能

亚洲必赢官网 11

思路:基于background:linear-gradient()的方案:把三个角都做出切角效果了。你须要四层渐变图案,代码如
下所示:

html:

XHTML

<div class=”example2″>Hey, focus! You’re supposed to be looking at
my corners, not reading my text. The text is just
placeholder!</div>

1
<div class="example2">Hey, focus! You’re supposed to be looking at my corners, not reading my text. The text is just placeholder!</div>

css:

CSS

.example2{ background: #8BC34A; background: linear-gradient(135deg,
transparent 15px, #8BC34A 0) top left, linear-gradient(-135deg,
transparent 15px, #8BC34A 0) top right, linear-gradient(-45deg,
transparent 15px, #8BC34A 0) bottom right, linear-gradient(45deg,
transparent 15px, #8BC34A 0) bottom left; background-size: 50% 50%;
background-repeat: no-repeat; padding: 1em 1.2em; max-width: 12em;
line-height: 1.5em; }

1
2
3
4
5
6
7
8
9
10
11
12
13
.example2{
    background: #8BC34A;
    background: linear-gradient(135deg, transparent 15px, #8BC34A 0) top left,
                linear-gradient(-135deg, transparent 15px, #8BC34A 0) top right,
                linear-gradient(-45deg, transparent 15px, #8BC34A 0) bottom right,
                linear-gradient(45deg, transparent 15px, #8BC34A 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    
    padding: 1em 1.2em;
    max-width: 12em;
    line-height: 1.5em;
}

11、弧形切角

亚洲必赢官网 12

思路:上述渐变技巧还有一个变种,能够用来创制弧形切角(很多个人也把那种
效果称为“内凹圆角” ,因为它看起来就好像圆角的反向版本) 。唯一的区分
在于,大家会用径向渐变来替代上述线性渐变,代码如下:

html:

XHTML

<div class=”example3″>Hey, focus! You’re supposed to be looking at
my corners, not reading my text. The text is just
placeholder!</div>

1
<div class="example3">Hey, focus! You’re supposed to be looking at my corners, not reading my text. The text is just placeholder!</div>

css:

CSS

.example3{ background: #8BC34A; background: radial-gradient(circle at
top left, transparent 15px, #8BC34A 0) top left, radial-gradient(circle
at top right, transparent 15px, #8BC34A 0) top right,
radial-gradient(circle at bottom right, transparent 15px, #8BC34A 0)
bottom right, radial-gradient(circle at bottom left, transparent 15px,
#8BC34A 0) bottom left; background-size: 50% 50%; background-repeat:
no-repeat; padding: 1em 1.2em; max-width: 12em; }

1
2
3
4
5
6
7
8
9
10
11
12
.example3{
    background: #8BC34A;
    background: radial-gradient(circle at top left, transparent 15px, #8BC34A 0) top left,
                radial-gradient(circle at top right, transparent 15px, #8BC34A 0) top right,
                radial-gradient(circle at bottom right, transparent 15px, #8BC34A 0) bottom right,
                radial-gradient(circle at bottom left, transparent 15px, #8BC34A 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    
    padding: 1em 1.2em;
    max-width: 12em;
}

 12、简单的饼图

亚洲必赢官网 13

思路:基于 transform 的解决方案:我们现在得以因此一个 rotate()
变形属性来让那些伪元素转起来。 假如大家要浮现出 20%
的比值,大家可以指定旋转的值为 72deg (0.2 × 360 = 72) ,写成 .2turn
会越发直观一些。你还足以见见其 他有些筋斗值的情况。代码如下:

html:

XHTML

<div class=”pie”></div>

1
<div class="pie"></div>

css:

CSS

.pie{ width:140px; height: 140px; background: #8BC34A; border-radius:
50%; background-image: linear-gradient(to right,transparent 50%,#655
0); } .pie::before{ content: ”; display: block; margin-left: 50%;
height: 100%; border-radius: 0 100% 100% 0 / 50%; background-color:
inherit; transform-origin: left; transform: rotate(.1turn);/*10%*/
transform: rotate(.2turn);/*20%*/ transform: rotate(.3turn);/*30%*/
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.pie{
    width:140px;
    height: 140px;
    background: #8BC34A;
    border-radius: 50%;
    background-image: linear-gradient(to right,transparent 50%,#655 0);
}
.pie::before{
    content: ”;
    display: block;
    margin-left: 50%;
    height: 100%;
    border-radius: 0 100% 100% 0 / 50%;
    background-color: inherit;
    transform-origin: left;
    transform: rotate(.1turn);/*10%*/
    transform: rotate(.2turn);/*20%*/
    transform: rotate(.3turn);/*30%*/
}

提示:在参数中规定角度。turn是圈,1turn = 360deg;其余还有弧度rad,2nrad
= 1turn = 360deg。如,transform:rotate(2turn); //旋转两圈

亚洲必赢官网 14

此办法展现 0 到 50% 的比率时运行卓绝,但要是大家尝试突显 60%
的比率时(比如指定旋转值为 .6turn 时),会合世问题。解决措施:使
用上述技术的一个反向版本来促成那几个界定内的比率:设置一个褐色的伪
元素,让它在 0 至 .5turn 的限量内转悠。由此,要得到一个 60% 比率的饼
图,伪元素的代码可能是那般的:

html:

XHTML

<div class=”pie2″></div>

1
<div class="pie2"></div>

css:

CSS

.pie2{ width:140px; height: 140px; background: #8BC34A; border-radius:
50%; background-image: linear-gradient(to right,transparent 50%,#655
0); } .pie2::before{ content: ”; display: block; margin-left: 50%;
height: 100%; border-radius: 0 100% 100% 0 / 50%; background:
#655;/*当范围大于50%时,要求转移伪元素的背景颜色为#655;*/
transform-origin: left; transform: rotate(.1turn); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.pie2{
    width:140px;
    height: 140px;
    background: #8BC34A;
    border-radius: 50%;
    background-image: linear-gradient(to right,transparent 50%,#655 0);
}
.pie2::before{
    content: ”;
    display: block;
    margin-left: 50%;
    height: 100%;
    border-radius: 0 100% 100% 0 / 50%;
    background: #655;/*当范围大于50%时,需要改变伪元素的背景颜色为#655;*/
    transform-origin: left;
    transform: rotate(.1turn);
}

用 CSS 动画来兑现一个饼图从 0 变化到 100%
的动画片,从而赢得一个炫酷的快慢提醒器:

亚洲必赢官网 15

代码如下:

html:

XHTML

<div class=”pie3″></div>

1
<div class="pie3"></div>

css:

CSS

.pie3 { width:140px; height: 140px; border-radius: 50%; background:
yellowgreen; background-image: linear-gradient(to right, transparent
50%, currentColor 0); color: #655; } .pie3::before { content: ”;
display: block; margin-left: 50%; height: 100%; border-radius: 0 100%
100% 0 / 50%; background-color: inherit; transform-origin: left;
animation: spin 3s linear infinite, bg 6s step-end infinite; }
@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg {
50% { background: currentColor; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.pie3 {
    width:140px;
    height: 140px;
    border-radius: 50%;
    background: yellowgreen;
    background-image: linear-gradient(to right, transparent 50%, currentColor 0);
    color: #655;
}
 
.pie3::before {
    content: ”;
    display: block;
    margin-left: 50%;
    height: 100%;
    border-radius: 0 100% 100% 0 / 50%;
    background-color: inherit;
    transform-origin: left;
    animation: spin 3s linear infinite, bg 6s step-end infinite;
}
 
@keyframes spin {
    to { transform: rotate(.5turn); }
}
@keyframes bg {
    50% { background: currentColor; }
}

1 赞 8 收藏
评论

亚洲必赢官网 16

SVG解决方案

SVG做图形化义务变得不难,饼图自然也是足以的,各类繁复的效用都是可以做出来,那里最紧即使分享部分技艺。

让我们从一个概括的圆开首:

<svg width="100" height="100">
<circle r="30" cx="50" cy="50" />
</svg>

然后给那几个圆附上有的简单的体裁:

circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 30;
}

注:你或许曾经清楚,CSS属性同样适用于SVG元素,考虑到可移植性,那将是会很有益于的。

亚洲必赢官网 17

图九:大家的源点:一个粉红色的SVG圆,填充色为#655

图九显示,SVG
strokes不仅仅包蕴stroke和stroke-width属性。它还蕴藏部分不是很常用的质量来微调strokes。stroke-dasharray就是中间之一。它是为着制造虚的strokes。例如,大家得以如此用:

stroke-dasharray: 20 10;

亚洲必赢官网 18

图十:一个不难的dashed stroke,由stroke-dasharray所创建

上面的CSS代码表示大家要虚实相间的圆(实线部分宽度为20,间隔部分宽度为10)。到现行得了,你恐怕想明白这么些SVG与饼图究竟有啥关系?当我们把实线部分的宽窄设置为0,间隔部分宽度设置为超越或等于圆的周长,这样就变得清楚了。(C
= 2πr, so in our case C = 2π × 30 ≈ 189):

stroke-dasharray: 0 189;

亚洲必赢官网 19

图十一:八个分化stroke-dasharray值的效用图;从左到右依次为:0 189;40
149; 95 189; 150 189;

正如您所看到的,图十一的首先个SVG把具有的stroke部分移除了,大家只可以看到粉色的圆。不过,好玩的是当大家开首逐步增加stroke-dasharray属性的首先个值时,stroke部分逐步回来了。由于间隙(gap)部分太大了,我们无法见到更加多的实线部分笔画(stroke),仅仅唯有一个stroke覆盖在圆上,看起来就像大家所指定的圆的周长的比重。

您或许曾经起来准备去弄驾驭究竟暴发了哪些:倘诺我们减小圆的半径到丰盛小,以至于完全被笔画(stroke)所覆盖,大家最后会得到近似于饼图的事物。例如,图十二,尽管您将半径设置为25,并且将笔触的宽度设置为50会发生什么?下边的代码所表现出来的图片如下:

亚洲必赢官网 20

图十二:我们的SVG逐渐的有点像饼图了

切记:SVG笔触总是一半在所对应的元素内,一半在要素外。将来我们将控制这一行为。

<svg width="100" height="100">
  <circle r="25" cx="50" cy="50" />
</svg>

circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */
}

现在,把它变成一个我们在前头的化解方案中所突显的饼图就变得更简便易行了:大家若是在思绪的下一层画一个大的青色的圆,然后顺时针旋转90°,那样,是她看起来像是从12点钟大势初始。由于<svg>元素也是一个HTML元素,大家一样可以给它写样式:

svg {
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;}

亚洲必赢官网 21

图十三:最终的SVG饼图

您可以看看最后的效能图(图十三)。那种技能驱动饼图从0到100%的卡通片效果尤其简约。我们仅仅必要创建一个CSS动画,使得属性stroke-dasharray的值从0
158到158 158;

@keyframes fillup {
  to { stroke-dasharray: 158 158; }
}

circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 0 158;
  animation: fillup 5s linear infinite;
}

作为额外的改正,大家得以指定圆的半径以使得它的周长为(无限接近于)100,那样我们就能便民的指定stroke-dasharray的长为百分比,而不要求去做额外的测算。由于周长=2πr,所以,半径r=100÷2π≈15.915494309,我们得以大约的认为是16。大家还将在viewBox属性中装置SVG的尺码而不是平素设置它的width和height,以使其适应期容器的轻重缓急。

经过这么些改动,图十三饼图将改为:

<svg viewBox="0 0 32 32">
  <circle r="16" cx="16" cy="16" />
</svg>

svg {
  width: 100px; height: 100px;
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}

circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 32;
  stroke-dasharray: 38 100; /* for 38% */
}

专注到了从未有过?现在设置比例将变得极度简单。当然,即便已经变得那样简约了,大家照样不情愿去重新设置每一个SVG饼图。是时候让JavaScript为大家提供一点点自动化的声援的时候了。大家将写一小段脚本来接管如下的简便的HTML标记:

<div class="pie">20%</div>
<div class="pie">60%</div>

而且在各样.pie元素中添加内联SVG,并顺便所有的不可或缺元素和特性。它还将增进一个<title>元素,以扶植读屏器用户也能领略饼图的比重的值。最后的脚本如下:

$$('.pie').forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  var NS = "http://www.w3.org/2000/svg";
  var svg = document.createElementNS(NS, "svg");
  var circle = document.createElementNS(NS, "circle");
  var title = document.createElementNS(NS, "title");
  circle.setAttribute("r", 16);
  circle.setAttribute("cx", 16);
  circle.setAttribute("cy", 16);
  circle.setAttribute("stroke-dasharray", p + " 100");
  svg.setAttribute("viewBox", "0 0 32 32");
  title.textContent = pie.textContent;
  pie.textContent = '';
  svg.appendChild(title);
  svg.appendChild(circle);
  pie.appendChild(svg);});

那就是SVG的饼图。你恐怕会觉得CSS的主意更好,因为它的代码更简单并且也更少的外来因素。然则,相对于纯CSS来说,SVG的措施也有肯定的亮点:

它极度简单添加第三种颜色:只要加上其余一种思路,并用stroke-dashoffset设置笔触的偏移量。或者,将stroked长度添加到此前的圆的尺寸。你什么可以将第两种颜色添加到第一张解决方案做的饼图里吗?

大家不须要额外担心打印难点,因为SVG元素被认为是内容并打印,如同<img>元素一样。第一种方案取决于背景,由此不会打印。

大家可以透过内联样式来改变颜色,那表示大家可以很方便的经过JavaScript脚本来改变(e.g.,取决于用户输入)。第一张方案依赖于伪元素,除了一连之外,它不帮忙内联样式,这并不总是方便的。

根据变换的化解方案


其一方案从HTML的角度来说是最好的:它只必要一个因素,其他的都能够用伪元素、变换和CSS渐变完毕。大家从下面这么些简单的元素起始:

<div class=”pie”></div>

1
<div class="pie"></div>

现在,假使大家期待突显一个 20% 比例的饼图。灵活性的标题大家前面再解决。我们先给元素添加样式,让它成为一个圆,也就是大家的背景:

亚洲必赢官网 22

图1:第一步是先画一个圆(或者可以说是突显0%百分比的饼图)

CSS

.pie { width: 100px; height: 100px; border-radius: 50%; background:
yellowgreen; }

1
2
3
4
5
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: yellowgreen;
}

 

咱俩的饼图是灰色(特指 yellowgreen )和绿色( #655 )突显的比例。可能会在比例部分尝试选拔transform 中的 skew ,不过透过五次考试之后声明,那是一个非常混乱的方案。因而,大家用那二种颜色为那个饼图的左右部分各自着色,然后对于我们想要的比重,使用旋转的伪元向来贯彻。

俺们运用一个简约的线性渐变,给右半部分着粉红色:

CSS

background-image: linear-gradient(to right, transparent 50%, #655 0);

1
background-image: linear-gradient(to right, transparent 50%, #655 0);

亚洲必赢官网 23

图2:用一个简便的线性渐变给右半圆着黄色

如图2所示,那样就完事了。现在,大家得以持续为伪元素添加样式,让它变成一个蒙版:

CSS

.pie::before { content: ”; display: block; margin-left: 50%; height:
100%; }

1
2
3
4
5
6
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
}

亚洲必赢官网 24

图3:虚线内的情节表示伪元素将用作蒙版的区域

你可以在图3中看出我们的伪元素当前定位相对于大家的pie元素。近来,它还并未添加样式,也不曾遮盖任何事物,只是一个晶莹剔透的矩形。在始发添加样式此前,大家先来分析一下:

  • 因为咱们盼望它覆盖圆的红肉色部分,大家要求给它拔取一个肉色的背景,使用
    background-color: inherit 来防止再度定义,因为我们本来就巴望它和父元素的背景颜色保持一致。
  • 俺们愿意它绕着圆的着力点旋转,中央点在伪元素的左边,所以我们须求给它的
    transform-origin ,应用一个
    0 50% ,或者是一直一个 left 。
  • 我们不想要它是一个矩形,因为它会当先饼图的边缘,所以大家需求给 .pie 应用 overflow: hidden ,或者是一个适用的
    border-radius 让它变成一个半圆。

汇总,伪元素的CSS样式如下:

CSS

.pie::before { content: ”; display: block; margin-left: 50%; height:
100%; border-radius: 0 100% 100% 0 / 50%; background-color: inherit;
transform-origin: left; }

1
2
3
4
5
6
7
8
9
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
}

亚洲必赢官网 25

图4:添加样式之后的伪元素(那里用虚线表示)

留意:不要拔取 class=”crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;”> class=”crayon-pre crayon-code”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;”> class=”crayon-e”>background class=”crayon-sy”>: class=”crayon-i”>inherit class=”crayon-sy”>; ,要用 id=”crayon-5b8f6c8720464547585400″
class=”crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;”> class=”crayon-pre crayon-code”
style=”font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;”> class=”crayon-e”>background-color class=”crayon-sy”>: class=”crayon-i”>inherit ;,否则父元素背景图像上的渐变也会被延续

大家的饼图近日如图4所示。现在上马有趣起来了!我们得以初阶旋转伪元素,给它采纳一个
rotate() 变换。要显示 20% 的百分比,我们得以给它一个 72deg ( 0.2 x 360 = 72 ),或 .2turn ,那几个可读性更好。你可以在图5中看看分化旋转角度值的结果。

亚洲必赢官网 26

图5:分别突显差异比例的饼图,从左到右: 10%  ( 36deg 或 .1turn ), 20%  ( 72deg 或  .2turn ), 40%  ( 144deg  或 .4turn )

您恐怕会想大家已经达成了,但是它可没这么简单。大家的饼图在呈现050%的轻重缓急的内容时是一直不其余难点的,不过一旦大家要描写一个
60% 的团团转(通过使用 .6turn ),就会暴发如图6的情事。然而,别担心,大家可以化解这些事情!

亚洲必赢官网 27

图6:对于超过50%的比例,大家的饼图就跪了orz(那里的是60%)

假如大家把 50%-100% 比例的意况作为独立的一个难题,可能会注意到可以运用此前的缓解方案的反相版本:从0.5turn旋转的红粉红色伪元素。所以,对于一个60%的饼图,伪元素的CSS代码如下:

CSS

.pie::before { content: ”; display: block; margin-left: 50%; height:
100%; border-radius: 0 100% 100% 0 / 50%; background: #655;
transform-origin: left; transform: rotate(.1turn); }

1
2
3
4
5
6
7
8
9
10
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background: #655;
  transform-origin: left;
  transform: rotate(.1turn);
}

亚洲必赢官网 28

图7: 60% 饼图的不利打开格局~

你能够在图7中见到结果。因为大家早已制定了一个方可描绘出任何百分比的主意,大家居然足以为饼图从0%100%添加动画功用,创造出一个妙不可言的进程条:

CSS

@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg {
50% { background: #655; } } .pie::before { content: ”; display: block;
margin-left: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%;
background-color: inherit; transform-origin: left; animation: spin 3s
linear infinite, bg 6s step-end infinite; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@keyframes spin {
  to { transform: rotate(.5turn); }
}
 
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  content: ”;
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 3s linear infinite,
             bg 6s step-end infinite;
}

 

See the Pen zGbNLJ by Airen
(@airen) on CodePen.

展现小意思,可是我们只要给三个例外比重的静态饼图添加样式呢,最广大的用例是?在可以状态下,我们目的在于得以概括地输入如下的内容:

<div class=”pie”>20%</div> <div
class=”pie”>60%</div>

1
2
<div class="pie">20%</div>
<div class="pie">60%</div>

下一场就足以博得三个饼图,一个象征20%,一个意味着60%。首先,我们先商量一下什么样行使内联样式来形成,然后大家可以写一个不难的台本来分析文本内容,对应地加上内联样式,而且要代码优雅、封装、可维护性,还有最首要的一点,可访问性。

行使内联样式控制饼图百分比的一个困难是:用于安装百分比CSS代码是用伪元素已毕的。而且你也晓得,我们不可能给伪元素设置内联样式,所以大家必要创新。

专注:假设您想要使用的值是在某个不必要通过再度的纷纭的盘算的限量内的意况,你可以利用同样的技巧,蕴涵经过它们一步一步调试动画的情事。看该技能的一个简简单单的言传身教。

 

See the Pen YXgNOK by Airen
(@airen) on CodePen.

化解方案来自最不能够的地点之一。大家就要利用大家已经介绍过的动画片,但是它是刹车状态的。大家不会让它像一个正常的动画那样运行,我们将应用负延迟来让它可以静态地暂停在某个点。很奇怪?一个负的animation-delay的值不仅在正规中是同意的,在相近那样的案例中也是更加好用:

负延迟是实用的。和0s的推迟类似,它表示动画将立刻施行,然而是按照延迟的相对化值来自动运行的,所以只要动画已经在指定的时间以前就开首运行了,那它就会一贯从active的时刻中途运行。
—CSS Animations Level
1

因为大家的卡通是刹车的,它的率先帧就是大家唯一显示的那一帧(通过大家的animation-delay概念)。饼图上体现的百分比将会是大家的animation-delay的总时间。例如,当前的持续时间是6s,我们的
animation-delay 值为-1.2s则显示20%的比例。为了简化总括,大家设置一个100s的持续时间。记住因为大家的卡通片是永久暂停的,大家给它指定的推迟大小并不会有哪些震慑。

再有最终一个标题:动画是赋给伪元素的,不过我们想要给.pie要素设置内联样式。因为<div>上并未动画,大家得以给它设置animation-delay用作内联样式,然后给伪元素应用
animation-delay: inherit; 。综上所述,20%60%的饼图的HTML代码如下:

<div class=”pie” style=”animation-delay: -20s”></div>
<div class=”pie” style=”animation-delay: -60s”></div>

1
2
<div class="pie" style="animation-delay: -20s"></div>
<div class="pie" style="animation-delay: -60s"></div>

刚好指出的那几个动画的CSS代码如下(省略 .pie 规则,因为从没改变):

CSS

@keyframes spin { to { transform: rotate(.5turn); } } @keyframes bg {
50% { background: #655; } } .pie::before { /* [Rest of styling stays
the same] */ animation: spin 50s linear infinite, bg 100s step-end
infinite; animation-play-state: paused; animation-delay: inherit; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@keyframes spin {
  to { transform: rotate(.5turn); }
}
 
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  /* [Rest of styling stays the same] */
  animation: spin 50s linear infinite, bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

此刻,可以把HTML标签改成选用比例作为内容,和一起先期待的均等,然后经过一个粗略的本子为其添加
animation-delay 内联样式。

JavaScript

$$(‘.pie’).forEach(function(pie) { var p = parseFloat(pie.textContent);
pie.style.animationDelay = ‘-‘ + p + ‘s’; });

1
2
3
4
$$(‘.pie’).forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  pie.style.animationDelay = ‘-‘ + p + ‘s’;
});

亚洲必赢官网 29

图8:没有隐藏文本前的图

  • 把饼图的height更换成 line-height (或抬高一个和height值卓殊的line-height,不过那值是毫无意义的再次代码,因为line-height会自行测算height的值)。
  • 经过相对定位给伪元素设置大小和岗位,那样它不会把公文挤下去。
  • 累加 text-align: center; 让文本水平居中。

终极的代码如下:

CSS

.pie { position: relative; width: 100px; line-height: 100px;
border-radius: 50%; background: yellowgreen; background-image:
linear-gradient(to right, transparent 50%, #655 0); color: transparent;
text-align: center; } @keyframes spin { to { transform: rotate(.5turn);
} } @keyframes bg { 50% { background: #655; } } .pie::before { content:
”; position: absolute; top: 0; left: 50%; width: 50%; height: 100%;
border-radius: 0 100% 100% 0 / 50%; background-color: inherit;
transform-origin: left; animation: spin 50s linear infinite, bg 100s
step-end infinite; animation-play-state: paused; animation-delay:
inherit; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.pie {
  position: relative;
  width: 100px;
  line-height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image: linear-gradient(to right, transparent 50%, #655 0);
  color: transparent;
  text-align: center;
}
 
@keyframes spin {
  to { transform: rotate(.5turn); }
}
@keyframes bg {
  50% { background: #655; }
}
 
.pie::before {
  content: ”;
  position: absolute;
  top: 0; left: 50%;
  width: 50%; height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: spin 50s linear infinite, bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

 

See the Pen qdvRMv by Airen
(@airen) on CodePen.

The problem

饼图,遍地可知,但是真正去贯彻,仍然要下点功夫的。
比如大家要创制一个速度提醒器,或者计时屏幕,寻常涉及动用外部图像编辑器为饼图的三个值创制图像,或行使js脚本设计更是复杂的图样。

现行有任何更好的情势去落到实处。

前景的饼图

锥形梯度在此地也将十分有协助。饼图所急需的是一个圆形元素,具有四个颜色甘休点的锥形渐变。
例如,图5中的40%饼图将不难如下:

亚洲必赢官网 30

.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: conic-gradient(#655 40%, yellowgreen 0);
}

此外,一旦CSS Values Level
3中定义的换代的attr()函数被广大完结,您将可以使用简便的HTML属性来支配百分比:

background: conic-gradient(#655 attr(data-value %), yellowgreen 0);

那也使得它相当不难添加第两种颜色。
例如,对于像上边上显得的饼图,大家只需添加八个颜色:

background: conic-gradient(deeppink 20%, #fb3 0, #fb3 30%, yellowgreen 0);

锥形梯度在此处也将尤其有救助。

其一饼图就大旨做出来了,大家有题目吧?
同时大家学习可以投入大家的读书群 497187010 一起念书和互换啊
另有上学材料和 学习沟通 解答我们的就学难题

按照SVG的缓解方案


SVG使得广大图纸工作变得越发简便易行,饼图也不例外。不过,用path途径创建饼图,需求复杂的数学总计,我们得以行使一些小技巧来取代。

我们从一个圆开端:

<svg width=”100″ height=”100″> <circle r=”30″ cx=”50″ cy=”50″
/> </svg>

1
2
3
<svg width="100" height="100">
<circle r="30" cx="50" cy="50" />
</svg>

现在,给它使用有的基础的体制:

CSS

circle { fill: yellowgreen; stroke: #655; stroke-width: 30; }

1
2
3
4
5
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 30;
}

专注:你恐怕清楚,那些CSS属性也可以当做SVG元素的性质使用,即使把可移植性考虑在内的话这或者挺方便的。

亚洲必赢官网 31

图9:从一个紫色的SVG圆形,带一个胖胖的#655描边初步

你可以在图9中看出大家绘制的加了描边的圆。SVG描边不止有strokestroke-width属性。还有好多不是专门流行的描边相关的质量可以用于对描边进行微调。其中一个是stroke-dasharray,用于成立虚线描边。例如,大家可以运用如下:

CSS

stroke-dasharray: 20 10;

1
stroke-dasharray: 20 10;

亚洲必赢官网 32

图10:一个简短的虚线描边,通过stroke-dasharray特性创设

那行代码的趣味是大家的虚线是20的长度加上10的边距,如图10所示。在那边,你恐怕会奇怪那些SVG描边属性和饼图究竟有哪些关系呢。假若大家给描边应用一个值为0的虚线宽度,和一个超乎或等于我们脚下圆的周长的边距,它或许就清楚一些了(统计周长:
C = 2πr , 所以在那边  C = 2π × 30 ≈ 189 ):

CSS

stroke-dasharray: 0 189;

1
stroke-dasharray: 0 189;

亚洲必赢官网 33

图11:不同stroke-dasharray值对应的效率;从左到右: 0 189; 40 189; 95 189; 150 189 

如图11中的首个圆所示,它的描边的都被移除了,只剩下一个绿色的圆。可是,当大家起初增大首个值的时候,有趣的事情时有暴发了(图11):因为边距太长,大家就从不虚线描边了,只有一个描边覆盖了大家指定的圆的周长的比例。

您恐怕已经开头弄精晓了那是怎么回事:借使大家把圆的半径减小到早晚水平,它或许就会全盘被它的描边覆盖,最后收获的是一个百般类似于饼图的事物。例如,你可以在图12中看出:当给圆应用一个25的半径和一个50stroke-width,像上面的功效:

亚洲必赢官网 34

图12:我们的SVG图像开首像一个饼图了O(∩_∩)O

切记:SVG描边总是相对于元素边缘一半在内一半在外的(居中的)。未来应当可以控制这一行事。

<svg width=”100″ height=”100″> <circle r=”25″ cx=”50″ cy=”50″
/> </svg> circle { fill: yellowgreen; stroke: #655;
stroke-width: 50; stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */ }

1
2
3
4
5
6
7
8
9
10
<svg width="100" height="100">
  <circle r="25" cx="50" cy="50" />
</svg>
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 60 158; /* 2π × 25 ≈ 158 */
}

当今,把它成为大家在上一个解决方案中制造的饼图的金科玉律是非凡不难的:大家只需求在描边上面添加一个更大的青色圆形,然后逆时针旋转90°,这样它的起源就在顶部中间。因为<svg>要素也是HTML元素,大家得以给它充足样式:

CSS

svg { transform: rotate(-90deg); background: yellowgreen; border-radius:
50%; }

1
2
3
4
5
svg {
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}

亚洲必赢官网 35

图13:最后的SVG饼图

你可以在图13中看出最终结出。那种技术可以让饼图更易于完毕从0%100%转移的卡通片。大家只须要创设一个CSS动画,让stroke-dasharray
0 158 变成 158 158 :

CSS

@keyframes fillup { to { stroke-dasharray: 158 158; } } circle { fill:
yellowgreen; stroke: #655; stroke-width: 50; stroke-dasharray: 0 158;
animation: fillup 5s linear infinite; }

1
2
3
4
5
6
7
8
9
10
11
@keyframes fillup {
  to { stroke-dasharray: 158 158; }
}
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 50;
  stroke-dasharray: 0 158;
  animation: fillup 5s linear infinite;
}

作为一个相当的寻行数墨,大家得以在圆上指定一个特定半径,使其周长无限接近100,那样大家得以用百分比指定stroke-dasharray的长短,而不需要做计算。因为周长是2πr,大家的半径则是100 ÷ 2π ≈ 15.915494309,约等于16。大家还足以用viewBox特色指定SVG的尺码,可以让它自动调整为容器的尺寸,不要拔取widthheight属性。

因此上述调整,图13的饼图的HTML标签如下:

<svg viewBox=”0 0 32 32″> <circle r=”16″ cx=”16″ cy=”16″ />
</svg>

1
2
3
<svg viewBox="0 0 32 32">
  <circle r="16" cx="16" cy="16" />
</svg>

CSS如下:

CSS

svg { width: 100px; height: 100px; transform: rotate(-90deg);
background: yellowgreen; border-radius: 50%; } circle { fill:
yellowgreen; stroke: #655; stroke-width: 32; stroke-dasharray: 38 100;
/* for 38% */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
svg {
  width: 100px; height: 100px;
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}
 
circle {
  fill: yellowgreen;
  stroke: #655;
  stroke-width: 32;
  stroke-dasharray: 38 100; /* for 38% */
}

留意现行比例已经能够很便宜地转移了。当然,纵然已经简化了标签,我们仍旧不想在绘制每个饼图的时候都重新一遍所有那个SVG标签。这是时候拿出JavaScript来帮大家一把了。我们写一个简便的本子,让大家的HTML标签直接省略地那样写:

<div class=”pie”>20%</div> <div
class=”pie”>60%</div>

1
2
<div class="pie">20%</div>
<div class="pie">60%</div>

下一场在每个.pie要素里边添加一个内联SVG,包蕴富有要求的要素和属性。它还会添加一个<title>要素,为了增添可访问性,那样显示屏阅读器用户还足以知晓当前的饼图表示的比重。最后的剧本如下:

JavaScript

$$(‘.pie’).forEach(function(pie) { var p = parseFloat(pie.textContent);
var NS = “”; var svg =
document.createElementNS(NS, “svg”); var circle =
document.createElementNS(NS, “circle”); var title =
document.createElementNS(NS, “title”); circle.setAttribute(“r”, 16);
circle.setAttribute(“cx”, 16); circle.setAttribute(“cy”, 16);
circle.setAttribute(“stroke-dasharray”, p + ” 100″);
svg.setAttribute(“viewBox”, “0 0 32 32″); title.textContent =
pie.textContent; pie.textContent = ”; svg.appendChild(title);
svg.appendChild(circle); pie.appendChild(svg); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$$(‘.pie’).forEach(function(pie) {
  var p = parseFloat(pie.textContent);
  var NS = "http://www.w3.org/2000/svg";
  var svg = document.createElementNS(NS, "svg");
  var circle = document.createElementNS(NS, "circle");
  var title = document.createElementNS(NS, "title");
  circle.setAttribute("r", 16);
  circle.setAttribute("cx", 16);
  circle.setAttribute("cy", 16);
  circle.setAttribute("stroke-dasharray", p + " 100");
  svg.setAttribute("viewBox", "0 0 32 32");
  title.textContent = pie.textContent;
  pie.textContent = ”;
  svg.appendChild(title);
  svg.appendChild(circle);
  pie.appendChild(svg);
});

就是它了!你也许会觉得CSS方法比较好,因为它的代码相比较不难而且更可信赖。可是,SVG方法相比较纯CSS方案或者有早晚的优势的:

  • 可以格外不难地丰盛第三种颜色:只必要加上另一个描边圆,然后利用stroke-dashoffset设置它的描边属性。然后,将它的描边长度添加到下方的圆的描边长度上。如若是后面那么些CSS的方案,你要如何给饼图添加第二种颜色吗?
  • 大家不须要考虑打印的题材,因为SVG元素如同<img>要素一样,被默许为是内容的一部分,打印完全不成难点。第一种方案取决于背景,所以不会被打印。
  • 咱们可以动用内联样式改变颜色,也就是说我们得以由此脚本就直接改动颜色(如,根据用户输入改变颜色)。第一种方案重视于伪元素,除了通过一而再,它从未其他措施可以加上内联样式,那很不便利。

See the Pen oXVBar by Airen
(@airen) on CodePen.

transform solution

先是,大家来画一个圆:

<pre>
.pie {
width: 100 px;
height: 100 px;
border-radius: 50 %;
background: yellowgreen;
}
</pre>

亚洲必赢官网 36

既然如此是饼图,比如双色饼图,就须要另一种颜色来展示速度,再画一个半圆:

能够用渐变来做:

background-image: linear-gradient(to right, transparent 50%, #655 0);

亚洲必赢官网 37

大家还亟需创设一个遮罩层:虚线部分。

<pre>
.pie::before {
content: ”;
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
}
</pre>

始建好了,不过有几点要留心的地点:

  • 因为大家想让那些层盖住灰色的一些,所以大家可以给它加个灰色的背景,也足以用
    <pre>
    background-color: inherit;
    </pre>来幸免再度表明。

  • 旋转的中央点是圆心,大家得以如此申明:
    <pre>
    transform-origin: left;
    //或者
    transform-origin: 0 50%;
    </pre>

  • 咱俩成立遮罩层的目的是盖住褐色的那部分,它需假设个半圆,然而大家今天写的是个矩形,所以为了幸免侧漏,大家用border-radius
    让它也变为半圆:

<pre>
border-radius: 0 100% 100% 0 / 50%;
</pre>

遮罩层也就就绪了,现在给一个旋转角度省视:

<pre>
.pie::before {
content: ”;
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background: #655;
transform-origin: left;
transform: rotate(.1turn);
}
</pre>

亚洲必赢官网 38

旋转36度

最近加点动画让它动起来:

<pre>
@keyframes spin {
to {
transform: rotate(.5turn)
}
}

@keyframes bg {
50% {
background: #655
}
}

.pie::before {
content: ”;
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0/50%;
background-color: inherit;
transform-origin: left;
animation: spin 3s linear infinite,bg 6s step-end infinite
}

</pre>

点击查阅:
http://dabblet.com/gist/722909b9808c14eb7300

现在率先步好了,更进一步,想想,假若大家在html中定义百分数,就能显得相应的比重,那大约是不能够更好了。
如同那样定义:
<pre>
<div class=”pie”>20%</div>
<div class=”pie”>60%</div>
</pre>

亚洲必赢官网 39

就像是那样

一个出示20%,另一个突显60% .

首先,大家摸索能不可能用行内样式,然后用一段脚本去分析。

回头想一想:大家是要控制伪元素的旋转度数来浮现百分比的,那难点来了(挖掘机技术哪家强。。XD),咱们无法直接给伪元素添加行内样式…怎么做吧?

The solution comes from one of the most unlikely places.

咱们刚刚定义了动画片,现在它该停停了。

咱俩将利用animation的delay 来兑现,与健康的运用分化的是,大家将运用负数
让它停在大家定义的任务。很迷惑是还是不是,animation-delay
的参数为负数,这是不符合规范的,可是在好几景况下,它是很有用的,看描述:

“A negative delay is valid. Similar to a delay of 0s, it means that the
ani-mation executes immediately, but is automatically progressed by the
ab-solute value of the delay, as if the animation had started the
specifiedtime in the past, and so it appears to start partway through
its activeduration.”
亚洲必赢官网,— CSS Animations Level 1 (w3.org/TR/css-animations/#animation-delay)

因为动画被定义为pause 的时候,只会显示第一帧。

此时,突显在饼图上的比重就是大家定义的延迟时间占全部动画时间的比例。

例如,大家的卡通片持续时间是6s, 延迟时间是-1.2s, 就会展现 20% ;
为了看起来方便,大家定义整个动画的持续时间为100s。

因为动画是不变的,所以设置多大的延迟是不会有其它影响的。

事例走起:

<pre>
<div class=”pie” style=”animation-delay: -20s”></div>
<div class=”pie” style=”animation-delay: -60s”></div>
</pre>

CSS 规则:
<pre>
@keyframes spin {
to {
transform: rotate(.5turn);
}
}

@keyframes bg {
50% {
background: #655;
}
}

.pie::before {
/* [Rest of styling stays the same] */
animation: spin 50s linear infinite,
bg 100s step-end infinite;
animation-play-state: paused;
animation-delay: inherit;
}
</pre>

<pre>
$$(‘.pie’).forEach(function(pie) {
var p = pie.textContent;
pie.style.animationDelay = ‘-‘ + parseFloat(p) + ‘s’;
});
</pre>

亚洲必赢官网 40

我们明日不想看看这么些比重,怎么做吧?

<pre>
color: transparent;
</pre>

这么字体就看不到了,不过依旧是足以选中和打印的。
别的,大家得以让那一个百分比居中,幸免它被入选时,出现在其余地点。

几点注意的地方:

  • 为了贯彻垂直居中,大家得以:

<pre>
height:100px;
line-height:100px;
</pre>

但是这么的代码是再次的,只写line-height 就好。

Convert height to line-height (or add a line-height equal to the
height, but that’s pointless code duplication, because line- height
would set the computed height to that as well ).

  • 给伪元素 相对定位,幸免字飞出去。
  • text-align:center; 完成程度居中。

最终的代码是这么的:

<pre>

.pie {
opacity: 1;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: yellowgreen;
background-image: linear-gradient(to right ,transparent 50% , #655
0);
}

@keyframes spin {
to {
transform: rotate(.5turn);
}
}

@keyframes bg {
50% {
background: #655;
}
}

.pie::before {
/* [Rest of styling stays the same] */
animation: spin 50s linear infinite,
bg 100s step-end infinite;
animation-play-state: paused;
animation-delay: inherit;
}
</pre>

在线查看:http://scaukk.github.io/css/static\_pie\_chart.html

自然,还足以用svg 完成,篇幅有限,那里就不说了。


题外话:

这是张鑫旭 此前做的 摊鸡蛋饼 动画 XD
http://www.zhangxinxu.com/wordpress/2014/04/css3-pie-loading-waiting-animation/

既然 饼图我都写好了,干脆写点动画,也摊个鸡蛋饼。
原理大致,有趣味的可以看看。
做客地址:

http://scaukk.github.io/css/pie.html


本文内容大体就像此多,欢迎交换,欢迎举报,如有错误,还请校勘,谢谢阅读。

有关资源


  • CSS Transforms
  • CSS Image Values
  • CSS Backgrounds & Borders
  • Scalable Vector Graphics
  • CSS Image Values Level 4

以后的饼图


圆锥形渐变在此间也得以丰盛有援救。它只要求一个圆形元素,以及包涵五个色标的锥形渐变即可做出饼图。例如,图5中表示40%的饼图可以如此成功:

亚洲必赢官网 41

CSS

.pie { width: 100px; height: 100px; border-radius: 50%; background:
conic-gradient(#655 40%, yellowgreen 0); }

1
2
3
4
5
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: conic-gradient(#655 40%, yellowgreen 0);
}

还有,一旦CSS Values Level
3中定义的attr()函数更新后被广泛应用,你就足以用简短的HTML属性来决定百分比了:

CSS

background: conic-gradient(#655 attr(data-value %), yellowgreen 0);

1
background: conic-gradient(#655 attr(data-value %), yellowgreen 0);

要添加第三种颜色也格外简单。例如,对于地方突显的饼图,大家只须要再扩展多个色标:

CSS

background: conic-gradient(deeppink 20%, #fb3 0, #fb3 30%, yellowgreen
0);

1
background: conic-gradient(deeppink 20%, #fb3 0, #fb3 30%, yellowgreen 0);

:多亏了Lea的锥形渐变polyfill,我们后天才方可拔取锥形渐变,在她的SmashingConf演说停止不久事后公布的。那可能就是你未来用CSS来统筹饼图的法门!那里的两种形式您会选用什么哪类,以及为啥这么做?或者您曾经想到了一个全然区其他缓解方案?请在评论中留言~

1 赞 2 收藏
评论

亚洲必赢官网 42

网站地图xml地图