2017-09-29 36 views
8

Kodum, bir grafik oluşturur ve her bir düğümde bir pivot noktası oluşturur, çift tıklatırsanız bu düğümle ilişkili daha fazla veri alır ve umarız yeni bağlantılar oluşturur. Şimdi burada ben içine çalıştırıyorum sorun şu:D3 grafiği yeni öğelerle güncelleştiriliyor Yanlış düğümlere sahip kenarlar oluştur

enter image description here enter image description here

Ben en dıştaki düğümlerden biri ancak yeni bağlantılar birinci düğüme bağlı ediliyordu nedense (mavi bir) için tıkladım. Bunun neden olduğu hakkında bir fikrin var mı?

function draw_graph(graph) { 
    var color = d3.scaleOrdinal(d3.schemeCategory20); 

    var svg = d3.select("svg"), 
     width = +svg.attr("width"), 
     height = +svg.attr("height"), 
     node, 
     link; 

    svg.append('defs').append('marker') 
     .attrs({ 
      'id': 'arrowhead', 
      'viewBox': '-0 -5 10 10', 
      'refX': 13, 
      'refY': 0, 
      'orient': 'auto', 
      'markerWidth': 13, 
      'markerHeight': 13, 
      'xoverflow': 'visible' 
     }) 
     .append('svg:path') 
     .attr('d', 'M 0,-5 L 10 ,0 L 0,5') 
     .attr('fill', '#999') 
     .style('stroke', 'none'); 

    var simulation = d3.forceSimulation() 
     .force("link", d3.forceLink().id(function (d) { 
      return d.id; 
     }).distance(200).strength(1)) 
     .force("charge", d3.forceManyBody()) 
     .force("center", d3.forceCenter(width/2, height/2)); 

    update(graph.links, graph.nodes); 

    svg.selectAll('circle').on('dblclick', function() { 
     var pivot_id = ($(this).siblings('title').text()) 
     console.log('pivoting on', pivot_id) 
     pivot_search(pivot_id) 
    }); 


    function update(links, nodes) { 
     link = svg.selectAll(".link") 
      .data(links) 
      .enter() 
      .append("line") 
      .attr("class", "link") 
      .attr('marker-end', 'url(#arrowhead)') 


     edgepaths = svg.selectAll(".edgepath") 
      .data(links) 
      .enter() 
      .append('path') 
      .attrs({ 
       'class': 'edgepath', 
       'fill-opacity': 0, 
       'stroke-opacity': 0, 
       'id': function (d, i) { 
        return 'edgepath' + i 
       } 
      }) 
      .style("pointer-events", "none"); 

     edgelabels = svg.selectAll(".edgelabel") 
      .data(links) 
      .enter() 
      .append('text') 
      .style("pointer-events", "none") 
      .attrs({ 
       'class': 'edgelabel', 
       'id': function (d, i) { 
        return 'edgelabel' + i 
       }, 
       'font-size': 10, 
       'fill': '#aaa' 
      }); 

     node = svg.selectAll(".node") 
      .data(nodes) 
      .enter() 
      .append("g") 
      .attr("class", "node") 
      .call(d3.drag() 
       .on("start", dragstarted) 
       .on("drag", dragged) 
      ); 

     node.append("circle") 
      .attr("r", 5) 
      .attr("fill", function (d) { 
       return color(d.group); 
      }) 


     node.append("title") 
      .text(function (d) { 
       return d.id; 
      }); 

     node.append("text") 
      .attr("dy", -3) 
      .text(function (d) { 
       return d.label; 
      }); 


     simulation 
      .nodes(nodes) 
      .on("tick", ticked); 

     simulation.force("link") 
      .links(links); 

    } 

    function ticked() { 
     link 
      .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; 
      }); 

     node 
      .attr("transform", function (d) { 
       return "translate(" + d.x + ", " + d.y + ")"; 
      }); 

     edgepaths.attr('d', function (d) { 
      return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y; 
     }); 

     edgelabels.attr('transform', function (d) { 
      if (d.target.x < d.source.x) { 
       var bbox = this.getBBox(); 

       rx = bbox.x + bbox.width/2; 
       ry = bbox.y + bbox.height/2; 
       return 'rotate(180 ' + rx + ' ' + ry + ')'; 
      } 
      else { 
       return 'rotate(0)'; 
      } 
     }); 
    } 

    function dragstarted(d) { 
     if (!d3.event.active) simulation.alphaTarget(0.3).restart() 
     d.fx = d.x; 
     d.fy = d.y; 
    } 

    function dragged(d) { 
     d.fx = d3.event.x; 
     d.fy = d3.event.y; 
    } 


} 

