Bir düğümdeki tüm alt öğeleri nasıl kaldırırım ve sonra bunları farklı renk ve boyutta yeniden uygularım?


87

Bu yüzden, düğümleri, bağlantıları ve diğer öğeleri ayarlamak için bir sonraki kuvvet düzeni grafik koduna sahibim:

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

Şimdi, renkler ve boyut bağımlılıkları değişti ve grafik çemberlerini (+ eklenen tüm öğeler) farklı renk ve yarıçapla yeniden çizmem gerekiyor. Bununla ilgili sorun yaşıyorum.

Bunu yapabilirim:

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

ama eklediğim tüm görüntüler '.circles'hala orada duruyor.

Herhangi bir şekilde, herhangi bir yardım takdir edilecektir, açıklama yeterince açık değilse bana bildirin, düzeltmeye çalışacağım.

PS graphData.nodes ve arasındaki fark d3.selectAll('.nodes')nedir?

Yanıtlar:


132

Cevabınız işe yarayacak, ancak gelecek nesil için bu yöntemler daha geneldir.

Tüm alt öğeleri HTML'den kaldırın:

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

Tüm alt öğeleri SVG / HTML'den kaldırın:

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

.html("")Çağrı benim SVG ile çalışır, ancak kullanmanın bir yan etkisi olabilir innerSVG .


3
Ne yazık ki .html ("") Safari'de çalışmıyor. Diğer tüm tarayıcılarda iyi çalışıyor.
glif

1
@glyph: Bunu yapmanın resmi yolu için stackoverflow.com/a/43661877/1587329 adresine bakın
serv-inc

8

İlk tavsiyem, d3.jsseçimlerle ilgili API'yi okumanızdır : https://github.com/mbostock/d3/wiki/Selections

enter()Komutun nasıl çalıştığını anlamalısınız ( API ). Yeni düğümleri işlemek için kullanmak zorunda olmanız gerçeğinin size yardımcı olacak bir anlamı var.

İşte uğraştığınız temel süreç selection.data():

  • önce seçime bazı verileri "eklemek" istersiniz. Yani sizde:

      var nodes = visualRoot.selectAll(".node")
          .data(graphData.nodes)
    
  • Ardından, her veri değiştiğinde tüm düğümleri değiştirebilirsiniz (bu tam olarak istediğinizi yapacaktır). Örneğin, yüklediğiniz yeni veri kümesindeki eski düğümlerin yarıçapını değiştirirseniz

      nodes.attr("r", function(d){return d.radius})
    
  • Ardından, yeni düğümleri işlemeniz gerekir, bunun için yeni düğümleri seçmeniz gerekir, bunun selection.enter()için yapılan şey budur:

      var nodesEnter = nodes.enter()
          .attr("fill", "red")
          .attr("r", function(d){return d.radius})
    
  • Sonunda, artık istemediğiniz düğümleri kesinlikle kaldırmak istiyorsunuz, bunu yapmak için onları seçmelisiniz, bunun selection.exit()için yapılmış.

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

Tüm sürecin iyi bir örneği API wiki'de de bulunabilir: https://github.com/mbostock/d3/wiki/Selections#wiki-exit


Merhaba Chris, önerileriniz ve puanlarınız için teşekkürler. Gerçek şu ki, yeni verilerim yok .. Veriler hala aynı. Her şey aynı. Tüm kuvvet sürecini tekrar yapmak istemiyorum. Anladığım kadarıyla (yanılıyorsam düzeltin). Tek yapmam gereken
HotFrost

Tek yapmam gereken '.circle' sınıfıyla ve çocuklarıyla dom öğeleri bulmak. Onları kaldır. '.Node' sınıfıyla svg elemanlarını bulun ve 'applyvisualelements' fonksiyonunda açıklanan svg çevreleri ve diğer görseller için 'attach' işlemini yeniden uygulayın, ancak bu kez yarıçap hesaplandığında farklı şekilde hesaplanacaktır.
HotFrost

herhangi bir şekilde çok kolay çözdüm, visualRoot.selectAll (". circle"). remove (); visualRoot.selectAll (". image"). remove ();
HotFrost

7

bu şekilde çok kolay çözdüm,

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

ve sonra, yarıçapı ve rengi hesaplama kodu özellikleri değiştirdiği için farklı şekilde oluşturulan görsel öğeleri yeniden ekledim. Teşekkür ederim.


6

Öğenin kendisini kaldırmak istiyorsanız element.remove(), yaptığınız gibi kullanın . Yalnızca öğenin içeriğini kaldırmak, ancak öğeyi olduğu gibi tutmak istiyorsanız, f.ex'i kullanabilirsiniz.

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

yerine .html("")(hangi öğenin çocuklarının silinmesini istediğinizden emin değildim). Bu , öğenin kendisini tutar ancak dahil edilen tüm içeriği temizler . Bunu yapmanın resmi yolu , tarayıcılar arası çalışmalıdır.

Not: daire boyutlarını değiştirmek istediniz. Denedin mi

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

html(null)benim için Internet Explorer 11'de çalışmıyor
Robert

@Robert: "Boş bir değer içeriği temizleyecektir." Böcek gibi görünüyor. Konsola bir şey bildirildi mi?
serv-inc

Hayır, hata veya uyarı yok. Sadece seçilen nesneyi döndürür. d3.select($0).html('')seçilen cevaptan benim için IE'de d3.select($0).selectAll('*').remove()çalışmıyor , ama çalışıyor.
Robert

@Robert: Bunu bildirmek ister misin ?
serv-inc

3

Tüm elemanı bir düğümden kaldırmak için:

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

Bir şeyden alıntı yapmak için dikiş atıyorsun, kaynağı nedir?
Christopher Chiche

Tüm bu düğümleri de kendi düğümlerinden kaldırmanız gerçekten gerekiyor mu? Elbette DOM tarafından önerilen yöntem yeterli olacaktır, çünkü düğümler mevcut düğümden ayrılmayacaktır, parçalanması da gerekmez.
Tatarize

var element = document.getElementById ("top"); while (element.firstChild) {element.removeChild (element.firstChild); }
Tatarize
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.