这是一个简单的页面,演示了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看起来像这样(注意数据显示在主体关闭标记之后):
还要注意行d3.select(“p:nth-child(7n + 1)”)。append(“text”)。text(“hello againss?”);打算在我的所有数据之后打印,但它没有显示出来。
答案 0 :(得分:8)
简短的回答是,在您的特定情况下,enter()选择的parentNode
是document
(而不是body
)。
让我们举一个简单的例子来看看enter()选择是什么样的。假设我们有一个没有任何p元素的文档。
var ps = d3.select("body").selectAll("p")
.data([0, 1, 2]);
由于还没有p元素,因此enter()选择将包含三个元素。让我们检查输入选择:
您会看到内部数组有一个名为parentNode的属性。使用selection.append()或selection.insert()添加新元素时,新元素将作为该parentNode的子元素创建。
因此,检查ps.enter()[0].parentNode
将显示body
元素。现在很清楚,在数据连接中,selectAll之前的选择指定了parentNode;在上述情况下是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);
顺便说一句,没有HTML text
元素。因此,append("text")
似乎没有意义。