2017-12-07 3 views
6

노드 유형에 따라 다른 노드 요소를 추가하고 싶습니다. 따라서 노드에는 type이라는 속성이 있습니다. 모든 노드는 종속 하위 요소가있는 g 요소로 구성되어야합니다.d3js를 사용하여 force-directed 그래프에서 특정 노드에 자식 요소 추가하기

D3s filter 기능을 사용하여 이것을 시도했지만 내 코드가 노드마다 한 번만 자식 요소를 추가하지는 않지만 원하는 자식 요소를 여러 번 추가합니다 (노드가있는 것과 같은 양). 그래서 내가 선택과 함께 뭔가 잘못하고있는 것 같아요.

그래프의 노드와 링크가 시간이 지남에 따라 바뀌므로 선택을 먼저 저장하고 노드가 self.nodes에 추가 될 때 나는 draw 함수를 호출합니다 (링크 코드는 생략 할 것입니다). 어떤 작품

self.domNodes = this.svg.append('g').attr('class', 'nodes').selectAll('.node') 

function draw() { 
    self.domNodes = self.domNodes.data(self.nodes, (node) => node.id) 
    self.domNodes.exit().remove() 

    // all nodes 
    self.domNodes.enter() 
     .append('g') 
     .attr('class', (node) => `node ${node.type}`) 
     .merge(self.domNodes) 

    // contributions 
    self.domNodes.filter((d) => d.type === 'contribution') 
     .append('circle') 
     .attr('r', 4) 
     .attr('fill', 'blue') 

    // persons 
    self.domNodes.filter((d) => d.type === 'person') 
     .append('other elements and attributes...') 

    self.simulation.nodes(self.nodes) 
    self.simulation.force('link').links(self.links) 
    self.simulation.alpha(1).restart() 
} 

personcontribution 사이에 차별화 요소가 내가 이런 종류의 위해 특별히 원하는 추가하지만 g 노드 당 하나의 추가하지 않습니다 않습니다,하지만 그것은 사람들의 복수를 (추가 내가 가지고있는 노드의 수)를 각 노드 g에 입력합니다. 그리기 기능을 계속 호출하면 g 요소에 점점 더 많은 원이 추가됩니다.

<svg> 
    <g> 
     <g class="nodes"> 
      <g class="node contribution" transform="translate(466, 442)"> 
       <circle r="4" fill="blue"></circle> 
       <circle r="4" fill="blue"></circle> 
       <circle r="4" fill="blue"></circle> 
      </g> 
      <g class="node contribution" transform="translate(466, 442)"> 
       <circle r="4" fill="blue"></circle> 
       <circle r="4" fill="blue"></circle> 
       <circle r="4" fill="blue"></circle> 
      </g> 
      <g class="node contribution" transform="translate(466, 442)"> 
       <circle r="4" fill="blue"></circle> 
       <circle r="4" fill="blue"></circle> 
       <circle r="4" fill="blue"></circle> 
      </g> 
      <g class="node person" transform="translate(400, 200)"> 
       <someotherthings></someotherthings> 
       <someotherthings></someotherthings> 
      </g> 
      <g class="node person" transform="translate(400, 200)"> 
       <someotherthings></someotherthings> 
       <someotherthings></someotherthings> 
      </g> 
     </g> 
    </g> 
</svg> 

여기서 내가 뭘 잘못하고 있니? 난 단지 circle 및 기타 요소가 노드 당 한 번만 추가되기를 원합니다.

<svg> 
    <g> 
     <g class="nodes"> 
      <g class="node contribution" transform="translate(466, 442)"> 
       <circle r="4" fill="blue"></circle> 
      </g> 
      <g class="node contribution" transform="translate(466, 442)"> 
       <circle r="4" fill="blue"></circle> 
      </g> 
      <g class="node contribution" transform="translate(466, 442)"> 
       <circle r="4" fill="blue"></circle> 
      </g> 
      <g class="node person" transform="translate(400, 200)"> 
       <someotherthings></someotherthings> 
      </g> 
      <g class="node person" transform="translate(400, 200)"> 
       <someotherthings></someotherthings> 
      </g> 
     </g> 
    </g> 
</svg> 

도움을 주시면 감사하겠습니다.

+0

[* "데이터를 기반으로 다른 유형의 SVG 요소를 만드는 방법"* (/ q/39278704)을 보셨습니까? – altocumulus

+0

답변을 게시했습니다.보세요. 작동하지 않는다면, 피들러/플 런커에 복제 된 문제에 대한 링크를 도와주십시오. –

+0

처음으로'draw()'를 호출 할 때 여러 개의 자식 노드가 나타 납니까? 아니면 노드가 나타나기 위해 두 번 이상 호출해야합니까 (처음에는), 아니면 여러 자식 노드가 존재해야합니까? –

답변

2

d3 위키에서 selection.data을 다시 읽은 후에 마침내 작동하게되었습니다.

내 노트를 미리 병합 했으므로 입력 한 내용에 입력 및 업데이트 노드가 포함되었습니다. 내가 지금 한 일은 먼저 입력 노드를 작성한 다음 선택 및 필터를 수행 한 후 나중에 병합합니다.

function draw() { 
    self.domNodes = self.domNodes.data(self.nodes, (node) => node.id) 
    self.domNodes.exit().remove() 

    // all nodes 
    const enterNodes = self.domNodes.enter() 
     .append('g') 
     .attr('class', (node) => `node ${node.type}`) 

    // contributions 
    enterNodes.filter((d) => d.type === 'contribution') 
     .append('circle') 
     .attr('r', 4) 
     .attr('fill', 'blue') 

    // persons 
    enterNodes.filter((d) => d.type === 'person') 
     .append('other elements and attributes...') 

    self.domNodes = self.domNodes.merge(enterNodes) 

    self.simulation.nodes(self.nodes) 
    self.simulation.force('link').links(self.links) 
    self.simulation.alpha(1).restart() 
} 
관련 문제