D3.js - 数据加入

数据连接是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代码

d3.select("#list ").selectAll("li").data([10,20,30,25,15]);

现在,文档中有五个虚拟元素.前两个虚拟元素是文档中定义的两个 li 元素,如下所示.

1. li - 10
2. li - 20

我们可以使用所有选择器的元素修改方法,如 attr(),style(),text ()等,对于前两个 li ,如下所示.

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()方法,用于处理从数据集中动态删除的数据项,如图所示

d3.selectAll("li")
   .data([10, 20, 30, 15])
   .exit()
   .remove()

在这里,我们已经从数据集及其相应的li中删除了第四项exit()和remove()方法.

完整代码如下 :

<!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>

Data Join Methods

数据连接提供以下四种方法来处理数据集:

  • 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()
}

Data Function

在DOM操作章节中,我们了解了D3.js中的不同DOM操作方法,例如style(),text()等。这些函数中的每一个通常都以常量值作为参数。 然而,在Data join的上下文中,它将匿名函数作为参数。 此匿名函数获取相应的数据和使用data()方法分配的数据集的索引。 因此,将为绑定到DOM的每个数据值调用此匿名函数。 考虑以下text()函数。

.text(function(d, i) {
   return d;
});

在此函数中,我们可以应用任何逻辑来操纵数据。 这些是匿名函数,意味着没有与函数关联的名称。 除了data(d)和index(i)参数之外,我们可以使用此关键字访问当前对象,如下所示:

.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()函数为所选元素提供数据,在我们的例子中它是数据数组。