我有一个非常基本的D3 SVG,它基本上由几个弧组成。
无论我使用什么(attr,attrTween和call),我似乎无法通过回调的第一个参数获取数据 - 它总是返回null(我认为它是某种解析错误,即使路径正确呈现?)
我可能会忽略一些基本的东西,因为我对图书馆比较陌生......
var el = $('#graph'),
width = 280,
height = 280,
twoPi = Math.PI * 2,
total = 0;
var arc = d3.svg.arc()
.startAngle(0)
.innerRadius(110)
.outerRadius(130),
svg = d3.select('#graph').append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"),
meter = svg.append('g').attr('class', 'progress');
/* Add Meter Background */
meter.append('path')
.attr('class', 'background')
.attr('d', arc.endAngle(twoPi))
.attr('transform', 'rotate(180)');
/* Add in Icon */
meter.append('text')
.attr('text-anchor', 'middle')
.attr('class', 'fa fa-user')
.attr('y',30)
.text('')
/* Create Meter Progress */
var percentage = 0.4,
foreground = meter.append('path').attr('class', 'foreground')
.attr('transform', 'rotate(180)')
.attr('d', arc.endAngle(twoPi*percentage)),
setAngle = function(transition, newAngle) {
transition.attrTween('d', function(d,v,i) {
console.log(d,v,i)
});
/*transition.attrTween('d', function(d) { console.log(this)
var interpolate = d3.interpolate(d.endAngle, newAngle);
return function(t) { d.endAngle = interpolate(t); return arc(d); };
});*/
};
setTimeout(function() {
percentage = 0.8;
foreground.transition().call(setAngle, percentage*twoPi);
},2000);
这段代码似乎有问题:
transition.attrTween('d', function(d,v,i) {
console.log(d,v,i)
});
返回:
undefined 0 "M7.959941299845452e-15,-130A130,130 0 0,1 76.4120827980215,105.17220926874317L64.65637775217205,88.99186938124421A110,110 0 0,0 6.735334946023075e-15,-110Z"
我尝试使用插值器将i值解析为字符串,因为我似乎无法获取“d”,但是有一个解析错误,返回带有多个NaN的d属性。
这看起来很奇怪,因为它是一个从弧线计算的简单路径
答案 0 :(得分:1)
D3中基本上所有回调的第一个参数(此处为d
)是绑定到您正在操作的DOM元素的数据元素。在您的情况下,没有数据绑定到任何内容,因此d
未定义。
我已更新您的jsfiddle here以设置转换动画,更像饼图示例。要显示的百分比作为基准绑定到路径。然后,您需要做的就是绑定新数据并以与任何饼图示例相同的方式创建补间:
meter.select("path.foreground").datum(percentage)
.transition().delay(2000).duration(750)
.attrTween('d', function(d) {
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc.endAngle(twoPi*interpolate(t))();
};
});