【问题标题】:Pure CSS3 or SVG animated Doughnut Chart纯 CSS3 或 SVG 动画圆环图
【发布时间】:2015-06-08 15:01:07
【问题描述】:

我正在寻找一个纯 CSS3 或 SVG 动画圆环图。

  • 需要中间的圆圈填充颜色
  • 要用灰色和蓝色分割的外圈,即:蓝色 80% 完成,灰色剩余 20%。
  • 需要圆圈中间的文字。

我找到了一个例子http://jsfiddle.net/4azpfk3r/

任何人都可以帮助创建/编辑上面的内容吗?到一半了。

<div class="item css">
   <h2>CSS</h2>
    <svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
     <g>
     <title>Layer 1</title>
       <circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#69aff4" fill="none"/>
      </g>
   </svg>
 </div>

谢谢

【问题讨论】:

  • 但是你的问题是什么?

标签: html css svg charts


【解决方案1】:

试试这个,它使用stroke-dasharray 创建长度为 251.2 的笔划,请参阅here 以获取更多参考。 stroke-dashoffset 属性指定到破折号图案的距离以开始破折号see here

<svg width="100%" height="100%" viewbox="0 0 100 100">
    <circle cx="50" cy="50" r="40" fill="tomato"/>
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="grey"/>
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#00CCFF" stroke-dasharray="251.2" stroke-dashoffset="50.3"/>
    <text x="40" y="50" fill="black" font-size="10">Text</text>
</svg>

这里的描边填充了 80%(使用 251.2 - 251.2*80/100 计算,251.2 是使用 2 * 3.14 * 40 计算的圆的周长)。即stroke-dashoffset = perimeter - perimeter * amount / 100 也将stroke-dasharray 设置为perimeterperimeter = 2 * 3.14 * radius.

您可以查看this blog post,轻松了解如何创建圆环图。

看到一个 50% 实心的圆圈

<svg width="100%" height="100%" viewbox="0 0 100 100">
    <circle cx="50" cy="50" r="40" fill="tomato"/>
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="grey"/>
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#00CCFF" stroke-dasharray="251.2" stroke-dashoffset="125.6"/>
    <text x="40" y="50" fill="black" font-size="10">Text</text>
</svg>

多环演示:

<svg width="300px" height="300px" viewbox="0 0 100 100">
    <!-- Center color -->
    <circle cx="50" cy="50" r="40" fill="#eee"/>
    <!-- Default color of ring -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="grey"/>
    
    <!-- Progress -->
    <!-- The amount shown as 'filled' is the amount the ring fills, starting from right center (3 o' clock) -->
    <!-- 100% fill -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#2196f3" stroke-dasharray="251.2" stroke-dashoffset="0"/>
    <!-- 80% fill -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#ff5722" stroke-dasharray="251.2" stroke-dashoffset="50.3"/>
    <!-- 70% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#009688" stroke-dasharray="251.2" stroke-dashoffset="75.36"/>
    <!-- 50% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#9c27b0" stroke-dasharray="251.2" stroke-dashoffset="125.6"/>
    <!-- 40% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#e91e63" stroke-dasharray="251.2" stroke-dashoffset="150.72"/>
    <!-- 20% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#f44336" stroke-dasharray="251.2" stroke-dashoffset="200.96"/>
    <!-- Center Text -->
    <text x="40" y="50" fill="black" font-size="10">Text</text>
</svg>

带动画的演示(未在所有浏览器中测试)

$(".progress").each(function() {
  var dataProgress = $(this).attr("stroke-dashoffset");
  $(this).attr("stroke-dashoffset", "251.2");
  $(this).animate({
    "stroke-dashoffset": dataProgress
  },1500)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<svg width="300px" height="300px" viewbox="0 0 100 100">
        <!-- Center color -->
        <circle cx="50" cy="50" r="40" fill="#eee"/>
        <!-- Default color of ring -->
        <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="white"/>
        
        <!-- Progress -->
        <!-- The amount shown as 'filled' is the amount the ring fills, starting from right center (3 o' clock) -->
        <!-- 100% fill -->
        <circle class="progress" cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#2196f3" stroke-dasharray="251.2" stroke-dashoffset="0"/>
        <!-- 80% fill -->
        <circle class="progress" cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#ff5722" stroke-dasharray="251.2" stroke-dashoffset="50.3"/>
        <!-- 70% filled -->
        <circle class="progress" cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#009688" stroke-dasharray="251.2" stroke-dashoffset="75.36"/>
        <!-- 50% filled -->
        <circle class="progress" cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#9c27b0" stroke-dasharray="251.2" stroke-dashoffset="125.6"/>
        <!-- 40% filled -->
        <circle class="progress" cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#e91e63" stroke-dasharray="251.2" stroke-dashoffset="150.72"/>
        <!-- 20% filled -->
        <circle class="progress" cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#f44336" stroke-dasharray="251.2" stroke-dashoffset="200.96"/>
        <!-- Center Text -->
        <text x="40" y="50" fill="black" font-size="10">Text</text>
    </svg>

使用 jquery 的解决方案:

data-fill=amount 分配给.progress 中的每一个,剩下的工作由jquery 完成

var radius = parseInt($("#radius").attr("r")) // Get the radius of the circle 
var perimeter = 2 * 3.14 * radius;

$(".progress").each(function(){
  var amount = parseFloat($(this).attr("data-fill"));
  var fillAmount = perimeter - perimeter * amount / 100;
  
  $(this).attr({
    "stroke-dasharray":perimeter,
    "stroke-dashoffset":fillAmount
  })
  
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<svg width="300px" height="300px" viewbox="0 0 100 100">
    <!-- Center color -->
    <circle cx="50" cy="50" r="40" fill="#eee" id="radius"/>
    <!-- Default color of ring -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="grey"/>
    
    <!-- Progress -->
    <!-- The amount shown as 'filled' is the amount the ring fills, starting from right center (3 o' clock) -->
    <!-- 100% fill -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#2196f3" data-fill="100" class="progress"/>
    <!-- 80% fill -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#ff5722" data-fill="80" class="progress"/>
    <!-- 70% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#009688" data-fill="70" class="progress"/>
    <!-- 50% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#9c27b0" data-fill="50" class="progress"/>
    <!-- 40% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#e91e63" data-fill="40" class="progress"/>
    <!-- 20% filled -->
    <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="20" stroke="#f44336" data-fill="20" class="progress"/>
    <!-- Center Text -->
    <text x="40" y="50" fill="black" font-size="10">Text</text>
</svg>

【讨论】:

  • 如果您能多解释一下,那就太好了。我想弄清楚stroke-dasharraystroke-dashoffset 到底是如何相互作用和相互影响的。
  • @Sumit 编辑了我的答案
  • @Akshay 对我来说仍然没有意义,为什么选择 stroke-dasharray 到 ="251.2" 为什么选择这个数字。你为什么将 stroke-dashoffset 设置为 80% 也许有某种比率对我来说并不明显,你正在使用?
  • @mibbit 应该解释得更好,如果你仍然不明白我已经更新了我的答案,请随时发表评论,我知道我不擅长解释事情
  • @Aditya 抱歉延迟回复,我不确定您指的是哪个 sn-p,但如果您检查 this fiddle 您会看到灰色部分从顶部顺时针动画到 80%方向。诀窍是将圆旋转-90度,使起点变为顶部。
猜你喜欢
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 2016-08-03
相关资源
最近更新 更多