D3 Force Directed Layout에서 노드 위치 수정
내 힘 지향 레이아웃의 일부 노드가 모든 힘을 무시하고 노드의 속성에 따라 고정 된 위치에 머무르면서 다른 노드에 대해 끌고 반발력을 발휘하고 링크 라인을 유지할 수 있기를 바랍니다.
다음과 같이 간단 할 것이라고 생각했습니다.
force.on("tick", function() {
vis.selectAll("g.node")
.attr("transform", function(d) {
return (d.someAttribute == true) ?
"translate(" + d.xcoordFromAttribute + "," + d.ycoordFromAttribute +")" :
"translate(" + d.x + "," + d.y + ")"
});
});
또한 각 틱마다 노드의 x 및 y 속성을 수동으로 설정하려고 시도했지만 힘의 영향을받는 경우 링크가 노드가있는 위치로 계속 떠 다닙니다.
분명히 이것이 어떻게 작동 해야하는지에 대한 기본적인 오해가 있습니다. 링크를 유지하면서 드래그 할 수 있도록 허용하면서 위치에서 노드를 수정하려면 어떻게해야합니까?
설정 d.fixedtrue로 원하는 노드에서, 초기화 d.x및 d.y원하는 위치로. 이러한 노드는 여전히 시뮬레이션의 일부가되며 일반 디스플레이 코드를 사용할 수 있습니다 (예 : 변환 속성 설정). 그러나 고정 된 것으로 표시되어 있기 때문에 시뮬레이션이 아닌 드래그로만 이동할 수 있습니다.
자세한 내용은 강제 레이아웃 문서 ( v3 문서 , 현재 문서 )를 참조 하고이 예제 에서 루트 노드의 위치를 확인 하십시오 .
d3v4 및 d4v5에 대한 강제 레이아웃의 고정 노드
d3v3 d.fixed에서 d.x및 노드를 수정합니다 d.y. 그러나 d3v4 / 5에서는이 방법이 더 이상 지원되지 않습니다. D3 문서 상태 :
주어진 위치에서 노드를 수정하려면 두 가지 추가 속성을 지정할 수 있습니다.
fx - the node’s fixed x-position
fy - the node’s fixed y-position각 틱이 끝날 때 힘을 적용한 후 node.fx가 정의 된 노드는 node.x를이 값으로 재설정하고 node.vx를 0으로 설정합니다. 마찬가지로 node.fy가 정의 된 노드는 node.y를이 값으로 재설정하고 node.vy를 0으로 설정합니다. 이전에 수정 된 노드를 수정 해제하려면 node.fx 및 node.fy를 null로 설정하거나 이러한 속성을 삭제합니다.
데이터 소스에서 강제 노드에 대한 fx및 fy속성을 설정 하거나 동적으로 fx및 fy값을 추가 및 제거 할 수 있습니다 . 아래 스 니펫은 드래그 이벤트가 끝날 때 이러한 속성을 설정합니다. 노드를 드래그하여 위치를 고정하면됩니다.
var data ={
"nodes":
[{"id": "A"},{"id": "B"},{"id": "C"},{"id":"D"}],
"links":
[{"source": "A", "target": "B"},
{"source": "B", "target": "C"},
{"source": "C", "target": "A"},
{"source": "D", "target": "A"}]
}
var height = 250;
var width = 400;
var svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }).distance(50))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g")
.selectAll("line")
.data(data.links)
.enter().append("line")
.attr("stroke","black");
var node = svg.append("g")
.selectAll("circle")
.data(data.nodes)
.enter().append("circle")
.attr("r", 5)
.call(d3.drag()
.on("drag", dragged)
.on("end", dragended));
simulation
.nodes(data.nodes)
.on("tick", ticked)
.alphaDecay(0);
simulation.force("link")
.links(data.links);
function ticked() {
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>
참고 URL : https://stackoverflow.com/questions/10392505/fix-node-position-in-d3-force-directed-layout
'program story' 카테고리의 다른 글
| Naive Bayes 분류기의 정확도를 향상시키는 방법은 무엇입니까? (0) | 2020.11.18 |
|---|---|
| 파이썬에서 파일 이름을 가져 오는 방법은 숫자로 시작합니다. (0) | 2020.11.18 |
| Chrome에서 웹 검사기를 어떻게 검사합니까? (0) | 2020.11.18 |
| System.Object를 C #에서`bool`로 안전하게 캐스팅하려면 어떻게해야합니까? (0) | 2020.11.17 |
| Android NDK 코드에 로그인하는 간단한 방법이 있습니까? (0) | 2020.11.17 |