【问题标题】:Map Filtered JSON Links to Filter JSON Nodes映射过滤的 JSON 链接以过滤 JSON 节点
【发布时间】:2017-12-09 13:14:48
【问题描述】:

我有力有向图的节点和链接数据。链接之间可能有 num 一个、两个或三个链接:

{"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}]
}

我有一个下拉列表,它应该根据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();

如何完成 JavaScript 数组操作代码以过滤掉基于 num 的链接,同时过滤掉相应的节点?

【问题讨论】:

  • 不要将其视为过滤节点——将其视为过滤链接后重建节点列表。过滤链接后,遍历它们并将您尚未遇到的任何sourcetarget 添加回nodes 数组。
  • 感谢您的洞察力 - 绝对有助于以这种方式思考它。所以我相信我需要使用JS数组方法map来迭代。我将如何确保仅找到唯一的源和目标并将其联合在一起(使用 SQL 术语)?然后我将如何将原始节点数组与这个新的一个元素数组匹配?
  • 我用节点中的额外信息更新了我的问题。换句话说,我需要保留原始节点数组中的信息,而不仅仅是从过滤后的链接中提取唯一的source 和唯一的target

标签: javascript json d3.js svg


【解决方案1】:

您可以使用节点 ids 作为对象的键,以确保它们只添加一次,并且节点数组每个 id 只过滤一次。这假设没有节点链接到自身,但这将是一个不寻常的边缘情况。

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;
},{}))

【讨论】:

  • 谢谢你——这合乎逻辑。我将它插入到我现有的代码中,并用filteredGraph 替换了graph 的所有实例,现在网络没有出现(尽管SVG 图例出现了)。控制台上没有显示错误。
  • 作为一个附带问题 - 如何在多个 JSON 属性中包含多个像这样的过滤器?似乎它需要在代码顶部嵌套函数 - 但这很快就会变得混乱。
  • 过滤链接只需要一个简单的“或”:d.num >= val || d.size >= someOtherVal。节点过滤器不需要更改。
猜你喜欢
  • 1970-01-01
  • 2022-01-05
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多