[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也有現成的庫,也可以用來繪制報表應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM