2017-07-05 7 views
0

強制的なグラフのノードとリンクのデータがあります。リンクは、それらの間numの一、二、又は三のリンクを有していてもよい:マップフィルタリングされたJSONフィルタリングJSONノードへのリンク

{"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はnumに基づいたD3力指向グラフのノードおよびリンクのフィルタリングを駆動する必要があり、ドロップダウンを持っています。私はこれまでJSONノードとリンクのデータをフィルタリングするために

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

どのように私はnumに基づいてリンクをフィルタリングし、また対応するノードをフィルタリングするためにJavaScript配列操作コードを終えるだろう、このコードを持っていますか?

+1

ノードをフィルタリングするとは思わない - リンクをフィルタした後にノードリストを再構築すると考えてください。リンクをフィルタリングした後、それらを繰り返して、まだ出会っていない 'source'または' target'を 'nodes'配列に追加してください。 – anbnyc

+0

その洞察をいただきありがとうございます - 間違いなくそのように考えてください。だから、私はJS配列メソッド 'map'を使って反復処理をする必要があると思います。ユニークなソースとターゲットだけが(SQL用語を使用するために)一緒に見つけられ、統合されていることを確認するにはどうすればよいでしょうか?そして、元のノード配列をこの新しい要素配列にどのようにマッチさせるのですか? –

+0

私は質問をノードの追加情報で更新しました。つまり、フィルタリングされたリンクから一意の 'source'と一意の' target'を取り出すだけでなく、元のノード配列から情報を保持する必要があります。 –

答えて

1

オブジェクトのキーとしてノードidを使用して、それらが確実に1回追加され、ノード配列がidごとに1回だけフィルタされるようにすることができます。これはノードがそれ自体にリンクされていないと仮定していますが、それは異常な場合です。

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

ありがとうございます - それは理にかなっています。私はそれを私の既存のコードに差し込み、 'graph'のすべてのインスタンスを' filteredGraph'に置き換えました。そして、ネットワークは現れません(SVGの伝説がしますが)。コンソールにエラーは表示されません。 –

+0

それは動作します!私は密集していた。ありがとうございました! –

+0

副次的な質問として、このような複数のフィルタを複数のJSON属性に含めるにはどうすればよいですか?コードの先頭に関数を入れ子にする必要があるようですが、それは本当に素早く乱雑になる可能性があります。 –

関連する問題