노드에서 모든 자식 요소를 제거한 다음 다른 색상과 크기로 다시 적용하려면 어떻게해야합니까?


87

그래서 노드, 링크 및 기타 요소를 설정하기위한 다음 강제 레이아웃 그래프 코드가 있습니다.

var setLinks = function ()
{
    link = visualRoot.selectAll("line.link")
        .data(graphData.links)
        .enter().append("svg:line")
        .attr("class", "link")
        .style("stroke-width", function (d) { return nodeStrokeColorDefault; })
        .style("stroke", function (d) { return fill(d); })
        .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; });

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


var setNodes = function ()
{
    node = visualRoot.selectAll(".node")
        .data(graphData.nodes)
        .enter().append("g")
        .attr("id", function (d) { return d.id; })
        .attr("title", function (d) { return d.name; })
        .attr("class", "node")
        .on("click", function (d, i) { loadAdditionalData(d.userID, this); })
        .call(force.drag)
        .on("mouseover", fadeNode(.1)).on("mouseout", fadeNode(1));
};

//append the visual element to the node
var appendVisualElementsToNodes = function ()
{
    node.append("circle")
        .attr("id", function (d) { return "circleid_" + d.id; })
        .attr("class", "circle")
        .attr("cx", function (d) { return 0; })
        .attr("cy", function (d) { return 0; })
        .attr("r", function (d) { return getNodeSize(d); })
        .style("fill", function (d) { return getNodeColor(d); })
        .style("stroke", function (d) { return nodeStrokeColorDefault; })
        .style("stroke-width", function (d) { return nodeStrokeWidthDefault; });

    //context menu:
    d3.selectAll(".circle").on("contextmenu", function (data, index)
    {
        d3.select('#my_custom_menu')
          .style('position', 'absolute')
          .style('left', d3.event.dx + "px")
          .style('top', d3.event.dy + "px")
          .style('display', 'block');

        d3.event.preventDefault();
    });
    //d3.select("svg").node().oncontextmenu = function(){return false;};

    node.append("image")
        .attr("class", "image")
        .attr("xlink:href", function (d) { return d.profile_image_url; })//"Images/twitterimage_2.png"
        .attr("x", -12)
        .attr("y", -12)
        .attr("width", 24)
        .attr("height", 24);

    node.append("svg:title")
        .text(function (d) { return d.name + "\n" + d.description; });
};

이제 색상과 크기 종속성이 변경되었으며 다른 색상과 반경으로 그래프 원 (+ 모든 추가 된 요소)을 다시 그려야합니다. 그것에 문제가 있습니다.

나는 이것을 할 수있다 :

visualRoot.selectAll(".circle").remove();

하지만 내가 첨부 한 모든 이미지는 '.circles'여전히 거기에 있습니다.

어떤 식 으로든 도움을 주시면 설명이 명확하지 않은 경우 알려 주시면 해결하려고 노력할 것입니다.

추신 graphData.nodes 과 의 차이점은 무엇 d3.selectAll('.nodes')입니까?

답변:


129

귀하의 답변은 효과가 있지만 후손에게는 이러한 방법이 더 일반적입니다.

HTML에서 모든 하위 항목을 제거합니다.

d3.select("div.parent").html("");

SVG / HTML에서 모든 하위 항목을 제거합니다.

d3.select("g.parent").selectAll("*").remove();

.html("")호출은 내 SVG에서 작동하지만 innerSVG 사용의 부작용 일 수 있습니다 .


3
불행히도 .html ( "")은 Safari에서 작동하지 않습니다. 다른 모든 브라우저에서 잘 작동합니다.
glyph

1
@glyph : 공식적인 방법 은 stackoverflow.com/a/43661877/1587329 를 참조하십시오
serv-inc

8

첫 번째 조언은 d3.js선택에 대한 API를 읽어야한다는 것입니다 : https://github.com/mbostock/d3/wiki/Selections

enter()명령이 작동하는 방식 ( API ) 을 이해해야합니다 . 새로운 노드를 처리하기 위해 그것을 사용해야한다는 사실은 당신에게 도움이 될 의미가 있습니다.

