Data Join
数据连接是D3.js中的另一个重要概念。 它与选择一起使用,使我们能够根据我们的数据集(一系列数值)操作HTML文档。 默认情况下,D3.js在其方法中为数据集提供最高优先级,并且数据集中的每个项对应于HTML元素。 本章详细介绍了数据连接。
什么是数据加入?
数据连接使我们能够根据现有HTML文档中的数据集注入,修改和删除元素(HTML元素以及嵌入的SVG元素)。 默认情况下,数据集中的每个数据项对应于文档中的元素(图形)。
随着数据集的变化,也可以轻松地操作相应的元素。 数据连接在我们的数据和文档的图形元素之间创建了一种紧密的关系。 数据连接使得基于数据集的元素操作变得非常简单和容易。
数据加入如何工作?
数据连接的主要目的是使用给定的数据集映射现有文档的元素。 它根据给定的数据集创建文档的虚拟表示,并提供使用虚拟表示的方法。 让我们考虑一个简单的数据集,如下所示。
[10, 20, 30, 25, 15]
数据集有五个项目,因此可以映射到文档的五个元素。 让我们使用选择器的selectAll()方法和数据连接的data()方法将它映射到以下文档的li元素。
HTML
<ul id = "list">
<li><li>
<li></li>
</ul>
D3.js code
d3.select("#list").selectAll("li").data([10, 20, 30, 25, 15]);
现在,文档中有五个虚拟元素。 前两个虚拟元素是文档中定义的两个li元素,如下所示。
1. li - 10
2. li - 20
对于前两个li ,我们可以使用所有选择器的元素修改方法,如attr(), style(), text()等,如下所示。
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d) { return d; });
text()方法中的函数用于获取li元素映射数据。 这里, d表示第一个li元素为10,第二个li元素为20。
接下来的三个元素可以映射到任何元素,可以使用数据连接的enter()和selector的append()方法完成。 enter()方法提供对剩余数据的访问(未映射到现有元素),append()方法用于从相应数据创建新元素。 让我们为剩余的数据项创建li 。 数据图如下 -
3. li - 30
4. li - 25
5. li - 15
创建新的li元素的代码如下 -
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d) { return "This is pre-existing element and the value is " + d; })
.enter()
.append("li")
.text(function(d)
{ return "This is dynamically created element and the value is " + d; });
数据连接提供了另一种称为exit() method用于处理从数据集中动态删除的数据项,如下所示。
d3.selectAll("li")
.data([10, 20, 30, 15])
.exit()
.remove()
在这里,我们使用exit()和remove()方法从数据集及其对应的li中删除了第四项。
完整的代码如下 -
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<ul id = "list">
<li></li>
<li></li>
</ul>
<input type = "button" name = "remove" value = "Remove fourth value"
onclick = "javascript:remove()" />
<script>
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d)
{ return "This is pre-existing element and the value is " + d; })
.enter()
.append("li")
.text(function(d)
{ return "This is dynamically created element and the value is " + d; });
function remove() {
d3.selectAll("li")
.data([10, 20, 30, 15])
.exit()
.remove()
}
</script>
</body>
</html>
上述代码的结果如下 -
<!--Fourth item removed
-->数据连接方法
数据连接提供以下四种方法来处理数据集 -
- datum()
- data()
- enter()
- exit()
让我们详细介绍这些方法。
The datum() Method
datum()方法用于为HTML文档中的单个元素设置值。 一旦使用选择器选择元素,就会使用它。 例如,我们可以使用select()方法选择现有元素(p标签),然后使用datum()方法设置数据。 设置数据后,我们可以更改所选元素的文本或添加新元素,并使用datum()方法设置的数据分配文本。
创建页面“datajoin_datum.html”并添加以下代码 -
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<p></p>
<div></div>
<script>
d3.select("p")
.datum(50)
.text(function(d) {
return "Used existing paragraph element and the data " + d + " is assigned.";
});
d3.select("div")
.datum(100)
.append("p")
.text(function(d) {
return "Created new paragraph element and the data " + d + " is assigned.";
});
</script>
</body>
</html>
上述代码的输出如下。
The data() method
data()方法用于将数据集分配给HTML文档中的元素集合。 使用选择器选择HTML元素后使用它。 在我们的列表示例中,我们使用它来设置li选择器的数据集。
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15]);
The enter() method
enter()方法输出之前没有图形元素的数据项集。 在我们的列表示例中,我们使用它来创建新的li元素。
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d) { return "This is pre-existing element and the value is " + d; })
.enter()
.append("li")
.text(function(d) { return "This is dynamically created element and the value is " + d; });
The exit() method
exit()方法输出不再存在数据的图形元素集。 在我们的列表示例中,我们使用它通过删除数据集中的数据项来动态删除其中一个li元素。
function remove() {
d3.selectAll("li")
.data([10, 20, 30, 15])
.exit()
.remove()
}
数据功能
在DOM操作章节中,我们了解了D3.js中的不同DOM操作方法,例如style(), text()等。这些函数中的每一个通常都以常量值作为参数。 然而,在Data join的上下文中,它将匿名函数作为参数。 此匿名函数获取相应的数据和使用data()方法分配的数据集的索引。 因此,将为绑定到DOM的每个数据值调用此匿名函数。 考虑以下text()函数。
.text(function(d, i) {
return d;
});
在此函数中,我们可以应用任何逻辑来操作数据。 这些是匿名函数,意味着没有与函数关联的名称。 除了data(d)和index(i)参数之外,我们可以使用this关键字访问当前对象,如下所示 -
.text(function (d, i) {
console.log(d); // the data element
console.log(i); // the index element
console.log(this); // the current DOM object
return d;
});
请考虑以下示例。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<p></p>
<p></p>
<p></p>
<script>
var data = [1, 2, 3];
var paragraph = d3.select("body")
.selectAll("p")
.data(data)
.text(function (d, i) {
console.log("d: " + d);
console.log("i: " + i);
console.log("this: " + this);
return "The index is " + i + " and the data is " + d;
});
</script>
</body>
</html>
上面的脚本将生成以下结果 -
在上面的例子中,参数“d”为您提供数据元素,“i”为您提供数组中的数据索引,“this”是当前DOM元素的引用。 在这种情况下,它是段落元素。 请注意,我们在上面调用了.data(数据)函数。 data()函数为所选元素提供数据,在我们的例子中它是数据数组。