我正试图在D3.js中做这件事,但无法找到办法。
我想要做的是,当一个人点击根节点(级别0)时,它应该显示子元素(级别1)。当一个人点击其中一个子节点(级别1)时,它应该显示其子级(级别2)和父级和父级父级(级别1,这是用户单击的),但隐藏所有不相关的父级(从1级开始。
让我用图片向你解释。
答案 0 :(得分:7)
您可以执行http://bl.ocks.org/benlyall/4fea200ebebb273aa4df
之类的操作我分叉http://bl.ocks.org/mbostock/4339083并进行了一些更改:
为每个节点.all_children
添加了一个新属性,用于跟踪所有子节点。我们需要这个或类似的东西,因为.children
包含当前显示的子节点,并且现有代码使用._children
来确定节点是否包含子节点(并相应地设置样式)。 / p>
还添加了.hidden
属性,以帮助确定是否应显示该节点。
加载数据后添加:
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);
});
更新了update
函数以反映新的更改,并仅绘制应该绘制的节点:
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).filter(function(d) { return !d.hidden; }).reverse(),
links = tree.links(nodes);
nodes
变量设置为仅包含未隐藏的节点。
更新了click
处理程序,以正确设置显示中节点的状态:
// 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);
}
当我们折叠节点时调用if
语句的第一部分,在这种情况下,我们需要通过将d.parent.children
设置为{{来显示所单击节点的所有兄弟节点1}}并将每个节点设置为d.parent.all_children
。我们需要设置.hidden = false
,然后将d.children = null
中的每个节点设置为隐藏,隐藏所点击节点的所有子节点。
我们在扩展节点时会调用d._children
语句的第二部分,在这种情况下,我们需要隐藏其兄弟节点(将if
设置为.hidden
)并更新单击节点的true
节点的.children
属性,以便仅将单击的节点列为子节点。