5个<>标签快速实现 漂亮的圆形图(饼图)
最终实现的效果
使用SVG能够很快的实现我们的场景
1. 通过SVG画一个圆形
定义svg文档的高宽
创建一个圆形 半径是100,圆点的定位在中心位,轮廓的宽度10px 颜色红色,填充蓝色
- r 圆的半径
- cx 圆点的x坐标
- cy 圆点的y坐标
- stroke-width 轮廓的宽度
- stroke 轮廓的颜色
- fill 填充颜色
<svg width="210px" height="210px">
<circle r="100" cx="105" cy="105" stroke-width="10" stroke="red" fill="blue">
</circle>
</svg>
呈现的效果:
2. 让它漂漂亮亮的
轮廓的颜色定义渐变色,我这里设置 渐变位置 从左上角 往 右下角 渐变 颜色从40%开始 到90%的时候结束
<svg width="230px" height="230px">
<defs>
<linearGradient x1="40%" y1="15%" x2="90%" y2="80%" id="linearGradient">
<stop offset="40%" stop-color='#29CABB' />
<stop offset="90%" stop-color='#EBD178' />
</linearGradient>
</defs>
<circle r="110" cx="115" cy="115" stroke-width="10" fill="transparent" stroke="#23aaff33" />
<circle r="100" cx="115" cy="115" stroke-width="12" fill="transparent" stroke="url(#linearGradient)" />
<text fill="#ffffff" font-size="35" font-family="Verdana" x="58" y="100">
93.8%</text>
<text fill="#ffffff" font-size="32" font-family="Verdana" x="65" y="150">
留存率</text>
</svg>
添加多了一个圆作为底色 衬托主圆的层次感
<linearGradient> 标签必须在<defs>标签内
fill 填充颜色默认黑色,不需要填充颜色? 只能设置成透明
呈现效果
3. 让它跟数据联动起来
现在只成了一个躯壳 我们要丰富下灵魂 让它动起来
这里可以巧妙的利用 stroke-dasharray 来把轮廓改成虚线
假设把虚线长度设置成23 我们看看效果
<svg width="230px" height="230px">
.....
<circle r="100" cx="115" cy="115" stroke-width="12" stroke-dasharray="23" fill="transparent" stroke="url(#linearGradient)" />
.....
那么,我们只需要把虚线的长设置成圆的周长,在利用偏移stroke-dashoffset 就可以实现我们的饼图效果啦
这里计算周长公式就不说了,人尽皆知
<svg width="230px" height="230px">
.....
<circle r="100" cx="115" cy="115" stroke-width="12" stroke-dasharray="628" fill="transparent" stroke="url(#linearGradient)" />
.....
最后我们在根据实际的数据 去生成 偏移值
计算: 偏移值 = 周长 - 周长 * 实际数据 这里得到计算 是38.93
<svg width="230px" height="230px">
.....
<circle r="100" cx="115" cy="115" stroke-width="12" stroke-dasharray="628" stroke-dashoffset="38.93" fill="transparent" stroke="url(#linearGradient)" />
.....
最终代码
<svg width="230px" height="230px">
<defs>
<linearGradient x1="40%" y1="15%" x2="90%" y2="80%" id="linearGradient">
<stop offset="40%" stop-color='#29CABB' />
<stop offset="90%" stop-color='#EBD178' />
</linearGradient>
</defs>
<circle r="110" cx="115" cy="115" stroke-width="10" fill="transparent" stroke="#23aaff33" />
<circle r="100" cx="115" cy="115" stroke-width="12" fill="transparent" stroke="url(#linearGradient)" stroke-dasharray="628" stroke-dashoffset="38.93"/>
<text fill="#ffffff" font-size="35" font-family="Verdana" x="58" y="100">
93.8%</text>
<text fill="#ffffff" font-size="32" font-family="Verdana" x="65" y="150">
留存率</text>
</svg>
到这里我们只用到5个标签 就能实现好看的饼图
当然 一般的实际应用中,希望还是通过js去动态的计算stroke-dashoffset, 还可以添加上过渡效果
最后贴上完整的demo代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>svg-round</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 200px;
background: #020C18;
}
#svgRound {
transition: all 1s;
}
</style>
</head>
<body>
<svg width="230px" height="230px">
<defs>
<linearGradient x1="40%" y1="15%" x2="90%" y2="80%" id="linearGradient">
<stop offset="40%" stop-color='#29CABB' />
<stop offset="90%" stop-color='#EBD178' />
</linearGradient>
</defs>
<circle r="110" cx="115" cy="115" stroke-width="10" fill="transparent" stroke="#23aaff33" />
<circle r="100" cx="115" cy="115" stroke-width="12" fill="transparent" stroke="url(#linearGradient)" id="svgRound" stroke-dasharray="628" stroke-dashoffset="628"/>
<text fill="#ffffff" font-size="35" font-family="Verdana" x="58" y="100">
93.8%</text>
<text fill="#ffffff" font-size="32" font-family="Verdana" x="65" y="150">
留存率</text>
</svg>
<script>
const svgRound = document.querySelector("#svgRound")
setTimeout(() => {
svgRound.style.strokeDashoffset = "30"
}, 1000)
</script>
</body>
</html>