我的目标是:当一个人点击根节点(第0级)时,显示子元素(第1级)。当一个人点击其中一个子节点(第1级)时,它应该显示其子节点(第2级)以及父级和父级的父级(第1级,这是用户点击的内容),但隐藏所有不相关的父级(来自第1级)。
让我用图片解释一下。
Added a new property to each node .all_children
which keeps track of all children. We need this, or something similar since .children
contains the child nodes currently displayed, and ._children
is used by the existing code to determine if a node contains children or not (and sets the style accordingly).
Also added a .hidden
property that helps to determine whether or not the node should be displayed.
These are added after loading the data:
d3.json("flare.json", function(error, flare) {
root = flare;
root.x0 = height / 2;
root.y0 = 0;
function collapse(d) {
if (d.children) {
d.all_children = d.children;
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
d.hidden = true;
}
}
root.all_children = root.children;
root.children.forEach(collapse);
root.children.forEach(function(d) { d.hidden = false; });
root.hidden = false;
update(root);
});
Updated the update
function to reflect the new changes and only draw the nodes that are supposed to be drawn:
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).filter(function(d) { return !d.hidden; }).reverse(),
links = tree.links(nodes);
The nodes
variable is set to only contain nodes that are NOT hidden.
Updated the click
handler to correctly set the state of the nodes in the display:
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
if (d._children) {
d._children.forEach(function(n) { n.hidden = true; });
if (d.parent) {
d.parent.children = d.parent.all_children;
d.parent.children.forEach(function(n) {
n.hidden = false;
});
}
}
} else {
d.children = d._children;
d._children = null;
if (d.children) {
d.children.forEach(function(n) { n.hidden = false; });
if (d.parent) {
d.parent.children = [d,];
d.parent.children.filter(function(n) { return n !== d; }).forEach(function(n) {
n.hidden = true;
});
}
}
}
update(d);
}
The first part of the if
statement is called when we're collapsing a node, in which case, we need to display all of the siblings of the clicked node by setting d.parent.children
to d.parent.all_children
and setting each of those nodes to .hidden = false
. And we need to hide all the children of the clicked node by setting d.children = null
and then setting each node in d._children
to hidden.
The second part of the if
statement is called when we're expanding a node, in which case, we need to hide its siblings (set .hidden
to true
) and update the .children
property of the clicked node's .parent
node so that only the clicked node is listed as a child.
$('selector').siblings()。hide()
来隐藏节点的兄弟节点。 - jwatts1980