Javascript 将过滤的JSON链接映射到过滤的JSON节点

Javascript 将过滤的JSON链接映射到过滤的JSON节点,javascript,json,d3.js,svg,Javascript,Json,D3.js,Svg,我有一个力定向图的节点和链接数据。链接之间可能有一个、两个或三个链接的num: {"nodes": [{"id": "Michael Scott", "type": "boss"} ,{"id": "Jim Halpert", "type": "employee"} ,{"id": "Pam Beasley", "type": "employee"} ,{"id": "Kevin Malone", "type": "employee"}

我有一个力定向图的节点和链接数据。链接之间可能有一个、两个或三个链接的
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
过滤掉链接,并过滤掉相应的节点?

您可以使用节点
id
s作为对象的键,以确保它们只被添加一次,并且节点数组只被每个
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;
},{}))

您可以将节点
id
s用作对象的键,以确保它们只添加一次,并且每个
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;
},{}))

不要将其视为过滤节点——将其视为过滤链接后重建节点列表。过滤链接后,对其进行迭代,并将您尚未遇到的任何
目标
添加回
节点
数组中。感谢您的深入了解-以这种方式思考肯定会有所帮助。所以我认为我需要使用JS数组方法
map
来迭代。如何确保只找到唯一的源和目标并将它们联合在一起(使用SQL术语)?然后我如何将原始的节点数组与这个新的单元素数组相匹配?我用节点中的额外信息更新了我的问题。换句话说,我需要保留原始节点数组中的信息,而不仅仅是从过滤的链接中提取unique
source
和unique
target
。不要将其视为过滤节点,而是将其视为过滤链接后重建节点列表。过滤链接后,对其进行迭代,并将您尚未遇到的任何
目标
添加回
节点
数组中。感谢您的深入了解-以这种方式思考肯定会有所帮助。所以我认为我需要使用JS数组方法
map
来迭代。如何确保只找到唯一的源和目标并将它们联合在一起(使用SQL术语)?然后我如何将原始的节点数组与这个新的单元素数组相匹配?我用节点中的额外信息更新了我的问题。换句话说,我需要保留原始节点数组中的信息,而不仅仅是从过滤链接中提取unique
source
和unique
target
。谢谢-这是合乎逻辑的。我将其插入到现有代码中,并将
graph
的所有实例替换为
filteredGraph
,现在网络没有出现(尽管SVG图例有)。控制台上没有显示错误。作为一个附带问题-如何在多个JSON属性上包含多个这样的过滤器?似乎需要在代码顶部嵌套函数,但这可能会很快变得混乱。筛选链接只需要一个简单的“或”:
d.num>=val | | d.size>=someOtherVal
。节点过滤器不需要更改。谢谢-这是合乎逻辑的。我将其插入到现有代码中,并将
graph
的所有实例替换为
filteredGraph
,现在网络没有出现(尽管SVG图例有)。控制台上没有显示错误。作为一个附带问题-如何在多个JSON属性上包含多个这样的过滤器?似乎需要在代码顶部嵌套函数,但这可能会很快变得混乱。筛选链接只需要一个简单的“或”:
d.num>=val | | d.size>=someOtherVal
。节点过滤器不需要更改。