d3js - 强制定向图:删除仅链接到自身的节点

时间:2017-05-21 11:53:55

标签: javascript d3.js graph force-layout

我正在尝试从this example执行强制导向图,但我的数据非常大(5000个节点),因此我想删除一些不链接到任何其他节点的节点。

但是,在我的JSON中,每个节点至少有一个链接(链接到自身)。这是我的数据的一个例子:

{"directed": false, "graph": {}, 
"nodes": [{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, 
         {"id": 6}, {"id": 7}, {"id": 8}, {"id": 9}, {"id": 10}, {"id": 11}, {"id": 12}], 

"links": [{"source": 0, "target": 0}, {"source": 1, "target": 1}, 
    {"source": 2, "target": 2}, {"source": 3, "target": 3}, 
    {"source": 4, "target": 4}, {"source": 5, "target": 5}, 
    {"source": 6, "target": 6}, {"source": 7, "target": 8}, 
    {"source": 7, "target": 9}, {"source": 7, "target": 10}, 
    {"source": 7, "target": 11}, {"source": 7, "target": 7}, 
    {"source": 8, "target": 8}, {"source": 9, "target": 9}, 
    {"source": 10, "target": 10}, {"source": 11, "target": 11}, 
    {"source": 12, "target": 12}], "multigraph": false}

即,节点id:0仅包含链接{"source": 0, "target": 0},因此应将其删除,但节点id:7具有链接{"source": 7, "target": 8}, {"source": 7, "target": 7}。它链接到另一个节点,因此不应删除它。

我的问题是如何删除仅链接到自身的节点?

1 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是首先将链接归结为不指向同一节点的链接,即func getCards() { let url = URL(string: "https://omgvamp-hearthstone-v1.p.mashape.com/cards/sets/Classic?mashape-key=....")! let task = URLSession.shared.dataTask(with: url) { (data, response, error) in if error != nil { // if urlSession have issues manage the error here print(error) } else { // if we have data, response, error then continue here if let urlContent = data { // if data exist then do { let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [Dictionary<String, AnyObject>] for cards in 0...jsonResult.count - 1 { let card = Card(name: "", cost: 0, attack: 0, durability: 0, cardClass: "", cardSet: "", imageURL: "", goldenImageURL: "", type: "", mechanics: [["":""]], howToGetGolden: "") if let name = jsonResult[cards]["name"] as? String { //NAME Optionaml Bindings self.card.name = name } else { self.card.name = "" } // END Name Optionaml Bindings if let cost = jsonResult[cards]["cost"] as? Int { //COST Optionaml Bindings self.card.cost = cost } else { self.card.cost = 0 } // END COST Optionaml Bindings if let attack = jsonResult[cards]["attack"] as? Int { //ATTACK Optionaml Bindings self.card.attack = attack } else { self.card.attack = 0 } self.allCard.append(card) // END TTACK Optionaml Bindings } catch { //catch error while parsing json print("error") } } } // end if/ELSE } // end of task (closure) task.resume() } 。我选择使用Array.prototype.reduce(),尽管其他迭代方法也可以使用相同的方法。为了加快以后节点的消除速度,我还使用Set来存储唯一的 id值,但从技术上讲,这不是必需的。

source !== target

过滤节点然后归结为迭代let uniqueNonSelfReferringLinks = data.links.reduce((set, {source:s, target:t}) => s !== t ? set.add(s).add(t) : set, new Set() ); 数组,查找集合中的节点值&#39; IDS:

nodes

将这两个步骤合并为一个可以更简洁地编写:

let filteredNodes = data.nodes.filter(n => uniqueNonSelfReferringLinks.has(n.id));

查看以下工作演示:

&#13;
&#13;
let filteredNodes = data.nodes.filter(
  function(n) { return this.has(n.id); },  
  data.links.reduce((set, {source:s, target:t}) =>
    s !== t ? set.add(s).add(t) : set,
    new Set()
  )
);
&#13;
&#13;
&#13;