2012-03-05 3 views
34

D3을 처음 사용하고 강제 지시 레이아웃의 경계를 설정하는 데 문제가 있습니다. 나는 내가 원했던 것을 모아서 (예제들로부터) 함께 관리 해왔다.하지만 나는 그래프를 포함시켜야한다. 눈금 함수에서 변환/변환은 내 그래프를 올바르게 표시하지만 Math.max/min (주석 코드 참조)과 함께 cx 및 cy를 사용하면 노드가 제대로 포함되어있는 동안 왼쪽 상단 에 고정됩니다 .D3 경계 상자가있는 강제 지시 레이아웃

다음은 내가 가지고있는 것입니다 ... 내가 뭘 잘못하고있는거야 ??

var w=960, h=500, r=8, z = d3.scale.category20(); 

var color = d3.scale.category20(); 

var force = d3.layout.force() 
     .linkDistance(function(d) { return (d.value*180) }) 
     .linkStrength(function(d) { return (1/(1+d.value)) }) 
     .charge(-1000) 
     //.gravity(.08) 
     .size([w, h]); 

var vis = d3.select("#chart").append("svg:svg") 
     .attr("width", w) 
     .attr("height", h) 
     .append("svg:g") 
     .attr("transform", "translate(" + w/4 + "," + h/3 + ")"); 

vis.append("svg:rect") 
    .attr("width", w) 
    .attr("height", h) 
    .style("stroke", "#000"); 


d3.json("miserables.json", function(json) { 

     var link = vis.selectAll("line.link") 
       .data(json.links); 

     link.enter().append("svg:line") 
       .attr("class", "link") 
       .attr("x1", function(d) { return d.source.x; }) 
       .attr("y1", function(d) { return d.source.y; }) 
       .attr("x2", function(d) { return d.source.x; }) 
       .attr("y2", function(d) { return d.source.y; }) 
       .style("stroke-width", function(d) { return (1/(1+d.value))*5 }); 

     var node = vis.selectAll("g.node") 
       .data(json.nodes); 

     var nodeEnter = node.enter().append("svg:g") 
       .attr("class", "node") 
       .on("mouseover", fade(.1)) 
       .on("mouseout", fade(1)) 
       .call(force.drag); 

     nodeEnter.append("svg:circle") 
       .attr("r", r) 
       .style("fill", function(d) { return z(d.group); }) 
       .style("stroke", function(d) { return 
d3.rgb(z(d.group)).darker(); }); 

     nodeEnter.append("svg:text") 
       .attr("text-anchor", "middle") 
       .attr("dy", ".35em") 
       .text(function(d) { return d.name; }); 

     force 
     .nodes(json.nodes) 
     .links(json.links) 
     .on("tick", tick) 
     .start(); 

     function tick() { 

     // This works 
       node.attr("transform", function(d) { return "translate(" + d.x + "," 
+ d.y + ")"; }); 

     // This contains the lines within the boundary, but the nodes are 
stuck in the top left corner 
       //node.attr("cx", function(d) { return d.x = Math.max(r, Math.min(w 
- r, d.x)); }) 
       //  .attr("cy", function(d) { return d.y = Math.max(r, Math.min(h - 
r, d.y)); }); 

     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; }); 
     } 

     var linkedByIndex = {}; 

    json.links.forEach(function(d) { 
     linkedByIndex[d.source.index + "," + d.target.index] = 1; 
    }); 

     function isConnected(a, b) { 
     return linkedByIndex[a.index + "," + b.index] || 
linkedByIndex[b.index + "," + a.index] || a.index == b.index; 
    } 

     function fade(opacity) { 
     return function(d) { 
      node.style("stroke-opacity", function(o) { 
         thisOpacity = isConnected(d, o) ? 1 : opacity; 
         this.setAttribute('fill-opacity', thisOpacity); 
       return thisOpacity; 
         }); 

         link.style("stroke-opacity", opacity).style("stroke-opacity", 
function(o) { 
       return o.source === d || o.target === d ? 1 : opacity; 
       }); 
     }; 
     } 

}); 
+0

일부 매개 변수를 사용하여 다른 사람이 해결 방법을 찾지 못하면 .gravity()를 많이 사용합니다. 그래프가 너무 크면 문제가 발생하지만 그렇지 않은 노드는 정상적으로 포함되어야합니다. –

답변

59

talk on force layoutsbounding box example있다. Verlet 통합 위치를 사용하면 "틱"이벤트 리스너 내에 기하학적 제약 조건 (경계 상자 및 collision detection 등)을 정의 할 수 있습니다. 단순히 제약 조건을 준수하도록 노드를 이동하면 시뮬레이션이 이에 따라 적절하게 적응합니다.

즉, 사용자가 경계 상자 외부로 그래프를 드래그하여 일시적으로 그래프를 복구 할 수 있기 때문에 중력이이 문제를 처리하는 데있어보다 유연한 방법입니다. 그래프의 크기와 표시된 영역의 크기에 따라 그래프를 맞추기 위해 다른 상대 강도의 중력과 충전 (반발)을 시도해야합니다.

+17

.attr ("cy") : 'node.attr ("cx", function (d) {return dx = 'line' 대신에'path'를 쓰면, 경계를 추가 할 필요가 있습니다. ('d' = Math.max (r, Math.min (height-r, dy));}) 'attr ('d', function() {...});'''도 검사하십시오. – Limin

0

주석 처리 된 코드는 사용자 정의에서 svg g (rouping) 요소이며 cx/cy 속성을 작동하지 않는 노드에서 작동합니다. 노드 내부의 circle 요소를 선택하여 이러한 속성을 활성화합니다.

관련 문제