5

这是一个简单的页面,展示了 d3 的一些基本功能。我做了一个数据集 var dataset = [3,1,4,1,5]; 并想输出它以及一些段落。数据是出现的,但身体之后!奇怪的 ...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title> demo project</title>
    <script type="text/javascript" src="d3/d3.v2.js"></script>
</head>
<body>

    <script type="text/javascript">
        d3.select("body").append("p").text("hello!");
        d3.select("p").append("text").text(" hello!!");
        d3.select("body").append("p").text("hello2!");
        d3.select("p:nth-child(3)").append("text").text(" hello2!!");
        var dataset = [3,1,4,1,5];
        d3.select("p:nth-child(3n+1)")
            .data(dataset)
            .enter()
            .append("p")
            .text(function(d) { return d; });
        d3.select("p:nth-child(7n + 1)").append("text").text("hello againss?");
    </script>

</body>
</html>

页面如下所示:

在此处输入图像描述

DOM 看起来像这样(注意数据显示body 关闭标记之后):

在此处输入图像描述

还要注意行 d3.select("p:nth-child(7n + 1)").append("text").text("hello againstss?"); 打算在我的所有数据之后打印,但它没有显示出来。

4

1 回答 1

8

简短的回答是,在您的特定情况下, enter() 选择parentNodedocument(而不是body)。

让我们举一个简单的例子来看看 enter() 选择是什么样子的。假设我们有一个正文没有任何 p 元素的文档。

var ps = d3.select("body").selectAll("p")
    .data([0, 1, 2]);

由于尚不存在 p 个元素,因此 enter() 选择将包含三个元素。让我们检查输入选择:

ps.enter()

您会看到内部数组有一个名为 parentNode 的属性。当您使用selection.append()selection.insert()添加新元素时,新元素将被创建为该父节点的子节点。

因此,检查ps.enter()[0].parentNode将揭示body元素。现在很清楚,在数据连接中,selectAll 之前的选择指定了父节点;在上述情况下是d3.select("body")

如果我们在数据连接中省略了 select("body") 部分会怎样?

// example of bad data join
var ps2 = d3.selectAll("p")
    .data([0, 1, 2]);

事实证明,在这种情况下ps2.enter()[0].parentNode#document!这意味着如果您使用此 enter() 选择添加元素,它们将成为文档的直接子元素。append 方法会将它们添加到文档的末尾;即在身体之后。

最后一种情况基本上就是你遇到的情况。您的数据连接和输入表达式不正确;它应该遵循这种模式:

d3.select(parent).selectAll(element)
    .data(data)
  .enter().append(element);

顺便说一句,没有 HTMLtext元素。所以,append("text")似乎没什么意义。

于 2012-12-10T07:08:04.260 回答