Skip to content

D3.js - 选择集 API

选择集(Selections)是 D3.js 的基石,允许你选择 DOM 元素并应用数据驱动的转换。通过选择集,你可以设置属性(attributes)、样式(styles)、属性(properties)、HTML 内容(HTML content)或文本内容(text content),并管理数据绑定(data joins)。本章深入探讨 D3 选择集 API。

选择集 API 是 D3 核心库的一部分。你可以通过引入完整的 D3 包或独立的 d3-selection 模块来使用它。

<!-- 选项 1:引入完整的 D3 库 -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<!-- 选项 2:引入独立的 d3-selection 模块 -->
<!-- <script src="https://d3js.org/d3-selection.v3.min.js"></script> -->
<script>
// 示例用法:
// const bodySelection = d3.select("body"); // 选择 body
// const allParagraphs = d3.selectAll("p"); // 选择所有 p 元素
</script>

以下是 D3 选择集 API 中一些最基础的方法:

  • d3.select(selectorOrNode) − 选择匹配 CSS selector 字符串的第一个 DOM 元素。如果 selectorOrNode 是一个节点(node),它将该节点封装成一个选择集。
  • d3.selectAll(selectorOrNodes) − 选择匹配 CSS selector 字符串的所有 DOM 元素。如果 selectorOrNodes 是一个节点数组,它将这些节点封装成一个选择集。
  • selection.select(selector) − 对于每个被选中的元素,选择与之匹配指定 selector 的第一个后代元素(descendant element)。
  • selection.selectAll(selector) − 对于每个被选中的元素,选择与之匹配指定 selector 的所有后代元素。这是实现子选择集(sub-selections)和嵌套结构(nested structures)的关键。
  • selection.data([data[, keyFunction]]) − 将指定的数据(data)数组与选中的元素绑定。可选的 keyFunction 控制数据如何与元素匹配。(数据绑定)
  • selection.join(enter[, update][, exit]) − 一个强大的方法(在 D3 v5 中引入),用于简洁地处理进入选择集(enter)、更新选择集(update)和退出选择集(exit)。enter 是一个函数或选择器字符串,用于处理新增数据点对应的元素;update 用于处理已存在元素;exit 用于处理需要被移除的元素。
  • selection.enter() − 返回进入选择集:那些有对应数据元素但没有对应 DOM 元素的占位节点(placeholder nodes)。
  • selection.exit() − 返回退出选择集:那些没有对应数据元素的 DOM 元素。
  • selection.append(type) − 将指定 type 类型(例如,“div”、“svg:circle”)的新元素作为每个选中元素的最后一个子元素附加进去。通常与进入选择集一起使用。
  • selection.remove() − 从文档中移除选中的元素。通常与退出选择集一起使用。
  • selection.attr(name, value) − 设置属性 name 的值为指定的 value。如果 value 是一个函数,它将对每个元素进行评估。
  • selection.style(name, value[, priority]) − 设置样式属性 name 的值为 value。如果 value 是一个函数,它将对每个元素进行评估。
  • selection.text(value) − 设置文本内容。如果 value 是一个函数,它将对每个元素进行评估。
  • selection.html(value) − 设置内部 HTML 内容。如果 value 是一个函数,它将对每个元素进行评估。
  • selection.each(function) − 为每个选中的元素调用指定的 function,并传入参数 (d, i, nodes),其中 d 是数据项(datum),i 是索引(index),nodes[i] 是当前元素。
  • selection.call(function[, arguments…]) − 调用指定的 function 一次,并将选择集本身作为第一个参数传入,后面跟着可选的参数。
  • selection.filter(filter) − 过滤选择集,返回一个新的选择集,其中只包含那些符合 filter 条件(选择器字符串或函数返回 true)的元素。
  • selection.merge(otherSelection) − 将当前选择集与另一个选择集合并。如果未使用 join(),这对于合并进入选择集和更新选择集非常有用。
  • d3.local() − 创建一个新的本地变量作用域(local variable scope),允许你在 DOM 节点上独立于数据设置和获取值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3.js Selection Example</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.important { color: red; font-weight: bold; }
</style>
</head>
<body>
<p>This is a normal paragraph.</p>
<p class="info">This paragraph has a class.</p>
<div><p>A nested paragraph.</p></div>
<script>
// 选择 body
const body = d3.select("body");
// 选择第一个 p 元素并修改其文本
d3.select("p").text("This first paragraph was changed by D3!");
// 选择所有 p 元素并添加一个类
d3.selectAll("p").classed("important", true);
// 按类名选择特定 p 元素并修改其样式
d3.select(".info").style("background-color", "yellow");
// 附加一个新的 p 元素
body.append("p").text("This is a newly appended paragraph.");
</script>
</body>
</html>

使用 selection.join() 实现 Enter-Update-Exit 模式

Section titled “使用 selection.join() 实现 Enter-Update-Exit 模式”

基于数据管理元素是 D3 的核心模式之一。selection.join() 简化了这一过程:

const data = [10, 20, 30, 40];
// Select a container and bind data
const circles = d3.select("svg")
.selectAll("circle")
.data(data);
// Use join() to handle enter, update, exit
circles.join(
enter => enter.append("circle") // 对于新增数据点,附加一个 circle
.attr("cy", 50)
.attr("r", d => d / 2)
.attr("cx", (d, i) => (i + 1) * 50)
.style("fill", "steelblue"),
update => update.style("fill", "green"), // 对于已存在元素,修改填充颜色
exit => exit.remove() // 对于数据中不再存在的元素,移除它们
);

如果你只需要处理进入选择集,可以直接传入 enter 函数或选择器字符串:selection.join("circle").attr(...),这等同于 selection.join(enter => enter.append("circle"))。

选择集几乎用于所有 D3.js 操作中:

  • 创建和更新图表元素(条形、圆形、线条)。
  • 将数据绑定到 DOM。
  • 动态应用样式和属性。
  • 通过为选择集附加事件监听器来处理用户交互。
  • 构建复杂的、数据驱动的文档。

理解选择集对于掌握 D3 至关重要。有关更多示例和详细解释,请查阅 d3-selection 文档 和 Mike Bostock 的经典文章 “选择集的工作原理”。