2012-10-20 1 views
21

강제 레이아웃 예제 (http://bl.ocks.org/1153292) 중 하나를 사용하여 웹 사이트에 네트워크를 표시하고 있습니다.기본 데이터가 변경 될 때 D3 강제 레이아웃 요소를 업데이트하는 방법

사용자는 주어진 시간에 볼 링크 유형을 선택할 수 있습니다. 링크 유형 A를보고 링크 유형 B를 추가 한 다음 링크 유형 A를 제거하면 유형 B의 나머지 링크가 A 색상으로 표시됩니다.

이것은 svg 다이어그램에 링크를 추가하기 위해 실행되는 코드입니다. 나는 그것에서 링크를 추가하고 제거함으로써 배열 this.links을 바꿀 것이다. 당신이 볼 수 있듯이 나는 클래스의 속성을 설정하지만, 업데이트되지 않은 -이 링크 A의 유형 남아

var path = svg.append("svg:g") 
    .selectAll("path") 
    .data(this.links) 
    .enter() 
    .append("svg:path") 
    .attr("class", function(d) { return "link " + d.type; }) 
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); 
나는 현재 틱 함수 내에서 클래스의 속성을 업데이트하여이 문제를 해결

그러나이 과정 떨어져 원인을 불필요한 작업.

입력 조작이 존재하는 요소와 새 요소의 병합 된 선택 사항을 리턴한다는 것을 읽었습니다. 따라서 attr 조작이 존재하는 항목을 갱신하고 새 항목을 설정해야합니다.

무엇이 누락 되었습니까?

답변

19

나는 answer in this post

var circle = svg.selectAll("circle") 
    .data(data); 

circle.enter().append("circle") 
    .attr("r", 2.5); 

circle 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }); 

circle.exit().remove(); 

대답은 내가 selectAll.data의 결과가 아니라 APPEND 연산자의 결과에 ATTR 연산자를 호출 할 필요가 있다는 것입니다 발견했습니다.

+1

이도, 나는 이것이 오래된 게시물 인 것을 알고있다. 그러나 나는 너와 똑같은 문제를 겪고 있다고 믿는다. 나는 아직도이 해결책을 이해하지 못한다. 어떻게 작동하는지 설명 할 수 있습니다 - 원래 문제를 어떻게 해결 했습니까? 고맙습니다. – Mars

+3

cx 및 cy의 attr 업데이트가 enter() 컨텍스트 외부에 있기 때문에 솔루션이 작동하므로 매번 발생합니다. 원래 코드에서 attr 함수는 enter() 컨텍스트 내에서 호출되므로 객체 ID에 따라 한 번만 생성됩니다. 나를 위해 무엇이 중요한 기능에 대해 data()의 두 번째 인수로 배우는 것이 었습니다 : http://bost.ocks.org/mike/constancy/ – velotron

4

강제 지정 레이아웃에서 노드를 추가하고 제거하는 예가 http://bl.ocks.org/1095795입니다. 링크와 노드는 별도로 처리해야하며 강제 레이아웃을 다시 시작해야합니다.

function restart() { 
    var link = vis.selectAll("line.link") 
     .data(links, function(d) { return d.source.id + "-" + d.target.id; }); 

    link.enter().insert("svg:line", "g.node") 
     .attr("class", "link"); 

    link.exit().remove(); 

    var node = vis.selectAll("g.node") 
     .data(nodes, function(d) { return d.id;}); 

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

    nodeEnter.append("svg:image") 
     .attr("class", "circle") 
     .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png") 
     .attr("x", "-8px") 
     .attr("y", "-8px") 
     .attr("width", "16px") 
     .attr("height", "16px"); 

    nodeEnter.append("svg:text") 
     .attr("class", "nodetext") 
     .attr("dx", 12) 
     .attr("dy", ".35em") 
     .text(function(d) { return d.id }); 

    node.exit().remove(); 

    force.start(); 
} 
+1

충분하지 않습니다. 나는 링크를 추가하고 제거하고 문제는 그것이 순서대로 없다는 것이다. 링크 배열이 [A1, A2, A3] 인 유형 A의 링크를 보려고하면 유형 B의 링크가 [A1, A2, A3, B1, B2] 인 링크를보고 유형을 보지 않도록 선택합니다. 배열은 [B1, B2]입니다. D3 다음에 2 개의 요소를 남겨두고 3을 제거하도록 선택했으나 현재 A1과 A2에 바인딩되어 있고 B1과 B2에 바인딩해야하기 때문에 두 요소를 업데이트해야합니다. vis.selectAll ("g.Node"). 데이터 (노드)를 저장하고 업데이트하여이 작업을 수행 할 수 있습니다. –

+0

현재하고있는 일과 그 문제점을 보여주는 jsfiddle을 만들면 더 나은 해결책을 찾는데 도움이 될 것입니다. – Bill

관련 문제