【css】SVG实现饼图

  • svg
    • viewBox(minX,minY,width,height)
      指定矩形区域,以自适应容器大小。
  • circle
    • (cx,cy)
      圆心坐标
    • r
      圆半径
    • fill
      填充色
    • stroke
      描边
    • stroke-width
      描边宽度。
      fill区域的径向宽度。
      它的宽度分布在两个区域:fill区域内和fill区域外,且各占一半,即(stroke-width)/2
    • dasharray
      以虚线的形式将描边分成多段。
      dasharray:20 10的意思是,每段的宽度是20,段与段之间的间隔是10
  • title
    每个svg都可以提供一个title描述性字符串,该描述只能是纯文本。
    title的内容不会成为svg绘图的一部分,说白了,在界面上看不到。
    通常title元素必须是其父元素的第一个子元素。
<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="50" fill="lightskyblue"></circle>
    </svg>
</body>

在这里插入图片描述

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="50" fill="lightskyblue"></circle>
    </svg>
    <br/><br/>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="50" fill="lightskyblue" stroke="lightseagreen" stroke-width="20"></circle>
    </svg>
</body>

在这里插入图片描述
这里的stroke-width设置为 20
于是海洋绿色的描边在fill区域内占用了10,蓝色圆可视区域因此也变小了;
海洋绿色的描边在fill区域外也占用了10,但由于svg的尺寸就是100*100,所以该尺寸外的区域被截,所以正如我们所见,fill区域外有部分圆弧。
那我们就把圆半径设置得小一点儿,比如30,这样描边区域就不会超出100*100这么个尺寸范围。

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue"></circle>
    </svg>
    <br/><br/>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue" stroke="lightseagreen" stroke-width="20"></circle>
    </svg>
</body>
svg{
    border: 1px solid lightgray;
}

在这里插入图片描述

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="20"
                ></circle>
    </svg><br/><br/>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="20"
                stroke-dasharray="20 10"
                ></circle>
    </svg><br/><br/>
</body>
svg{
    border: 1px solid lightgray;
}

在这里插入图片描述
当前circle的半径r30,要想让描边恰好完全覆盖fill区域,那么描边宽度stroke-width就应该等于30*2=60
stroke-width设置为60后,svg的尺寸100*100容不下,于是扩大svg尺寸至120*120,同时重新设置圆心坐标为(60,60)

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="20"
                ></circle>
    </svg><br/><br/>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="20"
                stroke-dasharray="20 10"
                ></circle>
    </svg><br/><br/>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
        <circle cx="50" cy="50" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="60"
                stroke-dasharray="20 10"
                ></circle>
    </svg><br/><br/>
    <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" >
        <circle cx="60" cy="60" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="60"
                stroke-dasharray="20 10"
                ></circle>
    </svg>
</body>
svg{
    border: 1px solid lightgray;
}

在这里插入图片描述
stroke-dasharray可设置各分段长度和分段间隔,如果分段间隔大于或等于circle周长,那么将有且只有一个分段。

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" >
        <circle cx="60" cy="60" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="60"
                stroke-dasharray="20 189"
                ></circle>
    </svg>
    <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
        <circle cx="60" cy="60" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="60"
                stroke-dasharray="20 189"
                ></circle>
    </svg>
</body>
svg:nth-of-type(2){
    background-color: lightskyblue;
    border-radius: 50%;
}

在这里插入图片描述
将上面的第二个图逆时针旋转90deg,就可以得到我们预期的饼图了。

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
        <circle cx="60" cy="60" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="60"
                stroke-dasharray="20 189"
                ></circle>
    </svg>
    <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
        <circle cx="60" cy="60" r="30" fill="lightskyblue" 
                stroke="lightseagreen" 
                stroke-width="60"
                stroke-dasharray="20 189"
                ></circle>
    </svg>
</body>
svg:nth-of-type(1){
    background-color: lightskyblue;
    border-radius: 50%;
}
svg:nth-of-type(2){
    background-color: lightskyblue;
    border-radius: 50%;
    transform:rotate(-90deg);
}

在这里插入图片描述

<body>
    <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
        <circle cx="60" cy="60" r="30"></circle>
    </svg>