function pivot_search(entity_id) { 
    var json = { 
     'nodes': [], 
     'links': [], 
    } 
    get_entities({'id': entity_id}) 
     .done(function (data) { 
      json.nodes.push({ 
       'label': data['results'][0]['label'], 
       'id': data['results'][0]['id'], 
       'group': data['results'][0]['entity_type'], 
      }) 
      get_entities({ 
       'related_entities': entity_id, 
       'related_entities__entity_instance__entity_type__strong_entity': true, 
       'page_size': 500 
      }) 
       .done(function (data) { 
        for (var i = 0; i < data['results'].length; i++) { 
         json.nodes.push({ 
          'label': data['results'][i]['label'], 
          'id': data['results'][i]['id'], 
          'group': data['results'][i]['entity_type'], 
         }) 
         json.links.push({ 
          'source': entity_id, 
          'target': data['results'][i]['id'], 

         }) 
        } 
        draw_graph(json) 
       }) 
     }) 
} 

DÜZENLEME: Bu yeni verilerle mevcut düğüm bağlantıları değiştirilmesi ve potansiyel olarak yinelenen yeni düğümler yaratıyor gibi başka araştırmalar görünüyor üzerine.

link = svg.selectAll('.link') 
      .data(links, function (d) { 
       return d.id; 
      }) 
      .enter() 
      .append('line') 
      .attr('class', 'link') 
      .attr('marker-end', 'url(#arrowhead)') 


     edgepaths = svg.selectAll('.edgepath') 
      .data(links) 
      .enter() 
      .append('path') 
      .attrs({ 
       'class': 'edgepath', 
       'fill-opacity': 0, 
       'stroke-opacity': 0, 
       'id': function (d, i) { 
        return 'edgepath' + i 
       } 
      }) 
      .style('pointer-events', 'none'); 

     node = svg.selectAll('.node') 
      .data(nodes, function (d) { 
       return d.id; 
      }) 
      .enter() 
      .append('g') 
      .attr('class', 'node') 
      .call(d3.drag() 
       .on('start', dragstarted) 
       .on('drag', dragged) 
      ); 

Ben düğüm çoğaltma başa çıkmaya yönelik bir kimliği eklendi, ama şimdi indeks kök yer değiştirme ile ilgili bir sorun var.

enter image description here enter image description here

+0

Merhaba, .data birleşimine geçiş yapmayı denediniz mi? örneğin .data (links, function (d) {return d.id}). Verilerin güncellenmesi ile tutarlılık istediğinizde bu genellikle gereklidir. Detaylar için buraya bakın https://github.com/d3/d3-selection#selection_data –

+0

@tomShanley Yaptım ve bazı problemleri çözdü. Ama hala bağlantılar ile garip sorunlara koşuyor. –

cevap

1

Karşılaştığınız sorun veri D3 veri birleşim işlevselliği içinde çoğaltarak olabileceği gerçeği nedeniyle anlaşılmaktadır. Sorunu çözmenin en iyi yolunun, D3'ü bağlamadan önce verilerinizdeki her düğüm için bir "UUID/GUID" oluşturmasıdır (örnek için here'a bakın). Bunu yaptıktan sonra, verileri tutarlı hale getirmek için verileri bağlayabilir ve veri-birleşiminin anahtar belirleme işlevini (açıklama için here) kullanabilirsiniz; bu, D3'ün tutarlılığı garantilemek için her nesne için oluşturduğunuz UUID/GUID değerlerini kullanmasını söyleyebilirsiniz. Oradan, ebeveyn-çocuk ilişkilerini daha kolay idare edebilmelisiniz. Bu yinelenen değerler için çalıştı beri "kaynak" nesneye referans D3 beklenir bu şekilde kurulmamış çünkü

Düzenleme 1.

, büyük olasılıkla yaşıyorsanız sonraki sorundur. D3'te, bağlantının "source" özelliği, sadece ID değerini sağladığınız gerçek kaynak nesneye yapılan bir başvurudır (bkz. D3v4 docs başvurusu için here). Dizideki gerçek kaynak nesneye referans sağlamayı deneyin ve düzeltmeniz gerekir.

Düzenleme 2.

Sen görselleştirmelere gelen YENİ verileri işlediğiniz de doğrudur, ama hiçbir vardır MEVCUT veya ESKİ (anlamı, veri noktalarını ele konum sanmıyorum Daha uzun alakalı ve düğümler/bağlantılar kaldırılmalı). Bu durumda, kodunuzu aşağıdaki örnekle birlikte Mike Bostock'dan (D3.js kitaplığının orijinal yaratıcısı) here güncelleştirmeyi deneyin ve ardından bir kez bitti raporunu bildirin. Gördüğünüz yeni düğümlerin, artık çocuklara bağlı olmadıkları için çıkarılması gereken eski düğümler olması mümkündür, bu nedenle D3js onları gerçekten olması gereken "yeni" veya "var olan" düğümler olarak görür. çıkarıldı.

+0

Bu nedenle, bir anahtar işlevi eklemek, çoğaltma sorununu düğümlerle çözdü, ancak her şey hala köke bağlanıyor. –

+0

Düzenlenmiş yorum @ Stupid.Fat.Cat – th3n3wguy

+0

Grafiği güncellemenin yolunun "doğru" şekilde olmadığı anlaşılıyor, yeni veri eklediğim yol doğru mu? (temelde svg'yi getir ve bazı şeyleri ona ekle) –