2017-07-05 77 views
0

我有節點和鏈接數據的力量有向圖。節點之間可以有一個,兩個或三個環節:通過基於Dropdown的JSON屬性過濾d3 SVG

{"nodes": [{"id": "Michael Scott", "numOfLinks": 1} 
      ,{"id": "Jim Halpert", "numOfLinks": 1} 
      ,{"id": "Pam Beasley", "numOfLinks": 2} 
      ,{"id": "Kevin Malone", "numOfLinks": 2} 
      ,{"id": "Angela", "numOfLinks": 3} 
      ,{"id": "Dwight Schrute", "numOfLinks": 3}] 
,"links": [{"source": "Michael Scott", "target": "Jim Halpert", "type": "red"} 
      ,{"source": "Pam Beasley", "target": "Kevin Malone", "type": "red"} 
      ,{"source": "Pam Beasley", "target": "Kevin Malone", "type": "white"} 
      ,{"source": "Angela", "target": "Dwight Schrute", "type": "red"} 
      ,{"source": "Angela", "target": "Dwight Schrute", "type": "white"} 
      ,{"source": "Angela", "target": "Dwight Schrute", "type": "blue"}] 
} 

我有一個HTML下拉爲用戶過濾掉節點(以及相應的鏈接),沒有一定數量的鏈接:

<select id="selectLinkNumber" name="selectLinkNumber"> 
    <option value="1">All</option> 
    <option value="2">Two or More Links</option> 
    <option value="3">Three or More Links</option> 
</select> 

我已經把這個下拉到我的D3代碼:

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) { 
    //do stuff 
    }) 
} 
dropdown.on("change", change) 
change(); 

這導致被移除的圖形,當一個新的選擇,從下拉做下來重新出現。目標是隻有節點的值大於或等於選定值。例如,如果選擇「三」,則只有安吉拉,德懷特和他們的三個鏈接出現。如果選擇「Two」,則選擇Pam,Kevin,Angela,Dwight和他們的相應鏈接。

從邏輯上說,我認爲需要在d3.json("test.json", function(error, graph) {行之後直接過濾test.json數據,基於val。但我不確定如何有效地完成這一點。這個例子(https://jsfiddle.net/tgv6s5cd/14/)基本上做我正在尋找的東西,但我無法通過手動數據創建和衆多功能。我認爲只需在導入後過濾一次會更簡單test.json

一旦用戶進行下拉選擇,我應該如何過濾數據?

回答

0

這是Javascript中的基本數組操作。畢竟只是一個具有兩個數組屬性的對象。

d3.json("test.json", function(error, graph) { 
    var filteredNodes = graph.nodes.filter(d => d.numOfLinks >= val); 
    var names = filteredNodes.map(d => d.id); 
    var filteredLinks = graph.links.filter((d) => { 
     return (names.indexOf(d.source) >= 0) || 
       (names.indexOf(d.target) >= 0) 
    }); 

    var filteredGraph = { 
     nodes: filteredNodes, 
     links: filteredLinks 
    }; 
    // render 
}) 
+0

非常感謝您的幫助。如果'value'在鏈接數組中,那麼代碼如何改變? –

+0

我將第一行更改爲'var filteredLinks = graph.links.filter(d => d.numOfLinks> = val);',並且我相信'var filteredGraph'會保持不變。只是不知道如何映射回節點,因爲它們只有'id'而不是'source'和'target'。 –