2016-03-23 6 views
1

Basierend auf der Anleitung von Stephen Thomas https://github.com/sathomas/jsDataV.is-source/tree/master/ch7/force, habe ich versucht, eine d3 Force-Layout-Grafik zu machen.D3 - Positionierung Kanten wirft NaN-Fehler

Allerdings stecke ich auf einen Fehler, den ich nicht kenne die Herkunft und wie man es anpackt.

Es gelten folgende Plunker http://plnkr.co/edit/Bx0qe8DNEsnFgLhkxbfS?p=preview dieser Ausschnitt verursacht

var positionEdge = function(edge, nodes) { 
     edge.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; }); 
    }; 

Viele Fehler z.B. Fehler: ungültiger Wert für das Attribut y2 = „NaN“

ich meine Kanten Array wie folgt bauen, aber voll in der Lage sein, das Problem zu reproduzieren Sie bitte die Plunker Link:

var edges = []; 
     links.forEach(function(srcLink){ 
      var targetNodeId; 
      var targetNodeName; 
      var sourceNodeId; 
      var sourceNodeName; 

      nodes.forEach(function(srcNode){ 
       if(srcNode.label === srcLink.source){ 
        sourceNodeId = srcNode.id; 
        sourceNodeName = srcNode.label; 
       } else if(srcNode.label === srcLink.target){ 
        targetNodeId = srcNode.id; 
        targetNodeName = srcNode.label; 
       } 
      }) 
      edges.push({ 
       "id": "From_" + sourceNodeName + "_To_" + targetNodeName, 
       "target": targetNodeId, 
       "source": sourceNodeId 
      }); 
     }) 

     // remove duplicate edges 
     var arr = {}; 
     for (var i=0, len=edges.length; i < len; i++) 
      arr[edges[i]['id']] = edges[i]; 

     edges = new Array(); 
     for (var key in arr) 
      edges.push(arr[key]); 

Was alles verursacht Die NaN-Fehler werden ausgelöst, wenn die Funktion positionEdge aufgerufen wird.

Antwort

1

Es scheint, dass die Felder source und target in Ihren Kanten Knoten-IDs sind, anstatt Objekte. Sie haben zwei Lösungen:

  • Verwendung Objekte:

    edges.push({ 
         "id": "From_" + sourceNodeName + "_To_" + targetNodeName, 
         "target": nodes[targetNodeId], 
         "source": nodes[sourceNodeId] 
        }); 
    

oder

  • Verwendung Indizes (schlechte Idee, zu bearbeiten Anmerkung unten sehen)

    var positionEdge = function(edge, nodes) { 
        edge.attr("x1", function(d) { return nodes[d.source].x; }) 
         .attr("y1", function(d) { return nodes[d.source].y; }) 
         .attr("x2", function(d) { return nodes[d.target].x; }) 
         .attr("y2", function(d) { return nodes[d.target].y; }); 
    }; 
    

Der Standard in d3 ist, die erste Option zu verwenden, aber es kann andere Änderungen geben, die zu Ihrem Code führen, wenn Sie dafür gehen. Mit der zweiten Option bleiben Sie bei jeder Verwendung eines Edge-Endpunkts bei der Verwendung von Knoten [d.source] und Knoten [d.target].


bearbeiten: Eigentlich ist die force Layout wandelt automatisch indexbasierte Kanten in objektbasierten. Wenn Sie also nicht zwei verschiedene Arrays für Kanten verwenden, müssen Sie die erste Option wählen.

+0

Vielen Dank Laurent. Ich habe mich für die zweite Option entschieden, die Sie mir gegeben haben, weil die Verwendung der ersten genau die gleichen Fehler ergibt (wahrscheinlich aufgrund der anderen Änderungen, die Sie notiert haben). ** Mit der zweiten Option sehe ich nicht mehr den Fehler, dass ich das Thema für ** geöffnet habe. Daher werde ich Ihre Antwort als Antwort auf meine Frage markieren. Wenn Sie jedoch bereit wären, sich das erneute Plunderbeispiel anzusehen, würde ich das sehr begrüßen. Ich erhalte den 'Ungültigen Wert für attribute transform =" translate (NaN, NaN) "' Fehler. http://plnkr.co/edit/Bx0qe8DNEsnFgLhkxbfS?p=preview –

+0

@Sander_M: Ich habe komplett vergessen, dass die Verwendung der ersten Option nicht nur der Standard, sondern tatsächlich von 'd3.force' (siehe Bearbeiten) erzwungen wurde. Entschuldige, dass ich dich irreführe. – tarulen

+0

Ich bin traurig zu hören, dass Option 2 keine gültige ist;) Ich gehe deinen Ratschlag und verwende Objekte als Ziel und Quelle. Wahrscheinlich bedeutet das, ich muss von vorne anfangen. Sehr gut für meine Lernkurve, ich liebe wirklich Datenvisualisierung mit D3. Auch wenn es sich komplexer anfühlt als beispielsweise sigma.js, bietet es auch viele weitere Möglichkeiten und Möglichkeiten. Danke, dass du die Dinge geklärt hast und die Bearbeitung! –