2017-07-05 1 views
0

Ich habe Knoten- und Verknüpfungsdaten für ein kraftgerichtetes Diagramm. Links können num von einer, zwei oder drei Verbindungen zwischen ihnen haben:Gefilterte JSON-Verbindungen zum Filtern von JSON-Knoten

{"nodes": [{"id": "Michael Scott", "type": "boss"} 
      ,{"id": "Jim Halpert", "type": "employee"} 
      ,{"id": "Pam Beasley", "type": "employee"} 
      ,{"id": "Kevin Malone", "type": "employee"} 
      ,{"id": "Angela", "type": "employee"} 
      ,{"id": "Dwight Schrute", "type": "employee"}] 
,"links": [{"source": "Michael Scott", "target": "Jim Halpert", "num": 1} 
      ,{"source": "Pam Beasley", "target": "Kevin Malone", "num": 2} 
      ,{"source": "Pam Beasley", "target": "Kevin Malone", "num": 2} 
      ,{"source": "Angela", "target": "Dwight Schrute", "num": 3} 
      ,{"source": "Angela", "target": "Dwight Schrute", "num": 3} 
      ,{"source": "Angela", "target": "Dwight Schrute", "num": 3}] 
} 

I ein Dropdown habe, die Filterung von Knoten und Verbindungen für ein d3 kraft gerichteten Graphen Laufwerk sollte, basierend auf num. Ich habe diesen Code so weit über die JSON-Knoten und Verbindungsdaten

var dropdown = d3.select("#selectLinkNumber") 
var change = function() { 
d3.selectAll("svg > *").remove() 
var val = dropdown.node().options[dropdown.node().selectedIndex].value; 

d3.json("test.json", function(error, graph) { 
    var filteredLinks = graph.links.filter(d => d.num >= val); 
    //Needs some way to map unique source and targets to id in nodes 
    var filteredNodes = graph.nodes.filter()//Needs some way to fill node filtering with mapping from filteredLinks 
     }); 

    var filteredGraph = { 
      nodes: filteredNodes, 
      links: filteredLinks 
     }; 
    //do stuff 
    }) 
} 
dropdown.on("change", change) 
change(); 

Wie würde ich die JavaScript-Array Manipulation Code beenden zu filtern Links auf num Basis, um herauszufiltern, und auch die entsprechenden Knoten herauszufiltern?

+1

Denken Sie nicht daran, die Knoten zu filtern - denken Sie daran, die Knotenliste neu aufzubauen, nachdem Sie die Links gefiltert haben. Nachdem Sie die Links gefiltert haben, durchlaufen Sie sie und addieren Sie alle noch nicht gefundenen "Quellen" oder "Ziele" zurück in das Array "nodes". – anbnyc

+0

Danke für diesen Einblick - definitiv hilft, darüber auf diese Weise zu denken. Also glaube ich, dass ich die JS-Array-Methode 'map' verwenden muss, um zu iterieren. Wie würde ich sicherstellen, dass nur eindeutige Quellen und Ziele zusammen gefunden und vereinigt werden (um SQL-Terminologie zu verwenden)? Und wie würde ich dann das ursprüngliche Nodes-Array an dieses neue, ein Element-Array anpassen? –

+0

Ich habe meine Frage mit zusätzlichen Informationen in den Knoten aktualisiert. Mit anderen Worten, ich muss Informationen aus dem ursprünglichen Knoten-Array behalten und nicht nur eindeutige "Quellen" und eindeutige "Ziele" aus den gefilterten Links ziehen. –

Antwort

1

Sie können den Knoten id als Schlüssel für ein Objekt verwenden, um sicherzustellen, dass sie nur einmal hinzugefügt werden. Das Knotenarray wird nur einmal pro id gefiltert. Dies setzt voraus, dass kein Knoten mit sich selbst verknüpft ist, aber das wäre ein ungewöhnlicher Randfall.

var filteredNodes = Object.values(filteredLinks.reduce(function(t,v){ 
    if(!t[v.source]){ 
    t[v.source] = graph.nodes.filter(o => o.id === v.source)[0] 
    } 
    if(!t[v.target]){ 
    t[v.target] = graph.nodes.filter(o => o.id === v.target)[0] 
    } 
    return t; 
},{})) 
+0

Danke - das macht logisch Sinn. Ich steckte das in meinen vorhandenen Code ein und ersetzte alle Instanzen von 'graph' durch' filteredGraph', und jetzt erscheint das Netzwerk nicht mehr (obwohl die SVG-Legenden dies tun). Auf der Konsole wird kein Fehler angezeigt. –

+0

Es funktioniert! Ich war dicht. Vielen Dank! –

+0

Als eine Nebenfrage - wie würde man mehrere Filter wie diese auf mehrere JSON-Attribute enthalten? Scheint so, als würde es die Verschachtelung der Funktionen an der Spitze des Codes erfordern - aber das könnte wirklich schnell unordentlich werden. –