다음은 처리 할 때의 기본 프로세스입니다 selection.data().

  • 먼저 일부 데이터를 선택 항목에 "첨부"하려고합니다. 그래서 당신은 :

    var nodes = visualRoot.selectAll(".node")
        .data(graphData.nodes)
    
  • 그런 다음 데이터가 변경 될 때마다 모든 노드를 수정할 수 있습니다 (원하는대로 정확하게 수행됨). 예를 들어로드 한 새 데이터 세트에있는 이전 노드의 반경을 변경하는 경우

    nodes.attr("r", function(d){return d.radius})
    
  • 그런 다음 새 노드를 처리해야합니다.이를 위해 새 노드를 선택해야합니다 selection.enter().

    var nodesEnter = nodes.enter()
        .attr("fill", "red")
        .attr("r", function(d){return d.radius})
    
  • 마지막으로 더 이상 원하지 않는 노드를 제거하고 싶을 것입니다.이를 수행하려면 노드를 선택해야 selection.exit()합니다.

    var nodesRemove = nodes.exit().remove()
    

전체 프로세스의 좋은 예는 API 위키 ( https://github.com/mbostock/d3/wiki/Selections#wiki-exit) 에서도 확인할 수 있습니다.


안녕하세요 Chris, 제안과 포인트에 감사드립니다. 사실 저는 새로운 데이터가 없습니다. 데이터는 여전히 동일합니다. 모든 것이 동일합니다. 다시는 전체 강제 프로세스를 수행하고 싶지 않습니다. 내가 이해하는 한 (내가 틀렸다면 나를 고쳐주세요). 내가해야 할 일은
HotFrost 2013 년

내가해야 할 일은 '.circle'클래스와 그 자식으로 dom 요소를 찾는 것입니다. 그들을 제거하십시오. '.node'클래스가있는 svg 요소를 찾아서 'applyvisualelements'함수에 설명 된 svg 서클 및 기타 시각적 개체에 대한 '첨부'프로세스를 다시 적용하지만 이번에는 반경을 계산할 때 다르게 계산됩니다.
HotFrost

어떤 식 으로든 매우 쉽게 해결했습니다. visualRoot.selectAll ( ". circle"). remove (); visualRoot.selectAll ( ". image"). remove ();
HotFrost

7

이런 식으로 아주 쉽게 해결했습니다.

visualRoot.selectAll(".circle").remove();
visualRoot.selectAll(".image").remove();

그런 다음 반경과 색상을 계산하는 코드가 속성을 변경했기 때문에 다르게 렌더링 된 시각적 요소를 다시 추가했습니다. 감사합니다.


6

요소 자체를 제거 element.remove()하려면했던 것처럼을 사용하십시오 . 요소의 내용 만 제거하고 요소를 그대로 유지하려는 경우 f.ex를 사용할 수 있습니다.

visualRoot.selectAll(".circle").html(null);
visualRoot.selectAll(".image").html(null);

대신 .html("")(삭제하려는 요소의 자식이 무엇인지 잘 모르겠습니다). 이렇게 하면 요소 자체는 유지되지만 포함 된 모든 콘텐츠가 정리됩니다 . 이 작업 을 수행하는 공식적인 방법 이므로 브라우저 간 작동해야합니다.

추신 : 원 크기를 변경하고 싶었습니다. 시도해 보셨습니까

d3.selectAll(".circle").attr("r", newValue);

html(null)11 Internet Explorer에서 나를 위해 작동하지 않습니다
로버트에게

@Robert : "null 값은 내용을 지 웁니다." 버그처럼 보입니다. 콘솔에보고 된 것이 있습니까?
serv-inc

아니요, 오류나 경고가 없습니다. 선택한 개체 만 반환합니다. d3.select($0).html('')선택한 답변에서 IE에서도 작동하지 않지만 작동 d3.select($0).selectAll('*').remove()합니다.
Robert

@Robert : 이것을 신고 하시겠습니까?
serv-inc

3

노드에서 모든 요소를 ​​제거하려면 :

var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
    for (var j = 0; j < siblings.length; j++) {
        siblings[i].parentElement.removeChild(siblings[j]);
    }
}`

당신은 무언가를 인용하기 위해 솔기합니다. 출처는 무엇입니까?
크리스토퍼 Chiche

정말로 자신의 노드에서 모든 노드를 제거해야합니까? 확실히 DOM 권장 방법은 노드가 현재 노드에서 벗어나지 않기 때문에 충분할 것이므로 분리 할 필요도 없습니다.
Tatarize

var element = document.getElementById ( "top"); while (element.firstChild) {element.removeChild (element.firstChild); }
Tatarize
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.