2017-11-07 1 views
3

이것은 내가 의도 한 것보다 더 복잡하게 들릴 수도 있지만, D3 V3에서 D3 V4로 전환 중입니다. 내 모든 다른 그래프와 차트는 정말 쉽게 옮겨 왔지만,이 특정한 하나의 트리는 모든 종류의 슬픔을 d3.layout.tree에서 변경하고 단순히 .children() 함수를 사용하여 노드/링크를 d3.hierarchy()를 사용하여 새로운 방식으로 이전 방법. 나는 그것을 수많은 튜토리얼에서 본 방식으로 설정했다.D3 V3에서 D3 V4 트리 배열 계층 구조를 잘못 사용하여 재정렬 됨

나는 두 가지 Plunkers를 설정했습니다. 이 사람은 D3 V3에 올바른 배열 순서와 제대로 표시/협력 : https://plnkr.co/edit/qXDWDGzhNIM2tTOoAXRa?p=preview

How the Tree Should Look

Correct Data Order

var tree = d3.layout.tree() 
       .nodeSize([0, 75]) 
       .children(function(d) { 
        return d.subsidiaries; 
       }); 

      var line = d3.svg.line().interpolate('step') 
       .x(function(d) { 
        return d.x; 
       }) 
       .y(function(d) { 
        return d.y - 12; 
       }); 

      // Define 'div' for tooltips 
      var div = d3.select('#tree') 
       // Declare the tooltip div 
       .append('div') 
       // Apply the 'tooltip' class 
       .attr('class', 'tooltip') 
       .style('opacity', 0); 

      var svg = d3.select('#tree').append('svg') 
       .attr('width', width + margin.left + margin.right) 
       .append('g') 
       .attr('transform', `translate(${ margin.left },${ margin.top })`); 

      function lineData(d) { 
       var points = [{ 
        x: d.source.y, 
        y: d.source.x 
       }, { 
        x: d.target.y, 
        y: d.target.x 
       }]; 

       return line(points); 
      } 

      root = treeData; 
      root.x0 = 0; 
      root.y0 = 0; 

      update(root); 

      function update(source) { 
       // Compute the flattened node list. 
       var nodes = tree.nodes(root); 
       console.log(nodes); 

       var height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom); 

       d3.select('svg').transition() 
        .duration(duration) 
        .attr('height', height); 

       d3.select(window.frameElement).transition() 
        .duration(duration) 
        .style('height', `${ height }px`); 

       // Compute the layout. 
       nodes.forEach(function(n, i) { 
        n.x = i * barHeight; 
       }); 

       // Update the nodes. 
       var node = svg.selectAll('g.node') 
        .data(nodes, function(d) { 
         return d.id || (d.id = ++i); 
        }); 

이 두 번째는 D3 V4에, 그것은에 분명하다 배열 순서가 매우 잘못되었음을 알려줍니다. 객체의 대부분은 그들이 있어야 할 곳의 목록을 이동, 그래서 여기에 보이는대로 이상한 COLLIDED 효과를 일으키는 : https://plnkr.co/edit/PGPw92URj24yDMrPenwE?p=preview

How the Tree Looks

Different Data Structure and Object Order

function _drawTree(treeData) { 
      // This solves the maximum call stack issue with d3 layout function 
      const margin = { 
        top: 55, 
        right: 20, 
        bottom: 30, 
        left: 30 
       }, 
       width = 960 - margin.left - margin.right, 
       barHeight = 65, 
       barWidth = width * 0.35, 
       duration = 400, 
       treeMap = d3.tree() 
        .nodeSize([0, 75]); 

      let i = 0, 
       root; 

      var line = d3.line() 
       .x(d => d.x) 
       .y(d => d.y - 12) 
       .curve(d3.curveStep); 

      // Define 'div' for tooltips 
      var div = d3.select('#tree') 
       // Declare the tooltip div 
       .append('div') 
       // Apply the 'tooltip' class 
       .attr('class', 'tooltip') 
       .style('opacity', 0); 

      var svg = d3.select('#tree').append('svg') 
       .attr('width', width + margin.left + margin.right) 
       .append('g') 
       .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

      function lineData(d) { 
       var points = [{ 
        x: d.source.y, 
        y: d.source.x 
       }, { 
        x: d.target.y, 
        y: d.target.x 
       }]; 

       return line(points); 
      } 

      root = d3.hierarchy(treeData, d => { 
       return d.subsidiaries; 
       }); 
      root.x0 = 0; 
      root.y0 = 0; 

      update(root); 

      function update(source) { 
       var tree = treeMap(root); 

       var nodes = tree.descendants(root); 

       console.log(nodes); 

       // Compute the flattened node list. 
       var height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom); 

       d3.select('svg').transition() 
        .duration(duration) 
        .attr('height', height); 

       d3.select(window.frameElement).transition() 
        .duration(duration) 
        .style('height', height + 'px'); 

       // Compute the layout. 
       nodes.forEach((n, i) => { 
        n.x = i * barHeight; 
       }); 

나는했습니다 필요한 변수를 기록했고, 개발자 콘솔을 열어서 볼 수 있습니다.

충분한 정보인지 아닌지 잘 모르겠 으면 더 알려주세요. 도와 주셔서 감사합니다!!!

답변

0

실제로 대답은 실제로 비교적 간단합니다. 각 노드 대신에 forEach를 사용했습니다. 노드를 배치하기 전에. 이것에 대한 해결책은 GitHub Issue입니다.

그들은이 example에 연결하고 올바른 수정은 이것이다 :

나는 액션에서 올바른 코드 내 Plunker를 업데이트 한
// Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67 
var index = -1; 
root.eachBefore(function(n) { 
    n.x = ++index * barHeight; 
    n.y = n.depth * 20; 
}); 

...