从svg外面的button中点击d3中的一个节点

我已经使用D3创build了一个强制有向图,并在正常的div中显示了节点的id。 我需要突出显示在div中点击了id的节点。 我已经search的节点的id和使用正常的JavaScript尝试点击它,但它不工作。

更一般地说,如果用户与元素A交互,你如何select(然后修改)相关元素B ? 实现这个目标有很多方法,但是这里有三种常用的方法。

选项1.对于一对一映射,请按IDselect。

如果A中的每个元素在B中只有一个对应的元素,则可以通过idselect相关的元素B,如d3.select("#foo")来select一个<div id="foo">

这种方法需要使用selection.attr为B中的每个元素设置一个id。 如果您的数据具有内部唯一标识符(如d.named.id ,这是最简单的:

 b.attr("id", function(d) { return d.id; }); 

接下来,要启用单击A来更改B中相应元素的填充颜色,请使用selection.on注册单击监听器,然后按IDselect:

 a.on("click", function(d) { d3.select("#" + d.id).style("fill", "red"); }); 

标识符必须是唯一的和有效的 。 例如,该ID必须以字母开头,而不是数字,并且不能包含空格。 如果你的数据还没有唯一的标识符,你可以从索引中生成一个,比如

 b.attr("id", function(d, i) { return "b-" + i; }); 

之后,假设元素A的顺序相同,

 a.on("click", function(d, i) { d3.select("#b-" + i).style("fill", "red"); }); 

你也可以迭代你的数据数组来生成一个唯一的标识符。

选项2.对于一对多映射,请按类select。

要select类“foo”的元素,比如<div class="foo"> ,请说d3.selectAll(".foo") 。 如果A中的任何元素对应于B中的多个元素,则使用此方法。 例如,如果您有一个显示学生之间关系的强制导向图,则可以根据每个学生的年份对节点进行着色,然后使用图例切换每年的可见性。

和以前的方法一样,你可以使用selection.attr来设置“class”属性。 在这种情况下,class属性不是唯一的,所以它可能来自数据中的d.type属性:

 b.attr("class", function(d) { return d.type; }) 

如果对于数据的不同分类属性有多个图例,则也可以使用更具体的名称作为前缀。 继续学生年的例子:

 b.attr("class", function(d) { return "year-" + d.year; }) 

设置class属性将取代以前设置的任何类,所以如果你想要将多个类应用到元素中,你需要在设置“class”属性时将它们连接在一起。

接下来,要启用点击元素A来更改B中相应元素的填充颜色,请使用selection.on注册点击侦听器,然后按类别select:

 a.on("click", function(d) { d3.selectAll("." + d.type).style("fill", "red"); }); 

请注意,我们在这里使用selectAll而不是select ; 这是因为我们要select所有相应的元素,而不是仅仅select第一个元素。 同样,你需要确保class属性是有效的 。

选项3.对于其他项目,select并按数据过滤。

前两种方法生成ids和类,以便浏览器可以索引B中的元素进行有效的select。 对于less数元素,或者当需要更多的常规select方法时,可以省略指定“id”或“class”属性,只需通过selection.filter手动select即可 。

让我们调用与A da中的每个元素相关联的数据,以及与B db每个元素相关联的数据。 现在,我们所要做的就是定义一个expression式,当dadb匹配时返回true。 例如,如果我们想按types过滤:

 a.on("click", function(da) { b.filter(function(db) { return da.type == db.type; }).style("fill", "red"); }); 

前两个选项是首选,但偶尔手动过滤也是有用的,比如当你有一个范围滑块并且想要根据一个定量variables进行过滤时。

当你写:

…和使用正常的JavaScript试图点击它…

你什么意思?

如果你的意思是你写了如下的代码:

 mySVGElement.click(); 

那么这是你的问题。 并不是所有的DOM元素都有一个click()方法,就像<button><input…>可能。 相反,你需要模拟和激发你自己的点击事件 :

 function simulateClick(elementToClick){ var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); var canceled = !elementToClick.dispatchEvent(evt); return canceled; //Indicate if `preventDefault` was called during handling }