我正在尝试创建一个具有动态过渡的可重用饼图作为一项学习任务。我正在研究 Chris Viau 撰写的 d3.js 可重用组件电子书。 我遇到的问题基本上不是更新,而是创建多个饼图。我想知道我是否不了解 d3.dispatch 是如何工作的,或者我是否搞砸了 pie char 应该工作的方式。它创建多个圆圈,而不是使用随机值动态更新单个饼图。
这是我的 jsfiddle。
http://jsfiddle.net/seoulbrother/Upcr5/
谢谢!
js代码如下:
d3.edge = {};
d3.edge.donut = function module() {
var width = 460,
height = 300,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var dispatch = d3.dispatch("customHover");
function graph(_selection) {
_selection.each(function(_data) {
var pie = d3.layout.pie()
.value(function(_data) { return _data; })
.sort(null);
var arc = d3.svg.arc()
.innerRadius(radius - 100)
.outerRadius(radius - 50);
if (!svg){
var svg = d3.select(this).append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
}
var path = svg.selectAll("path")
.data(pie)
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc)
.each(function(d) {this._current = d;} );
path.transition()
.ease("elastic")
.duration(750)
.attrTween("d", arcTween);
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
});
}
d3.rebind(graph, dispatch, "on");
return graph;
}
donut = d3.edge.donut();
var data = [1, 2, 3, 4];
var container = d3.select("#viz").datum(data).call(donut);
function update(_data) {
data = d3.range(~~(Math.random() * 20)).map(function(d, i) {
return ~~(Math.random() * 100);
});
container.datum(data).transition().ease("linear").call(donut);
}
update();
setTimeout( update, 1000);
最佳答案
出现多个 SVG 的主要原因是您没有检查是否已经正确存在一个。您依赖于正在定义的变量 svg
,但只有在检查它是否已定义后才定义它。
更好的方法是选择您要查找的元素并检查该选择是否为空:
var svg = d3.select(this).select("svg > g");
if (svg.empty()){ // etc
此外,除了输入选择之外,您还需要在代码中处理更新和退出选择。完整的 jsfiddle here .
关于具有动态更新的 d3.js 可重用饼图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20227397/