过去两周我一直坚持这一点。我一直在浏览有关更新包布局和类似物的所有StackOverflow问题,并且我阅读了关于它和更新模式的d3js文档,但是它们都没有解决这个问题而且我真的无法在没有包装布局的情况下添加新元素重绘一切。
演示:http://jsfiddle.net/v74qp3a7/1/
var diameter = 300;
// The layout I'm using now
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.value(function(d) { return 1 });
// The basic container
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(2,2)");
// My initial data source
var data = {
name: "Languages",
children: [{
name: "Functional",
children: [
{ name: "OCaml" },
{ name: "Haskell" },
{ name: "Erlang" }
]
}, {
name: "Imperative",
children: [
{ name: "BASIC" },
{ name: "Clipper" }
]
}]
};
// The node basis
var node = svg.datum(data).selectAll(".node")
.data(pack.nodes)
.enter().append("circle")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
.attr("r", function(d) {
return d.r;
});
function addToRoot(obj) {
// Modify the current data object
data.children.push(obj);
// I try to modify by entering the node and applying a transition
svg.datum(data).selectAll(".node")
.data(pack.nodes)
.enter().append("circle")
.transition()
.duration(500)
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
.attr("r", function(d) {
return d.r;
});
}
d3.select(self.frameElement).style("height", diameter + "px");
我读过有关enter
和exit
的内容,但我没有弄清楚如何更新 数据对象(而不是数据)属性,非常简单)。我一直在尝试使用这三种更新模式而没有结果。
如何在调用addToRoot({ name: "foo" })
时添加简单元素并更新图形界面而不重绘所有内容?
答案 0 :(得分:1)
首先,您的选择器依赖于您从未分配给相关圈子的班级。因此,您的选择将始终为空,只需再次添加所有内容即可。其次,您还需要处理更新选择,而不仅仅是输入选择。
var sel = svg.datum(data).selectAll(".node")
.data(pack.nodes);
sel.enter().append("circle")
.classed("node", true);
sel
.transition()
.duration(500)
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
.attr("r", function(d) {
return d.r;
});
完整演示here。