This is a simple page that demonstrates some basic functionality of d3. I made a dataset var dataset = [3,1,4,1,5]; and would like to output it as well as some paragraphs. The data is appearing, but after the body! Strange ...
<!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>
the page looks like this:
and the DOM looks like this (note the data shows up after the body close tag):
Also note that the line d3.select("p:nth-child(7n + 1)").append("text").text("hello againss?"); was intended to be printed after all my data, but it does not show up.
The short answer is that in your particular case the enter() selection's parentNode
is the document
(and not the body
).
Let's take a simple example to see what an enter() selection looks like. Assuming we have a document with a body without any p elements.
var ps = d3.select("body").selectAll("p")
.data([0, 1, 2]);
Since no p elements existed yet, the enter() selection will have three elements. Let's inspect the enter selection:
You see that the inner array has a property named parentNode. When you add new elements using selection.append() or selection.insert() the new elements will be created as children of that parentNode.
So, inspecting ps.enter()[0].parentNode
will reveal the body
element. It now becomes clear that, in a data join, the selection before the selectAll specifies the parentNode; in the above case that was d3.select("body")
.
What if we had omitted the select("body") part in the data join?
// example of bad data join
var ps2 = d3.selectAll("p")
.data([0, 1, 2]);
It turns out that in this case ps2.enter()[0].parentNode
is the #document
! That means that if you add elements using this enter() selection, they will become the document's direct children. The append method will add them to the end of the document; i.e. after the body.
The last case is basically what you've encountered. Your data join and enter expression is not correct; it should follow this pattern:
d3.select(parent).selectAll(element)
.data(data)
.enter().append(element);
BTW, there is no HTML text
element. So, append("text")
doesn't seem meaningful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With