[SVG实战]饼图全面解析

之前写过一篇CSS3的饼图全面解析,这次给大家分享一个SVG实现饼图的全面解析。

既然是绘制饼图,那么显然需要绘制圆形。

// 一个简单的圆形,具有一定宽度的描边。
<svg width="100px" height="100px" viewBox="0 0 100 100">
    <circle r="30" cx="50" cy="50" fill="yellowgreen" stroke="#655" stroke-width="30" />
</svg>

描边刚好是从半径30的位置开始左右两边平均各分配15px的宽度,这样整个圆形看起来就像是45px的半径宽度。

于是,如果我们将描边的宽度设置为半径的两倍,那么整个圆都会被描边所覆盖。

接着利用stroke-dasharray这个属性设置描边的点划线的图案范式,也就是指定短划线和缺口的长度。取值是一个数列,使用逗号或空格分开,依次表示短划线的长度,缺口的长度。

// 设置描边宽度为半径的两倍,同时指定stroke-dasharray属性
<svg width="100px" height="100px" viewBox="0 0 100 100">
    <circle r="25" cx="50" cy="50" fill="yellowgreen" stroke="#655" stroke-width="50" stroke-dasharray="20 10"/>
</svg>

此时,如果我们将第二个值(缺口的长度)设置为整个描边的长度,那么第一个值(短划线的长度)就变的有意义了,可以用它来表示百分比。从而实现饼图。

// 圆的半径为25 周长2*PI*R=158 那么stroke-dasharray的第二个值就设置为158
<svg width="100px" height="100px" viewBox="0 0 100 100">
    <circle r="25" cx="50" cy="50" fill="yellowgreen" stroke="#655" stroke-width="50" stroke-dasharray="16 158"/>
</svg>

16/158刚好约等于10%,由实际效果图也能看出来。

但是这里有个小问题,那就是描边都是从0度开始的,怎么将起始点移动到圆的最上方呢?那就是利用变换,也就是rotate旋转。将svg元素的世界坐标轴进行逆时针方向90度旋转即可。

最后给circle这个元素加上一个CSS3动画(当然也可以考虑使用SMIL动画)就可以实现饼图百分比从0到100的动画效果了。

// stroke-dasharray属性的第一个值从0变化到158
<svg width="100px" height="100px" viewBox="0 0 100 100">
    <circle r="25" cx="50" cy="50" fill="yellowgreen" stroke="#655" stroke-width="50" stroke-dasharray="0 158"/>
</svg>
@keyframes fillup{
  to{
     stroke-dasharray: 158 158;
  }
}
svg{
  transform: rotate(-90deg);
  background: yellowgreen;
  border-radius: 50%;
}circle{  animation: fillup 5s linear infinite;}

直接看效果图即可:

@keyframes fillup{
to{
stroke-dasharray: 158 158;
}
}
.pie{
transform: rotate(-90deg);
background: yellowgreen;
border-radius: 50%;
}
.pie-part{
animation: fillup 5s linear infinite;
}

拔高篇

如何给饼图添加第三种颜色呢?

这时候就要派出另外一个stroke系列属性: stroke-dashoffset

stroke-dashoffset这个属性是用来指定stroke-dasharray属性中短划线的偏移量。

先上一个简单的小案例

<svg width="100px" height="100px" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="#123456" stroke="#ccc" stroke-width="0.5"/>
    <line x1="0" y1="50" x2="100" y2="50" stroke="#fff" stroke-width="1" stroke-dasharray="10 5" />
</svg>
<svg width="100px" height="100px" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="#123456" stroke="#ccc" stroke-width="0.5"/>
    <line x1="0" y1="50" x2="100" y2="50" stroke="#fff" stroke-width="1" stroke-dasharray="10 5" stroke-dashoffset="-5" />
</svg>
<svg width="100px" height="100px" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="#123456" stroke="#ccc" stroke-width="0.5"/>
    <line x1="0" y1="50" x2="100" y2="50" stroke="#fff" stroke-width="1" stroke-dasharray="10 5" stroke-dashoffset="5" />
</svg>

效果图如下,可见当stroke-dashoffset设置为负数时,点划线的位置会后移,而设置为正数时,点划线的位置会前移。

那么利用这个特性,我们完全可以在svg中绘制多个圆形,每个圆形根据各自的百分比数设置对应的stroke-dasharray属性的第一个属性值。而将stroke-dashoffset设置为前面已有百分比的数值总和的负数。还需要注意一点的就是后面覆盖的圆必须设置fill=none 其实第一个圆也可以不用设置fill颜色,因为整个画布已经fill了一种颜色。

<svg width="100px" height="100px" viewBox="0 0 100 100">
    <circle r="25" cx="50" cy="50" fill="none" stroke="#f00" stroke-width="50" stroke-dasharray="16 158" />
    <circle r="25" cx="50" cy="50" fill="none" stroke="#0f0" stroke-width="50" stroke-dasharray="48 158" stroke-dashoffset="-16"/>
    <circle r="25" cx="50" cy="50" fill="none" stroke="#00f" stroke-width="50" stroke-dasharray="79 158" stroke-dashoffset="-64"/>
