一个非常简单的 d3 数据连接将新元素添加到错误的位置

A very simple d3 data join adds the new elements in the wrong place

<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.4/d3.min.js" integrity="sha512-T+1zstV6Llwh/zH+uoc1rJ7Y8tf9N+DiC0T3aL0+0blupn5NkBT52Avsa0l+XBnftn/14EtxpsztAWsmiAaqfQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
    var data = {
        "Domains": [ "Domain 1", "Domain 2", "Domain 3" ]
    };
    d3.selectAll('#domains ul li')
        .data(data.Domains)
        .join("li")
        .text(function(d) {
            return d;
        });
</script>
</head>
<body>
<h2>Domains</h2>
<div id="domains"><ul></ul></div>
</body>

这是我的非常简单的代码。我期望它在 <ul> 元素内创建 <li> 元素,每个域一个。 但它在头部和 body 之间创建了它们! 结果 html(从 Chrome 检查员那里收集到的)是:

<html><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.4/d3.min.js" integrity="sha512-T+1zstV6Llwh/zH+uoc1rJ7Y8tf9N+DiC0T3aL0+0blupn5NkBT52Avsa0l+XBnftn/14EtxpsztAWsmiAaqfQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
    var data = {
        "Domains": [ "Domain 1", "Domain 2", "Domain 3" ]
    };
    d3.selectAll('#domains ul li')
        .data(data.Domains)
        .join("li")
        .text(function(d) {
            return d;
        });
</script>
</head><li>Domain 1</li><li>Domain 2</li><li>Domain 3</li>
<body>
<h2>Domains</h2>
<div id="domains"><ul></ul></div>

</body></html>

显然我在做一些愚蠢的事情 - 谁能指出它是什么?

然后我修改了我的脚本如下:

<script>
    var data = {
        "Domains": [ "Domain 1", "Domain 2", "Domain 3" ]
    };
    d3.select('#domains ul')
        .selectAll('li')
        .data(data.Domains)
        .join("li")
        .text(function(d) {
            return d;
        });
</script>

在这个实例中,没有 <li> 项目被添加到任何地方,甚至没有调用文本函数。

帮忙?

您 select 与 d3.selectAll 的内容与元素在 DOM 中的插入位置无关。你要用的是selection.selectAll

Joins and enter append elements to a parent:你没有指定一个parent,所以元素只是被输入到页面中,因为parent是文档本身默认情况下,如果使用 d3.selectAll.

而不是 select 你的 parent 元素,ul 然后使用那个 selection,做连接:这意味着任何输入的元素都将附加到parent 我们 select 编辑的元素, ul:

d3.select("#domains ul") // return a selection of a parent element
  .selectAll("li")       // select children we have or want to have
  .data(data.Domains)
  .join("li")            // enter/update/exit children li elements
  ...

通常您会看到 parent 的 selection 用变量保存的模式。

但我们还有一个问题,您的代码位于文档头部,它在文档的其余部分加载之前运行,因此您将无法 select ul。如果将脚本放在主体的末尾,则可以避免这种情况,或者您可以使用 document.ready 方法。这也是为什么要在头部和主体之间添加 li 元素的原因:append 添加内容作为最后一个 child,但是这些元素不能附加在主体之后,因为主体没有尚未加载

这是一个工作示例:

var data = {
        "Domains": [ "Domain 1", "Domain 2", "Domain 3" ]
    };
    
    let ul = d3.select("#domains ul");
    ul.selectAll("li")
      .data(data.Domains)
      .join("li")
      .text(function(d) {
          return d;
      });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<h2>Domains</h2>
<div id="domains"><ul></ul></div>