从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.name
或d.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式,当da
与db
匹配时返回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 }