</svg>

总结篇

其实实现饼图效果的方案无非就是CSS3,Canvas,SVG。如果是报表应用,那完全可以用Canvas来实现,而且现成的CanvasJS库也非常多: chart.js, echart.js, c3.js d3.js等等。

而如果是显示饼图动画loading效果,那可以用SVG来简单处理,甚至很容易给饼图添加多种颜色。CSS3实现饼图loading效果则还需要一定的数学计算。当然SVG也有现成的库,也可以用来绘制报表应用。

时间: 2024-10-17 01:22:59

[SVG实战]饼图全面解析的相关文章

【java项目实战】dom4j解析xml文件,连接Oracle数据库

简介 dom4j是由dom4j.org出品的一个开源XML解析包.这句话太官方,我们还是看一下官方给出的解释.如下图: dom4j是一个易于使用的.开源的,用于解析XML,XPath和XSLT等语言的库.它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP等编程标准. 特点 dom4j是一个非常非常优秀的Java XML API,具有性能优异.功能强大和极端易用的特点,同时它也是一个开放源代码的软件.如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,例

SVG实战开发学习(五)——装饰SVG图形

之前介绍过<defs>元素,它允许我们自定义图形元素.在本章中将要使用这个元素来定义SVG图形的色彩渐变.模式填充.剪裁和遮罩,还将介绍如何在svg中使用css样式表. [色彩渐变] svg中有两种色彩渐变:线性渐变和反射渐变.它们的渐变格式都被定义在<defs>元素中,然后在需要的SVG图元中引用它. 线性渐变——是沿着直线方向的色彩渐变过度,使用<linearGradient>元素来定义. 基本属性: id="GradientName":<

用CSS和SVG制作饼图

饼图,即使是最简单的只有两种颜色的形式,用Web技术创建也并不简单,尽管都是一些常见的信息内容,从简单的统计到进度条指标还有计时器.通常是使用外部图像编辑器来分别为多个值创建多个图像来实现,或是使用大型的JavaScript框架来设计更复杂的图表. 尽管这个东西并不像它曾经看起来那么难以实现,但是也没有什么直接并且简单的方法.但是,现在已经有很多更好.更易于维护的方式来实现它. 基于变换的解决方案 这个方案从HTML的角度来说是最好的:它只需要一个元素,其它的都可以用伪元素.变换和CSS渐变完成

Android SVG动画PathView源代码解析与使用教程(API 14)

使用的是一个第三方库android-pathview主要是一个自己定义View--PathView.跟全部自己定义View一样,重写了三个构造方法. 而且终于调用三个參数的构造方法,在里面获取自己定义属性. /** * Default constructor. * * @param context The Context of the application. */ public PathView(Context context) { this(context, null); } /** * D

SVG实战开发学习(二)——基本图形

[1]线段:<line>元素 基本属性:两点确定一条线段,所以线段的基本属性就是它的起止点的坐标. <svg width="300" height="400"> <!--水平线--> <line x1="20" y1="20" x2="70" y2="20"  style="stroke:black"  /> <!

从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析

API 网关 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会多次请求不同的微服务,增加了客户端的复杂性. 存在跨域请求,在一定场景下处理相对复杂. 认证复杂,每个服务都需要独立认证. 难以重构,随着项目的迭代,可能需要重新划分微服务.例如,可能将多个服务合并成一个或者将一个服务拆分成多个.如果客户端直接与微服务通信,那么重构将会很难实施. 某些微

Python网络爬虫实战(二)数据解析

上一篇说完了如何爬取一个网页,以及爬取中可能遇到的几个问题.那么接下来我们就需要对已经爬取下来的网页进行解析,从中提取出我们想要的数据. 根据爬取下来的数据,我们需要写不同的解析方式,最常见的一般都是HTML数据,也就是网页的源码,还有一些可能是Json数据,Json数据是一种轻量级的数据交换格式,相对来说容易解析,它的格式如下. { "name": "中国", "province": [{ "name": "黑龙江

SVG实战开发学习(七)——文字与声音

[文字:<text>元素] 基本属性 x:文字左下角的X坐标,默认测量单位是当前用户坐标系单位,默认值是0. y:文字左下角的Y坐标. [<text>中嵌套<tspan>元素] 通过该元素就可以对同一个<text>元素内的文字位置.样式等属性进行单独或者部分设置,而不用再增加<text>元素. 基本属性: x:逐个定义文字左下角的X绝对坐标."+"号表示这是一个列表值(下同),列表值可以用逗号或者空格进行分割.如果是列表值则表

SVG实战开发学习(三)——路径

[三种基本的绘图指令] 1.移动到当前点( MoveTo )和绘制直线(LineTo) <path d=" M269 112, L217 163, L272 163, M257 149, L299 149, L249 200" fill="#ffffff" stroke="#000000" /> 解析:           指令                     实际绘制动作                    M269 11