javascript - NodeSize를 사용하는 노드 간 D3 트리 레이아웃 분리



tree d3.js (4)

지금은 아래 그림과 같이 겹치기 때문에 사각형 노드를 분리하려고합니다.

나는 D3가 nodeSizeseparation 메서드를 제공한다는 것을 nodeSize 만, 어떤 이유로 그것이 작동하지 않았다.

나는이 블로그 포스트 가이 문제에 관해 이야기하는 것을 발견했다. 그러나 그는 말한다.

size 속성은 노드에 없으므로 크기를 제어하려는 속성이됩니다.

하지만 분명히 nodeSize 메서드가 있기 때문에 단순히 메서드를 잘못 사용하거나 블로그 게시물이 유효하지 않은 것으로 느껴집니다. 내 노드를 직사각형의 크기로 만들고 모양이 서로 겹치지 않도록 간격을두고 싶습니다. 누구든지 제대로 메서드를 사용하는 방법을 알고 있습니까? 이 방법에 대한 문서는 잘 설명되어 있지 않으며 어떤 차이점도 나타나지 않습니다. 또한 사람들이 나무의 노드 크기를 변경하거나 직사각형 객체에 대한 분리가 필요했던 많은 예제를 찾을 수 없었습니다 (순환 패턴과 관련된 몇 가지 예제가 있지만 그 차이는 너무 큽니다 ...)

다음은 관련 코드입니다. 나는 JSFiddle을 준비하려고 노력할 것이다.

var margin = {top: 20, right: 120, bottom: 20, left: 120},
    height = 960 - margin.right - margin.left,
    width = 800 - margin.top - margin.bottom,
    rectW = 70;
    rectH = 30;
    //bbox = NaN,
    maxTextLength = 0;

var i = 0,
    duration = 750,
    root;


//paths from each node drawn initially here
//changed to d.x, d.y
var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.x+rectW/2, d.y+rectH/2];
    //.projection(function(d) { return [d.x+bbox.getBBox().width/2, d.y+bbox.getBBox().height/2]; 
});

var tree = d3.layout.tree()
    .nodeSize([30,70])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2); })
    .size([width, height]);

var svg = d3.select("body")
            .append("svg")
              .attr("height","100%").attr("width","100%")
              .call(d3.behavior.zoom().on("zoom", redraw))
              .append("g")
                .attr("transform", "translate(" + margin.top + "," + margin.left + ")");

Answers

업데이트 05/04/2018 : d3가 훨씬 더 모듈 식이되도록 많이 바뀌 었습니다. 이 답변을 원하는 사람들은 d3 (특히 v3)의 훨씬 오래된 버전을 사용하고있었습니다.

많은 발견은 여전히 cluster.size()cluster.nodeSize() 아래의 d3-hierarchy 패키지와 관련이 있으며이를 사용하기 위해 잠재적으로 예제를 업데이트 할 계획입니다. 역사적인 참고를 위해, 나는 밑바닥을 손대지 않은 채로두고있다.

다음은 jsFiddle입니다. http://jsfiddle.net/augburto/YMa2y/

편집 : 예제를 업데이트하고 Codepen으로 이동하십시오. 이 예제는 여전히 jsFiddle에 있지만 Codepen은 더 멋진 편집기를 갖고있어 쉽게 포크 할 수 있습니다. 또한 그 내용을 줄이면 예제를이 답변에 직접 추가하려고합니다.

http://codepen.io/augbog/pen/LEXZKK

이 대답을 업데이트 중입니다. 나는 친구와 이야기를 나누었고 sizenodeSize size 의 소스를 보았다.

  tree.size = function(x) {
    if (!arguments.length) return nodeSize ? null : size;
    nodeSize = (size = x) == null;
    return tree;
  };

  tree.nodeSize = function(x) {
    if (!arguments.length) return nodeSize ? size : null;
    nodeSize = (size = x) != null;
    return tree;
  };

