选择元素
一个选择是 DOM 中的一组元素。通常这些元素通过 选择器 来识别,例如 .fancy
用于具有类fancy 的元素,或者 div
用于选择 DIV 元素。
选择方法有两种形式,select 和 selectAll:前者只选择第一个匹配的元素,而后者选择文档中所有匹配的元素(按文档顺序)。顶级选择方法,d3.select 和 d3.selectAll,查询整个文档;子选择方法,selection.select 和 selection.selectAll,将选择范围限制为所选元素的后代。还有 selection.selectChild 和 selection.selectChildren 用于直接子元素。
按照惯例,返回当前选择的 selection 方法(如 selection.attr)使用四个空格缩进,而返回新选择的 selection 方法只使用两个空格缩进。这有助于通过突出显示上下文变化来揭示上下文变化。
d3.select("body")
.append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g")
.attr("transform", "translate(20,20)")
.append("rect")
.attr("width", 920)
.attr("height", 460);
selection()
源代码 · 选择 根元素 document.documentElement
。
const root = d3.selection();
此函数也可用于测试选择(instanceof d3.selection
)或扩展选择原型。例如,要向选择添加一个方法来检查复选框
d3.selection.prototype.checked = function(value) {
return arguments.length < 1
? this.property("checked")
: this.property("checked", !!value);
};
然后使用
d3.selectAll("input[type=checkbox]").checked(true);
select(selector)
源代码 · 选择与指定 selector 字符串匹配的第一个元素。
const svg = d3.select("#chart");
如果没有任何元素与 selector 匹配,则返回一个空选择。如果多个元素与 selector 匹配,则只选择第一个匹配的元素(按文档顺序)。例如,要选择第一个锚元素
const anchor = d3.select("a");
如果 selector 不是字符串,则选择指定的节点;如果您已经拥有节点的引用(如 document.body
),这很有用。
d3.select(document.body).style("background", "red");
或者,要使单击的段落变为红色
d3.selectAll("p").on("click", (event) => d3.select(event.currentTarget).style("color", "red"));
selectAll(selector)
源代码 · 选择与指定 selector 字符串匹配的所有元素。
const p = d3.selectAll("p");
这些元素将按文档顺序(从上到下)选择。如果文档中没有任何元素与 selector 匹配,或者 selector 为空或未定义,则返回一个空选择。
如果 selector 不是字符串,则选择指定的节点数组;如果您已经拥有节点的引用(如事件监听器中的 this.childNodes
或全局变量 document.links
),这很有用。这些节点可以是可迭代对象,也可以是伪数组,如 NodeList。例如,要将所有链接颜色设置为红色
d3.selectAll(document.links).style("color", "red");
selection.select(selector)
源代码 · 对于每个选定元素,选择第一个与指定 selector 字符串匹配的后代元素。
const b = d3.selectAll("p").select("b"); // the first <b> in every <p>
如果当前元素的指定选择器没有任何匹配的元素,则返回选择中当前索引处的元素将为 null。(如果 selector 为 null,则返回选择中的每个元素都将为 null,从而导致选择为空。)如果当前元素具有关联数据,则此数据将传播到相应的选定元素。如果多个元素与选择器匹配,则只选择第一个匹配的元素(按文档顺序)。
如果 selector 是一个函数,则按顺序针对每个选定元素对其进行评估,并传递当前数据 (d)、当前索引 (i) 和当前组 (nodes),其中 this 为当前 DOM 元素 (nodes[i])。它必须返回一个元素,或者如果没有任何匹配的元素,则返回 null。例如,要选择每个段落的上一级同级元素
const previous = d3.selectAll("p").select(function() {
return this.previousElementSibling;
});
与 selection.selectAll 不同,selection.select 不会影响分组:它保留现有分组结构和索引,并将数据(如果有)传播到选定的子元素。分组在 数据连接 中起着重要作用。有关此主题的更多信息,请参阅 嵌套选择 和 选择的工作原理。
警告
selection.select 将父级的数据传播到选定的子元素。
selection.selectAll(selector)
源代码 · 对于每个选定元素,选择与指定 selector 字符串匹配的后代元素。
const b = d3.selectAll("p").selectAll("b"); // every <b> in every <p>
返回选择中的元素将按其在该选择中的相应父节点分组。如果当前元素的指定选择器没有任何匹配的元素,或者 selector 为 null,则当前索引处的组将为空。选定的元素不会从该选择继承数据;使用 selection.data 将数据传播到子元素。
如果 selector 是一个函数,则按顺序针对每个选定元素对其进行评估,并传递当前数据 (d)、当前索引 (i) 和当前组 (nodes),其中 this 为当前 DOM 元素 (nodes[i])。它必须返回一个元素数组(或可迭代对象,或伪数组,如 NodeList),或者如果没有匹配的元素,则返回空数组。例如,要选择每个段落的上一级和下一级同级元素
const sibling = d3.selectAll("p").selectAll(function() {
return [
this.previousElementSibling,
this.nextElementSibling
];
});
与 selection.select 不同,selection.selectAll 会影响分组:每个选定的后代元素都将按原始选择中的父元素分组。分组在 数据连接 中起着重要作用。有关此主题的更多信息,请参阅 嵌套选择 和 选择的工作原理。
selection.filter(filter)
源代码 · 过滤选择,返回一个新选择,其中只包含指定 filter 为 true 的元素。例如,要过滤一个表格行选择,使其只包含偶数行
const even = d3.selectAll("tr").filter(":nth-child(even)");
这与直接使用 d3.selectAll 相当,尽管索引可能不同
const even = d3.selectAll("tr:nth-child(even)");
filter 可以指定为选择器字符串或函数。如果 filter 是一个函数,则按顺序针对每个选定元素对其进行评估,并传递当前数据 (d)、当前索引 (i) 和当前组 (nodes),其中 this 为当前 DOM 元素 (nodes[i])。使用函数
const even = d3.selectAll("tr").filter((d, i) => i & 1);
或者使用 selection.select(并避免使用箭头函数,因为需要 this 来引用当前元素)
const even = d3.selectAll("tr").select(function(d, i) { return i & 1 ? this : null; });
请注意,:nth-child
伪类是基于一的索引,而不是基于零的索引。此外,上面的过滤函数的含义与 :nth-child
并不完全相同;它们依赖于选择索引,而不是 DOM 中的前面同级元素数量。
返回的过滤后的选择将保留该选择的父元素,但与 array.filter 类似,它不会保留索引,因为某些元素可能会被删除;如果需要,请使用 selection.select 来保留索引。
selection.selectChild(selector)
源代码 · 返回一个新的选择,其中包含当前选择中每个元素的(第一个)子元素,这些子元素与 selector 匹配。
d3.selectAll("p").selectChild("b") // the first <b> child of every <p>
如果未指定选择器,则选择第一个子元素(如果有)。如果选择器被指定为字符串,则选择第一个匹配的子元素(如果有)。如果选择器是一个函数,它将按顺序为每个子节点执行,并传递子元素 (child)、子元素的索引 (i) 以及子元素列表 (children);该方法将选择第一个返回真值的子元素(如果有)。
警告
selection.selectChild 将父元素的数据传播到选定的子元素。
selection.selectChildren(selector)
源代码 · 返回一个新的选择,其中包含当前选择中每个元素的子元素,这些子元素与选择器匹配。如果未指定选择器,则选择所有子元素。如果选择器被指定为字符串,则选择匹配的子元素(如果有)。如果选择器是一个函数,它将按顺序为每个子节点执行,并传递子元素 (child)、子元素的索引 (i) 以及子元素列表 (children);该方法将选择所有返回真值的子元素。
selection.selection()
源代码 · 返回选择(与 transition.selection 对称)。
matcher(selector)
源代码 · 给定指定的选择器,返回一个函数,如果this
元素 匹配 指定的选择器,则该函数返回 true。此方法在内部由 selection.filter 使用。例如,以下代码
const div = selection.filter("div");
等效于
const div = selection.filter(d3.matcher("div"));
(虽然 D3 不是兼容层,但此实现由于element.matches 的最新标准化而支持供应商前缀实现。)
selector(selector)
源代码 · 给定指定的选择器,返回一个函数,该函数返回this
元素的第一个匹配指定选择器的后代。此方法在内部由 selection.select 使用。例如,以下代码
const div = selection.select("div");
等效于
const div = selection.select(d3.selector("div"));
selectorAll(selector)
源代码 · 给定指定的选择器,返回一个函数,该函数返回this
元素的所有匹配指定选择器的后代。此方法在内部由 selection.selectAll 使用。例如,以下代码
const div = selection.selectAll("div");
等效于
const div = selection.selectAll(d3.selectorAll("div"));
window(node)
源代码 · 返回指定node 的所有者窗口。如果node 是一个节点,则返回所有者文档的默认视图;如果node 是一个文档,则返回其默认视图;否则返回node。
style(node, name)
源代码 · 返回指定node 的指定name 的样式属性的值。如果node 有一个具有指定name 的内联样式,则返回其值;否则返回 计算后的属性值。另请参阅 selection.style。