您好stackoverflow社区,
我正在寻找一种解决方案,用d3将节点置于较大的节点中,因为我需要证明图形的某些部分发生在特定区域。
输入是一个JSON对象,如下所示:
{
"nodes": [
{"id": "sourcSink1", "label": "sourcSink1", "compartment": null},
{"id": "process1", "label": "process1", "compartment": null},
{"id": "element1", "label": "element1", "compartment": "compartment1"},
{"id": "compartment1", "label":"compartment1", "compartment": null},
]
"edges": [
{"source": "sourcSink1", "target": "process1", "class": 1},
{"source": "process1", "target": "element1", "class": 2},
]
}
节点“compartment1”应包含“element1”。是否有可能用d3.js来实现这一目标?
我很感谢每一个提示:)
答案 0 :(得分:3)
以下是可以执行的操作的快速示例:https://jsfiddle.net/thatOneGuy/qhL8wztm/1/
首先调整半径。我已经检查了节点是否有子节点:
node.each(function(d) {
if (d.compartment) {
node.filter(function(e) {
if (e.name == d.compartment) {
e.hasChildren = true;
}
})
}
})
然后调整半径。如果它有孩子,那就让它成为其他5:
node.attr("r", function(d) {
if (d.hasChildren) {
return 20;
} else {
return 5;
}
})
现在调整坐标。因此,如果节点有一个隔间,它会移动到名称与该隔间匹配的节点,并相应地设置d.x和d.y:
node.attr("cx", function(d) {
if (d.compartment) {
node.filter(function(e) {
return e.name == d.compartment;
}).each(function(e) {
d.x = e.x
})
}
return d.x;
})
.attr("cy", function(d) {
if (d.compartment) {
node.filter(function(e) {
return e.name == d.compartment;
}).each(function(e) {
d.y = e.y
})
}
return d.y;
});
这并不完美,但它确实有效。显然,它需要一些玩法,例如,将孩子带到容器节点等前面。但是你可以从中得到基础:)
编辑
我还添加了一个课程。如果节点必须位于容器中,请将pointerEvents设置为none。这样做不会影响拖动:
.attr("class", function(d){
if(d.compartment){
return "node noPointers"
} else {
return "node"
}
})
CSS:
.noPointers{
pointer-events:none;
}