>

用CSS和SVG制作饼图

- 编辑:至尊游戏网站 -

用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框架来兼顾更复杂的图纸。

即便这一个事物并不像它已经看起来那么难以达成,可是也并未有啥直接并且轻便的艺术。可是,现在早原来就有繁多越来越好、更易于维护的格局来促成它。


据他们说调换的消除方案


本条方案从HTML的角度来讲是最棒的:它只需求多个成分,别的的都能够用伪成分、转变和CSS渐变达成。大家从上边那一个简单的要素初步:

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

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

以往,假使我们期望展现贰个 百分之四十 比例的饼图。灵活性的标题我们前边再消除。大家先给成分增多样式,让它成为叁个圆,也正是大家的背景:

图片 1

图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);

图片 2

图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%;
}

图片 3

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

您能够在图3中看出咱们的伪成分当前定位相对于大家的pie成分。近年来,它还一直不增多样式,也不曾覆盖任何事物,只是二个透明的矩形。在最初增多样式早先,我们先来深入分析一下:

  • 因为大家盼望它覆盖圆的紫水晶色部分,大家要求给它利用二个青白的背景,使用 background-color: inherit 来幸免重新定义,因为我们自然就指望它和父成分的背景颜色保持风流罗曼蒂克致。
  • 笔者们期待它绕着圆的基本点旋转,宗旨点在伪成分的左边手,所以大家需求给它的 transform-origin ,应用二个0 一半 ,大概是平昔一个 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;
}

图片 4

图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() 转变。要出示 百分之三十三 的比重,大家得以给它八个 72deg ( 0.2 x 360 = 72 ),或 .2turn ,那个可读性更加好。你能够在图5中观察不一致旋转角度值的结果。

图片 5

图5:分别展现分化期比较例的饼图,从左到右: 一成  ( 36deg 或 .1turn ), 五分之二  ( 72deg 或  .2turn ), 三分之一  ( 144deg  或 .4turn )

你或然会想大家早已做到了,可是它可没那样简单。大家的饼图在展现050%的分寸的剧情时是未曾经担负何难题的,可是只要大家要描写一个十分六 的旋转(通过接收 .6turn ),就能爆发如图6的场馆。然而,别忧郁,大家能够缓慢解决那些职业!

图片 6

图6:对于大多数的比重,大家的饼图就跪了orz(这里的是五分之一)

若果我们把 十分之五-百分之百 比例的景况作为独立的七个主题材料,可能会注意到勉强接受从前的解决方案的反相版本:从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);
}

图片 7

图7: 三分一 饼图的不错打开药情势~

你能够在图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标签改成接Nabi例作为内容,和意气风发最早期望的后生可畏律,然后经过一个简易的台本为其增加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';
});

图片 8

图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脚本设计更为复杂的图片。

当今有此外越来越好的措施去完毕。

依据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成分的性质使用,假如把可移植性思量在内的话那只怕挺低价的。

图片 9

图9:从贰个浅乌紫的SVG圆形,带一个胖胖的#655描边伊始

你能够在图9中看看大家绘制的加了描边的圆。SVG描边不独有有strokestroke-width本性。还应该有超级多不是特地流行的描边相关的品质可以用于对描边进行微调。此中七个是stroke-dasharray,用于成立虚线描边。举例,大家能够运用如下:

CSS

stroke-dasharray: 20 10;

1
stroke-dasharray: 20 10;

图片 10

图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;

图片 11

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

如图1第11中学的第贰个圆所示,它的描边的都被移除了,只剩余叁个湖蓝的圆。可是,当我们开始增大第七个值的时候,风趣的业务时有产生了(图11):因为边距太长,大家就从不虚线描边了,唯有一个描边覆盖了大家内定的圆的周长的比重。

您可能已经起头弄驾驭了那是怎么回事:假若大家把圆的半径减小到早晚程度,它可能就能够完全被它的描边覆盖,最终收获的是多个老大贴近于饼图的事物。举例,你能够在图12中来看:当给圆应用二个25的半径和二个50stroke-width,像上面包车型客车作用:

图片 12

图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%;
}

图片 13

图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;
}

用作二个十三分的改过,大家能够在圆上钦点一个一定半径,使其周长Infiniti相近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>

图片 14

既然如此是饼图,例如双色饼图,就必要另风流倜傥种颜色来展现速度,再画二个半圆:

能够用渐变来做:

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

图片 15

咱俩还亟需成立贰个遮罩层:虚线部分。

<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>

图片 16

旋转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>

图片 17

就像那样

三个出示百分之四十,另贰个出示四分一 .

首先,我们尝试能或无法用行内样式,然后用生机勃勃段脚本去解析。

回头想意气风发想:大家是要调控伪成分的旋转度数来展现百分比的,那难题来了(发掘机手艺哪家强。。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, 就能够突显 伍分叁 ;
为了看起来方便,大家定义整个动画的持续时间为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>

图片 18

大家不久前不想见到这几个比例,怎么做呢?

<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中表示十分之二的饼图可以这样成功:

图片 19

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 收藏 评论

图片 20

本文由门户名站发布,转载请注明来源:用CSS和SVG制作饼图