</body>
svg{
    background-color: lightskyblue;
    border-radius: 50%;
    transform:rotate(-90deg);
}
circle{
    fill: lightskyblue;
    stroke: lightseagreen;
    stroke-width: 60;
    stroke-dasharray: 0 189;
    animation: fillup 10s linear infinite;
}
@keyframes fillup{
    to{
        stroke-dasharray:189 189;
    }
}

在这里插入图片描述
如果circle周长是100就好了,这样百分比就好算了。
恩,r=100/(2*3.14),约16

<body>
    <div class="pie">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
            <circle cx="16" cy="16" r="16"></circle>
        </svg>
    </div>
</body>
svg{
    background-color: lightskyblue;
    border-radius: 50%;
    transform:rotate(-90deg);
}
circle{
    fill: lightskyblue;
    stroke: lightseagreen;
    stroke-width: 32;
    stroke-dasharray: 60 100;
}
.pie{
    width: 100px;
    height: 100px;
}

在这里插入图片描述

<body>
    <div class="pie">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
            <title>20%</title>
            <circle cx="16" cy="16" r="16"
                stroke-dasharray="20 100"
            ></circle>
        </svg>
    </div>
    <div class="pie">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
            <title>60%</title>
            <circle cx="16" cy="16" r="16"
                stroke-dasharray="60 100"
            ></circle>
        </svg>
    </div>
</body>
svg{
    background-color: lightskyblue;
    border-radius: 50%;
    transform:rotate(-90deg);
}
circle{
    fill: lightskyblue;
    stroke: lightseagreen;
    stroke-width: 32;
}
.pie{
    width: 100px;
    height: 100px;
}

在这里插入图片描述
用js脚本生成以上内容。

<body>
    <div class="pie">20%</div>
    <div class="pie">60%</div>
    <script>
    document.querySelectorAll(".pie").forEach(function(pie){
        var p = parseFloat(pie.textContent);
        var NS = "http://www.w3.org/2000/svg";
        var svg = document.createElementNS(NS,"svg");
        svg.setAttribute("viewBox","0 0 32 32");

        var title = document.createElementNS(NS,"title");
        title.textContent = pie.textContent;
        pie.textContent = "";
        svg.appendChild(title);

        var circle = document.createElementNS(NS,"circle");
        circle.setAttribute("cx",16);
        circle.setAttribute("cy",16);
        circle.setAttribute("r",16);
        circle.setAttribute("stroke-dasharray",p+" 100");
        svg.appendChild(circle);
        
        pie.appendChild(svg);

    })
    </script>
</body>
 svg{
     background-color: lightskyblue;
     border-radius: 50%;
     transform:rotate(-90deg);
 }
 circle{
     fill: lightskyblue;
     stroke: lightseagreen;
     stroke-width: 32;
 }
 .pie{
     width: 100px;
     height: 100px;
 }

使用stroke-dashoffset制作两种以上颜色的饼图。

<body>
    <div class="pie">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"  >
            <circle cx="16" cy="16" r="16" stroke-dasharray="20 100" fill="lightskyblue" stroke="lightseagreen"></circle>
            <circle cx="16" cy="16" r="16" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="lightgoldenrodyellow"></circle>
        </svg>
    </div>
    <div class="pie">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"  >
            <circle cx="16" cy="16" r="16" stroke-dasharray="20 100" fill="lightskyblue" stroke="lightseagreen"></circle>
            <circle cx="16" cy="16" r="16" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="lightgoldenrodyellow"></circle>
            <circle cx="16" cy="16" r="16" stroke-dasharray="10 100" stroke-dashoffset="-60" fill="transparent" stroke="gold"></circle>
        </svg>
    </div>
    <div class="pie">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"  >
            <circle cx="16" cy="16" r="16" stroke-dasharray="20 100" fill="lightskyblue" stroke="lightseagreen"></circle>
            <circle cx="16" cy="16" r="16" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="lightgoldenrodyellow"></circle>
            <circle cx="16" cy="16" r="16" stroke-dasharray="10 100" stroke-dashoffset="-60" fill="transparent" stroke="gold"></circle>
            <circle cx="16" cy="16" r="16" stroke-dasharray="10 100" stroke-dashoffset="-70" fill="transparent" stroke="orange"></circle>
        </svg>
    </div>
</body>
svg{
    background-color: lightskyblue;
    border-radius: 50%;
    transform:rotate(-90deg);
}
circle{
    stroke-width: 32;
}
.pie{
    width: 100px;
    height: 100px;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值