• [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;
    }

    直接看效果图即可:

    拔高篇

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

    这时候就要派出另外一个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也有现成的库,也可以用来绘制报表应用。

  • 相关阅读:
    layer满屏/禁止最大化最小化 可以做选择框使用
    layer关闭弹窗
    导出excel
    linux中安装软件的集中方法
    nginx负载均衡
    zookeeper部署搭建
    git 分支合并处理
    前端框架
    云计算基本概念
    Android 单元测试四大组件Activity,Service,Content Provider , Broadcast Receiver
  • 原文地址:https://www.cnblogs.com/joyjoe/p/7257922.html
Copyright © 2020-2023  润新知