我已经在d3(v5)中制作了可折叠树形图,其简化版本可以在以下位置找到:https://jsfiddle.net/philipnye/cwj9nkhr/。
每个节点都有一个标签,但是标签仅在有足够空间使其不互相重叠或太靠近SVG边缘的位置显示。在链接的示例中,在第一次加载时,标签仅出现在树图的前两个深度。
requiredSpacing
用于估计需要多少空间,而minSpacing
则检查每个深度的节点之间存在的最小间距。
以下几行放置节点和标签,并具有过渡效果:
var nodeUpdate=nodeEnter.merge(node)
.transition()
.duration(function() {
if (loaded==0) {
return 0;
}
else {
return duration;
}
})
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
nodeUpdate.select("circle")
.attr("r", function(d) {
return radiuses[d.depth];
})
.attr("class", function(d) {
if (d._children) {
return "filled";
} else {
return "unfilled";
}
});
nodeUpdate.select("text")
.style("fill-opacity", function(d) {
if (minSpacing[d.depth]<requiredSpacing[d.depth]*2 || (d.data.position=='left' && Math.ceil(d.x/5)*5-radiuses[d.depth]-requiredSpacing[d.depth]<margin.left) || (d.data.position=='right' && Math.ceil(d.x/5)*5+radiuses[d.depth]+requiredSpacing[d.depth]>width)) {
return 1e-6;
}
else {
return 1;
}
})
.attr("class", function(d) {
if (minSpacing[d.depth]<requiredSpacing[d.depth]*2 || (d.data.position=='left' && Math.ceil(d.x/5)*5-radiuses[d.depth]-requiredSpacing[d.depth]<margin.left) || (d.data.position=='right' && Math.ceil(d.x/5)*5+radiuses[d.depth]+requiredSpacing[d.depth]>width)) {
return "nodeLabel nonselectable";
}
else {
return "nodeLabel";
}
})
我将没有空格显示的标签的不透明度设置为1e-6(以启用过渡),并给它们提供nonselectable
类,这意味着无法选择标签。但是我实际上并没有删除它们-然后我遇到的问题是,在某些情况下,它们与节点重叠,这意味着无法单击节点以展开/折叠该点以下的树。查看比标记为“男性”和“女性”的节点深两到三个级别的节点-只能单击节点的三分之一到一半之间的某个位置。 (请注意,底部层中的节点不可扩展/可折叠,因为它们没有子节点。)
如何最好地删除这些标签,或者至少停止它们以防止您单击节点?
我考虑过的事情:
nonselectable
来删除节点
课,但这不是最有效的方法,我已经
实施它时遇到了一些麻烦font-size
设置为接近零。我试过了
将下面的代码添加到我的nodeUpdate
代码中,但这似乎会导致过渡问题.attr("font-size", function(d) {
if (minSpacing[d.depth]<requiredSpacing[d.depth]*2 || (d.data.position=='left' && Math.ceil(d.x/5)*5-radiuses[d.depth]-requiredSpacing[d.depth]<margin.left) || (d.data.position=='right' && Math.ceil(d.x/5)*5+radiuses[d.depth]+requiredSpacing[d.depth]>width)) {
return '0.1em';
}
})
或者可能有另一种更好的方法来解决这个问题。
我应该怎么做?
答案 0 :(得分:1)
只需为这些标签设置pointer-events: none;
:
.nonselectable {
pointer-events: none;
etc...
}
实际上,由于我看到标签不可点击,因此您可以将pointer-events: none;
设置为其中的全部。
这是更新的JSFidle:https://jsfiddle.net/e3j7ta4y/