2013-08-12 2 views
2

강제 지시 레이아웃을 사용하여 DAG의 D3.js 시각화를 사용하고 있습니다. 때로는 특정 노드의 색상을 변경하려고합니다. 지금까지, 나는 this를 사용하여 클릭 리스너에서 이런 짓을했는지 :바인딩 된 D3 데이터를 사용하여 DOM 요소의 특성을 변경합니다.

function clickNode(node) { 
    d3.select(this).attr("fill", nodeHighlightColour); 
} 

그러나, 지금은 리스너에 의해을 호출되는 함수에서 노드의 색상을 변경하려면, 대신에 청취자 자체. 별도의 함수가되어야하는 이유는 클릭 한 노드에서 다시 추적하여 일련의 노드를 "강조 표시"하고 싶기 때문에 함수 (tracePath)를 재귀 적으로 호출해야합니다.

수신기에서 tracePath을 호출하면 d3.select(this).attr("fill")을 시도하면 "정의되지 않은 함수"런타임 오류가 발생합니다. 나는 이것이 this이 더 이상 범위에 없기 때문이라고 추측합니다. node 개체는 tracePath으로 전달할 수 있지만 DOM 요소가 아닌 노드 데이터입니다. 바인딩 된 데이터 객체 만 사용하여 DOM 요소를 얻으려면 어떻게해야합니까?

편집 : 나는 펠릭스 클링 내 의견에 썼던 것처럼 , 단순히 tracePaththis를 전달할 수 없습니다. 이것은 첫 번째 노드에서 작동하지만 여전히 함수를 재귀 적으로 호출해야합니다. 여기 내 tracePath 기능은 지금까지입니다이에 대한 답변

// Trace the back from a node - node_el is "this", node is the node data 
function tracePath(node_el, node) { 
    var this_id = node.id; 

    if (node.logic == null) { 
      console.log("Highlighting!"); 
      // Using "this" to change colour 
      d3.select(node_el).attr("fill", nodeHighlightColour); 
    } 
    // Look for edges that point to this node 
    for (var i=0; i<edges.length; i++) { 
      var e = edges[i]; 
      if (e.target == this_id) { 
        var next_node = None; 

        // Get the node at the source of the edge 
        for (var j = 0; j<nodes.length; j++) { 
         if (nodes[j].id == e.source) { 
          next_node = nodes[j]; 
         } 
        } 
        // Recursively trace back from that node 
        if (next_id != None) { 
          // How do I get the DOM element to pass to tracepath? 
          tracePath(???, next_node); 
        } 
      } 
    } 
} 
+0

'this' *는 DOM 요소이므로 'this'를'tracePath'에 전달하면됩니까? –

+0

@FelixKling 오 하하 감사합니다 ... 그 생각을해야합니다. – FrancesKR

+0

@FelixKling 사실 그것은 꽤하지 않습니다 ... 왜냐하면 다른 노드에서'tracePath'를 재귀 적으로 호출해야하기 때문입니다. 관련 에지에서 ID를 가져 와서 노드 데이터를 가져올 수 있지만 여전히 DOM 요소에 대한 액세스가 필요합니다. 내 질문을 편집하겠습니다. 죄송합니다. 잊어 버렸습니다. – FrancesKR

답변

0

감사 펠릭스 클링를! 내가 노드 ID를 사용하여 DOM 요소에 액세스 할 수 있습니다, 그리고

circle = d3.select('#graphics').append("g").selectAll("circle") 
     .data(force.nodes()) 
     .enter().append("svg:circle") 
     .attr("id", function(d) { 
       return d.id; 
     }) 
     .on("click", clickNode) 

: 그가 제안한 것처럼,이 같은 노드 데이터 ID와 동일 각 SVG 원 요소에 id을 추가했다.

// Trace the path back from a node 
function tracePath(node_el, node) { 
    var this_id = node.id; 
    console.log("in tracepath"); 
    if (node.logic == null) { 
      console.log("Highlighting!"); 
      d3.select(node_el).attr("fill", nodeHighlightColour); 
    } 
    console.log("this_id:", this_id); 
    // Look for edges that point to this node 
    for (var i=0; i<edges.length; i++) { 
      var e = edges[i]; 
      if (e.target.id == this_id) { 
        console.log("edge from ", e.source.name); 

        // Recursively trace back from that node 
        var next_el = document.getElementById(e.source.id); 
        tracePath(next_el, e.source); 
      } 
    } 
} 

가 나는 또한 (e는 가장자리 임) e.target 나에게 대상 노드 자체뿐 아니라 ID를 제공 것으로 나타났습니다, 그래서 노드를 검색 할 필요가 없었다 : 여기 내 완료 tracePath 기능입니다.

관련 문제