我需要制作一个带有三个值的动画的svg饼图,并且找不到代码中的错误。当我删除setTimeout(function(){ circle.setAttribute(“ stroke-dasharray”,p +“ 100”); },10);从JavaScript来看,饼形图看起来不错,但没有动画效果。当我添加那段代码时,它是有动画效果的,但是不会加载所有值,而是逆时针而非顺时针加载。我不知道任何JavaScript,但需要向现有的饼形图中添加两个额外的值,并使用给定的javascript创建了两个额外的圆。在只有一个圆圈的情况下,动画效果很好。我注意到最终结果(动画结束后仍留有粉红色的饼图)来自.pie div 35中的值,但如果我将div留为空白,整个饼图就会消失。
HTML
<div class="widgets">
<div class="left box stats">
<div class="content">
<div class="widget-row">
<div class="stat stat--pie stat--productivity">
<div class="pie">35</div>
</div>
</div>
</div>
</div>
</div>
CSS
.box.stats .stat.stat--pie {
width: 170px;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.box.stats .stat.stat--pie .pie {
position: relative;
height: 170px;
width: 170px;
}
.box.stats .stat.stat--pie .pie > svg {
-webkit-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
width: 170px;
height: 170px;
}
.box.stats .stat.stat--pie .pie > svg circle {
-webkit-transition: all 1.2s ease-out;
-o-transition: all 1.2s ease-out;
transition: all 1.2s ease-out;
}
.box.stats .content .stat.stat--productivity .pie svg {
border-radius: 50%;
}
.box.stats .content .stat.stat--productivity .pie svg circle {
fill: none;
stroke: #283250;
stroke-width: 32;
}
.box.stats .content .stat.stat--productivity .pie svg .circle2 {
fill: none;
stroke: #E8E05A;
stroke-width: 32;
}
.box.stats .content .stat.stat--productivity .pie svg .circle3 {
fill: none;
stroke: #E24264;
stroke-width: 32;
}
JavaScript
function $$(selector, context) {
context = context || document;
var elements = context.querySelectorAll(selector);
return Array.prototype.slice.call(elements);
}
$$('.stat--productivity .pie').forEach(function(pie) {
var p = parseFloat(pie.textContent);
var NS = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(NS, "svg");
var circle = document.createElementNS(NS, "circle");
var circle2 = document.createElementNS(NS, "circle");
var circle3 = document.createElementNS(NS, "circle");
var digit = document.createElement("H1");
var percent = document.createElement("span");
circle.setAttribute("r", 16);
circle.setAttribute("cx", 16);
circle.setAttribute("cy", 16);
circle.setAttribute("stroke-dasharray", "100 100");
setTimeout(function(){
circle.setAttribute("stroke-dasharray", p + " 100");
}, 10);
circle2.classList.add('circle2');
circle2.setAttribute("r", 16);
circle2.setAttribute("cx", 16);
circle2.setAttribute("cy", 16);
circle2.setAttribute("stroke-dasharray", "90 100");
setTimeout(function(){
circle2.setAttribute("stroke-dasharray", p + " 100");
}, 10);
circle3.classList.add('circle3');
circle3.setAttribute("r", 16);
circle3.setAttribute("cx", 16);
circle3.setAttribute("cy", 16);
circle3.setAttribute("stroke-dasharray", "50 100");
setTimeout(function(){
circle3.setAttribute("stroke-dasharray", p + " 100");
}, 10);
svg.setAttribute("viewBox", "0 0 32 32");
digit.textContent = pie.textContent;
percent.textContent = '%';
pie.textContent = '';
pie.appendChild(svg);
svg.appendChild(circle);
svg.appendChild(circle2);
svg.appendChild(circle3);
pie.appendChild(digit);
pie.appendChild(percent);
});
Link to codepen: https://codepen.io/anon/pen/jjRYwR
答案 0 :(得分:0)
以下是顺时针展开的多值图表的工作示例:https://jsfiddle.net/bowkugsq/
原始代码有多个更改,但是我尝试保留尽可能多的内容,以使OP理解更改并将其应用于自己的解决方案。
CSS已使用索引后缀为每个circle
枚举类。还为label
(传说)提供了一组类,以反映饼图的颜色并进行进一步的自定义。如果要添加下一个图表,则需要再添加一个circle
和label
类。
大多数复杂的重构都是针对饼图生成的(如下所述):
$$('.stat--productivity .pie').forEach(function(pie) {
var percents = pie.textContent.split(",");
percents = percents.map(function(pct, idx) {
return {
value: parseFloat(pct),
sum: 0,
idx: idx + 1
}
});
for (var i = 0; i < percents.length; i++) {
var prevSum = (i > 0) ? percents[i - 1].sum : 1;
percents[i].sum = prevSum + percents[i].value;
};
percents.reverse();
var NS = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(NS, "svg");
pie.textContent = ''; //clear div
svg.setAttribute("viewBox", "0 0 32 32");
pie.appendChild(svg);
percents.forEach(function(pct, idx) {
var circle = document.createElementNS(NS, "circle");
circle.classList.add("circle" + pct.idx);
circle.setAttribute("r", 16);
circle.setAttribute("cx", 16);
circle.setAttribute("cy", 16);
circle.setAttribute("stroke-dasharray", "0 100");
setTimeout(function() {
circle.setAttribute("stroke-dasharray", pct.sum + " 100");
});
svg.appendChild(circle);
});
percents.forEach(function(pct, idx) {
var digit = document.createElement("span");
digit.textContent = pct.value + " %";
digit.classList.add("label" + (idx + 1));
pie.appendChild(digit);
});
});
首先,主Pie div现在包含逗号分隔的百分比列表,如下所示:<div class="pie">25,15,60</div>
。它们的总和必须为100%,否则圆圈将无法关闭。最初,文本内容通过逗号分隔为percents
数组,随后转换为具有额外索引和部分和的对象数组;对于给定的样本,它将产生[{value:25,sum:25,idx:1}, {value:15,sum:40,idx:2}, {value:60,sum:100,idx:3}]
。实际上,sum
上调了1%,因为“笔划数组”的范围“ 100 100”导致微小的插槽未闭合整个圆。反转这样的对象阵列以使动画片段彼此不重叠。接下来的circle
元素将按照原始OP代码中的每个百分比创建。最后,处理percent
数组以添加带有原始值标签的span
。
免责声明:代码的结构可以更好,但是与原始方法的相似之处是主要驱动力。
答案 1 :(得分:-1)
如果您想学习新知识并提高编码技能,可以自己尝试编码,但是如果出于任何其他原因需要此编码,我建议您不要尝试重新设计Weeel,而是使用“准备就绪”的方法。 -使用'
看看这个:PieGraph