从 svg 外部的按钮单击 d3 中的节点 [英] clicking a node in d3 from a button outside the svg

查看:30
本文介绍了从 svg 外部的按钮单击 d3 中的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 D3 创建了一个力有向图,并在普通 div 中显示了节点的 id.我需要在 div 中突出显示其 id 已被单击的节点.我搜索了节点的 id 并使用普通的 javascript 尝试单击它,但它不起作用.

解决方案

更一般的,如果用户与元素A交互,你如何选择(然后修改)相关元素B?有很多方法可以实现这一点,但这里是三种常见的方法.

选项 1.对于一对一映射,按 ID 选择.

如果A中的每个元素在B中正好有一个对应的元素,则可以通过id选择相关的元素B,例如d3.select("#foo") 选择一个

.

这种方法需要使用selection.attr.如果您的数据具有固有的唯一标识符,例如 d.named.id,这是最简单的:

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

接下来,要启用单击元素 A 以更改 B 中相应元素的填充颜色,请使用 selection.on 注册一个点击监听器,然后通过id选择:

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

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

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

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

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

您还可以遍历您的数据数组以生成唯一标识符.

选项 2.对于一对多映射,按类选择.

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

与之前的方法一样,您可以使用 selection.attr 设置类"属性.在这种情况下,类属性不是唯一的,因此它可能来自数据中的 d.type 属性:

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

如果您对数据的不同分类属性有多个图例,您也可以更具体并在类名前加上前缀.继续以学生年为例:

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

设置class属性会替换之前设置的所有classes,所以如果你想给元素应用多个classes,你需要在设置class属性的时候用空格把它们连接起来.

接下来,要启用点击元素A改变B中对应元素的填充颜色,使用selection.on注册一个点击监听器,然后选择按班级:

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

请注意,我们在此处使用 selectAll 而不是 选择;那是因为我们要选择所有相应的元素,而不仅仅是第一个.同样,您需要确保 class 属性是 valid.

选项 3.对于其他所有内容,请按数据选择和过滤.

前两种方法生成 id 和类,以便浏览器可以索引 B 中的元素以进行高效选择.对于少量元素,或者需要更通用的选择方法时,可以省略指定id"或class"属性,只需通过 selection.filter.

我们把与A中的每个元素关联的数据称为da,将与B中的每个元素关联的数据称为db.现在我们要做的就是定义一个表达式,当 da 匹配 db 时返回 true.例如,如果我们想按类型过滤:

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

首选前两个选项,但有时手动过滤也很有用,例如当您有一个范围滑块并希望根据定量变量进行过滤时.

I have created a force directed graph using D3 and displayed the id of the nodes in a normal div. I need to highlight the node whose id has been clicked in the div. I have searched the id of the node and using normal javascript tried to click it but it does not work.

解决方案

More generally, if the user interacts with element A, how do you select (and then modify) related elements B? There are many ways of achieving this, but here are three common approaches.

Option 1. For one-to-one mappings, select by id.

If each element in A has exactly one corresponding element in B, you can select the related element B by id, such as d3.select("#foo") to select a <div id="foo">.

This approach requires setting an id for each element in B using selection.attr. This is easiest if your data has an intrinsic unique identifier, such as d.name or d.id:

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

Next, to enable clicking on elements A to change the fill color of the corresponding element in B, use selection.on to register a click listener, and then select by id:

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

Identifiers must be both unique and valid. For example, the id must start with a letter and not a number, and can't contain spaces. If your data doesn't already have a unique identifier, you could generate one from the index, such as

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

And later, assuming the elements A are in the same order,

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

You could also iterate over your data array to generate a unique identifier.

Option 2. For one-to-many mappings, select by class.

To select elements of class "foo", such as a <div class="foo">, say d3.selectAll(".foo"). Use this approach if any element in A corresponds to multiple elements in B. For example, if you had a force-directed graph showing the relationships between students, you might color the nodes based on each student's year, and then use a legend to toggle the visibility of each year.

As with the previous approach, you can use selection.attr to set the "class" attribute. In this case, the class attribute is not unique, so it might come from a d.type property in the data:

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

If you have multiple legends for different categorical attributes of data, you could also be more specific and prefix the class name. To continue the student year example:

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

Setting the class attribute will replace any previously-set classes, so if you want to apply multiple classes to the elements, you need to join them together with a space when setting the "class" attribute.

Next, to enable clicking on elements A to change the fill color of the corresponding elements in B, use selection.on to register a click listener, and then select by class:

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

Note that we're using selectAll here rather than select; that's because we want to select all corresponding elements, rather than just the first one. Again, you'll need to make sure that the class attribute is valid.

Option 3. For everything else, select and filter by data.

The previous two approaches generate ids and classes so that the browser can index the elements in B for efficient selection. For a small number of elements, or when more general selection methods are needed, you can omit specifying "id" or "class" attributes and simply select manually by selection.filter.

Let's call the datum associated with each element in A da, and the datum associated with each element in B db. Now all we have to do is define an expression that returns true when da matches db. For example, if we wanted to filter by type:

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

The first two options are preferred, but occasionally manual filtering is useful, such as when you have a range slider and want to filter based on a quantitative variable.

这篇关于从 svg 外部的按钮单击 d3 中的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