基于单选按钮过滤器动态更改 d3 力图中链接和节点的不透明度

Dynamically change opacity of links and nodes in d3 force graph based on radio button filter

我有a jsfiddle here。选择过滤器单选按钮后,我希望它根据元素和链接的等级动态更改元素和链接的不透明度(节点对象有一个 rating 属性 和一个整数值)。

由于函数被嵌套不能简单地使用onchange/onclick

当我将一个 JS 函数绑定到单选按钮的 onchange 或 onclick 方法时,它找不到该函数,因为它在 d3.json(){}; 块内(该示例将数据分开以使其成为在 fiddle 上工作,但此行已被注释掉)。如果我不把这个函数放在那个块里,它就不能访问链接和节点,但如果它在里面,onchange/onclick 就找不到它。我无法从 html 端调用嵌套函数,因为它超出了范围。

无法将属性添加到现有输入单选按钮(不起作用)

然后我尝试将 onchange 和 onclick 事件动态添加到 JS 端的输入中(我尝试了两种方法),但这似乎没有用(也许我做错了)。

怎么做?

我试过让 #1 在下面工作,但我实际上停留在 #1 上,这让我觉得我正在以错误的方式解决问题。必须有另一种方法来做到这一点。

  1. 找出当从单选按钮触发 onchangeonclick 事件时如何调用 d3.json(){} 块内的函数。

  2. 找出如何根据数据更改节点和链接的不透明度。

This 是一个类似的问题,但是没有例子所以我看不到如何应用它。我 在我的节点对象中有一个要过滤的字段,但无法弄清楚如何动态地响应单选按钮选择。

只需在 .json 回调之外的范围内创建对您关心的变量的引用。在这种情况下,它可能是 linknode:

var link, node;
d3.json('map2.json', function(error, graph) { 

   ...

   link = container.append("g")
    .attr("class", "links")

   ...

   node = container.append("g")
    .attr("class", "nodes")

   ...

});

然后您可以使用这些是您的单选按钮的更改事件:

d3.selectAll("input[name=filter]").on("change", function(d){

  // value of selected radio
  var value = this.value;
  // everybody
  node.style("opacity", 1);
  // those that aren't dim
  if (value !== "all"){
    value = +this.value;
    node.filter(function(d){
      return d.rating != value;
    })
    .style("opacity", "0.5");
  }

});

运行代码here.