我一直在制作一个带有发芽光谱的饼图。
我有一个演示工作,但是补间动画正在捕捉,而不是平滑地制作动画。如果有人可以帮助增强它,那就太好了,所以它可以动画而不是拍摄周围的弧线。
我已经对选择器阈值进行了硬编码。弧线似乎没有正确补间 - 似乎是快速的。
var arcGenerator = {
radius: 100,
oldData: "",
init: function(data){
var clone = jQuery.extend(true, {}, data);
this.oldData = this.setData(clone, false);
this.setup(this.setData(data, true));
},
update: function(data){
var clone = jQuery.extend(true, {}, data);
this.animate(this.setData(data, true));
this.oldData = this.setData(clone, false);
},
animate: function(data){
var that = this;
var chart = d3.select(".arcchart");
that.generateArcs(chart, data);
},
setData: function(data, isSorted){
var diameter = 2 * Math.PI * this.radius;
var localData = new Array();
var innerPieSliceTotal = 0;
for (x in data) {
innerPieSliceTotal += data[x].value;
}
var displacement = 0;
var oldBatchLength = 0;
if(isSorted){
data.sort(function(a, b) {
return b.value - a.value;
});
}
$.each(data, function(index, value) {
var riseLevels = value.riselevels;
var machineType = value.label;
var innerPieSliceValue = value.value;
var ratioToWorkWith = innerPieSliceValue/innerPieSliceTotal;
var riseLevelCount = riseLevels.length;
if(oldBatchLength !=undefined){
displacement+=oldBatchLength;
}
var arcBatchLength = (2*ratioToWorkWith)*Math.PI;
var arcPartition = arcBatchLength/riseLevelCount;
$.each(riseLevels, function( ri, value ) {
var startAngle = (ri*arcPartition);
var endAngle = ((ri+1)*arcPartition);
if(index!=0){
startAngle+=displacement;
endAngle+=displacement;
}
riseLevels[ri]["startAngle"] = startAngle;
riseLevels[ri]["endAngle"] = endAngle;
riseLevels[ri]["machineType"] = machineType;
});
oldBatchLength = arcBatchLength;
localData.push(riseLevels);
});
var finalArray = new Array();
$.each(localData, function(index, value) {
$.each(localData[index], function(i, v) {
finalArray.push(v);
});
});
return finalArray;
},
generateArcs: function(chart, data){
var that = this;
//append previous value to it.
$.each(data, function(index, value) {
data[index]["previousEndAngle"] = that.oldData[index].endAngle;
});
var arcpaths = chart.selectAll("path")
.data(data);
arcpaths.enter().append("svg:path")
.attr("class", function(d, i){
return d.machineType;
})
.style("fill", function(d, i){
return d.color;
})
.transition()
.ease("elastic")
.duration(750)
.attrTween("d", arcTween);
arcpaths.transition()
.ease("elastic")
.duration(750)
.attrTween("d",arcTween);
arcpaths.exit().transition()
.ease("bounce")
.duration(750)
.attrTween("d", arcTween)
.remove();
function arcTween(b) {
var i = d3.interpolate({value: b.endAngle-0.1}, b);
return function(t) {
return that.getArc()(i(t));
};
}
},
setup: function(data){
var chart = d3.select("#threshold").append("svg:svg")
.attr("class", "chart")
.attr("width", 420)
.attr("height", 420)
.append("svg:g")
.attr("class", "arcchart")
.attr("transform", "translate(200,200)");
this.generateArcs(chart, data);
},
getArc: function(){
var that = this;
var arc = d3.svg.arc()
.innerRadius(that.radius)
.outerRadius(function(d){
var maxHeight = 100;
var ratio = (d.height/maxHeight * 100)+that.radius;
return ratio;
})
.startAngle(function(d, i){
return d.startAngle;
})
.endAngle(function(d, i){
return d.endAngle;
});
return arc;
}
}
答案 0 :(得分:1)
您的arcTween
函数在错误的值之间进行插值。在这种情况下,您需要的是数据元素与endAngle
到previousEndAngle
(正如您已经在计算)和未修改元素之间的插值。以下代码实现了这一点。
function arcTween(b) {
var prev = JSON.parse(JSON.stringify(b));
prev.endAngle = b.previousEndAngle;
var i = d3.interpolate(prev, b);
return function(t) {
return that.getArc()(i(t));
};
}
完整示例here。