트리의 size 를 설정하면 나무가 그 너비와 높이를 따라야하도록 고정 크기를 설정합니다. nodeSize 를 설정하면 트리가 동적이어야 트리의 크기가 재설정됩니다.

nodeSize 후에 size 를 지정할 때, 나는 내가 원했던 것을 거의 무시했다.

결론 : nodeSize 를 작동 nodeSize 려면 고정 된 트리 크기를 가질 수 없습니다. 크기를 null 설정합니다. nodeSize 선언하는 경우에는 size 선언하지 마십시오.

편집 : D3.js 실제로 설명서를 업데이트했습니다 . 그것이 이제는 더 명확 해지기 때문에 누구에게나 감사합니다!

nodeSize 속성은 tree.size와 독점적입니다. tree.nodeSize를 설정하면 (자), tree.size가 null로 설정됩니다.

이것은 내 나무가 지금과 같은 것입니다. 또한 확대 / 축소 기능뿐만 아니라 사각형 내부에 텍스트를 가운데에 배치하는 방법을 추가했습니다.


첫째, 전에 게시 한 모든 사람들에게 감사합니다, 순금. 가로로 그려진 나무와 관련된 오프셋 문제로 어려움을 겪고있는 사람들을 위해이 포스트에 추가하고 싶었습니다.

핵심은 가로 트리에서 .size ()에서 .nodeSize ()로 전환하면 루트 노드가 (0,0)에 위치하도록 점프 / 방향이 변경된 것입니다. 그리고 d3.js 문서에 따르면 이것이 사실입니다 ( https://github.com/d3/d3-hierarchy/blob/master/README.md#tree_nodeSize ).

그러나 조정하려면 viewBox 방향을 재조정해야합니다. 말하자면, 당신이 당신의 svg 를 추가 할 때 명시 적으로 .append 를 설정해야합니다. 여기 저를 위해 일한 나의 해커 작은 선이 있습니다 ...

svg = d3.select("#tree").append("svg")
            .attr("width", width + margin.right + margin.left)
            .attr("height", height + 0 + 0)
            .attr("viewBox", "0 "+(-1*(height-margin.top-margin.bottom)/2)+" "+width+" "+height)
            .append("g")
            .attr("transform", "translate("
                  + margin.left + "," + 0 + ")");

나는 내 자신을 파고 할 때까지 받아 들여진 대답을 이해하지 못했고, 그래서 나는 내가 발견 한 것을 나눌 것이라고 생각했다.

.size() 하고 노드가 겹치면 대신 .nodeSize() 사용하십시오.

허용 된 대답에서 설명한 것처럼 .size() 는 트리의 사용 가능한 크기를 설정하므로 사촌 노드와 두 번째 사촌 간의 간격에 따라 서로 겹쳐서 겹칠 수 있습니다. .nodeSize() 를 사용하면 단순히 각 노드가이 많은 공간을 확보해야하므로 중복되지 않을 것이라고 말합니다!

결국 나를 위해 일한 코드는

var nodeWidth = 300;
var nodeHeight = 75;
var horizontalSeparationBetweenNodes = 16;
var verticalSeparationBetweenNodes = 128;

var tree = d3.layout.tree()
    .nodeSize([nodeWidth + horizontalSeparationBetweenNodes, nodeHeight + verticalSeparationBetweenNodes])
    .separation(function(a, b) {
        return a.parent == b.parent ? 1 : 1.25;
    });

horizontalSeparationBetweenNodes 노드와 verticalSeparationBetweenNodes 노드 사이에 노드 가장자리가 서로 닿았습니다. 나는 또한 .separation() 을 추가하여 사촌 노드 사이의 공간을 줄였다. 노드가 꽤 넓고 많은 공간이 낭비되었다.

참고 : 이것은 v3가 아닌 d3 v3 용입니다.






javascript tree d3.js