D3 可折叠力布局混淆了孩子和父母
D3 Collapsible Force Layout Mixing up Children and Parents
我正在研究位于jsfiddle上的示例,在这里。
看来我的所有内容都结构正确,因为孩子们与父母正确关联并显示正确的文本。
我遇到的问题如下...
主节点(位于中心)不可折叠。 与此处的示例相比,图形的整体行为有些故障。
折叠节点时颜色不会更改,父节点折叠时显示父节点的子节点。 在各个节点上点击几次后,孩子和父母似乎被切换了。
我的问题是哪一部分代码可能导致这种情况,为什么?
这是我用来生成图表的代码。 数据丢失,但由 jsfiddle 提供。 任何帮助不胜感激,提前感谢。
var width = 960,
height = 500,
root;
var force = d3.layout.force()
.charge(-220)
.size([width, height])
.on("tick", tick);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var link = svg.selectAll(".link");
function update() {
var nodes = flatten(root);
var links = d3.layout.tree().links(nodes);
console.log(nodes);
// Restart the force layout.
force.nodes(nodes)
.links(links)
.linkDistance(55)
.start();
var link = svg.selectAll(".link")
.data(links, function(d) { return d.target.id; });
link.enter().append("line")
.attr("class", "link");
link.exit().remove();
var node = svg.selectAll("g.node")
.data(nodes)
var groups = node.enter().append("g")
.attr("class", "node")
.attr("id", function (d) {
return d.id
})
.on('click', click)
.call(force.drag);
groups.append("circle")
.attr("class","node")
.attr("x", -8)
.attr("y",-8)
.attr("r", function(d) { return d.children ? 4.5 : 10 })
.style("fill", color)
.on("click", click)
.call(force.drag);
groups.append("text")
.attr("dx", 12)
.attr("dy", "0.35em")
.style("font-size", "10px")
.style("color", "#000000")
.style("font-family", "Arial")
.text(function (d) {
console.log(d);
return d.name
});
node.exit().remove();
force.on("tick", function () {
link.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", function (d) {
return d.target.x;
})
.attr("y2", function (d) {
return d.target.y;
});
node.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
}
function tick() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
// Color leaf nodes orange, and packages white or blue.
function color(d) {
return d._children ? "#3182bd" // collapsed package
: d.children ? "#c6dbef" // expanded package
: "#fd8d3c"; // leaf node
}
// Toggle children on click.
function click(d) {
if (!d3.event.defaultPrevented) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update();
}
}
// Returns a list of all nodes under the root.
function flatten(root) {
var nodes = [], i = 0;
function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
好的,这里有两件事。
首先,默认情况下,d3 使用每个基准面的索引作为其 ID(以确定项目何时进入/退出选择)。 这是父/子移动的问题,当索引 X 处的元素被新元素替换时,d3 认为它们是相同的。 您需要提供一个函数来返回 id:
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id; });
其次,您仅在项目进入选择时设置圆圈的填充颜色。 您应该从 enter() 块中提取分配样式的位,以便每次调用 update()
时都会执行它。
node.selectAll('circle').style('fill', color);
我复制并破解了你的小提琴到plunker中,因为jsFiddle对我来说运行得非常慢:http://plnkr.co/edit/7AJlQub6uCGQ3VSvq4pa?p=preview
相关文章:
- 当选择不同的父母时,我如何使条件形式的孩子消失并清除
- 反应.js:同一父母的两个孩子之间的通信
- 在另一个父母的孩子中更改父母
- 如何在鼠标悬停时仅悬停父母李而不是孩子
- 如何使用父母,之前,孩子等
- D3 可折叠力布局混淆了孩子和父母
- jQuery代码:从父级到子级;不是从孩子到父母
- 防止孩子在父母鼠标向上后点击
- 在骨干中使用手动ID绑定是否正确.js孩子到父母
- 如果一个模型在续集中引用自身,如何让所有孩子或父母在多对多关联中
- 试着根据父母的位置来定位孩子
- 如何为父母's的孩子ul
- 得到父母的第n个孩子
- Javascript通过父母ID选择孩子
- 孩子的身高是父母身高的80%(身高未知)
- 如何将一个孩子附加到两个父母
- D3 .js:如何根据孩子和父母的值来调整D3分区表的大小
- 只影响没有父母的孩子
- 我怎么能从孩子那里提到父母呢?
- 在序列的阳光下,如何给孩子和父母一样的颜色