[英]Why does this D3 code add the <p> element outside the body, instead of inside it?
I'm learning D3 and have come across an issue using the select operator. 我正在学习D3并且使用select运算符遇到了一个问题。
Specifically, why does the following code add the <p>
element outside the body, instead of inside it? 具体来说,为什么以下代码将
<p>
元素添加到正文之外,而不是在其中?
var pData1 = d3.select("body").select("p").data([1]).enter().append("p");
I am using a totally blank HTML file with just <head>
and <body>
tags to test. 我正在使用一个完全空白的HTML文件,只需
<head>
和<body>
标签进行测试。
<html lang="en">
<head>
<title><!-- Insert your title here --></title>
<script type="text/javascript" src="d3.min.js"></script>
</head>
<body>
</body>
</html>
(This repeats the content from Lars Kotthoff's answer, but I'd spent time creating the demo so I thought I'd still post.) (这重复了Lars Kotthoff的回答中的内容,但我花时间创建了演示,所以我想我还会发帖。)
The problem is that select
, unlike selectAll
, does not re-define the parent element for elements added in the enter()
selection. 问题是,与
selectAll
不同, select
不会为enter()
选择中添加的元素重新定义父元素。
d3.select("body").select("p#a")
.data([1])
.enter().append("p").attr("id", "a")
.text("This paragraph is appended to <html> (the document root)
because no selectAll statement reset the parent element.");
d3.selectAll("p#b")
.data([1])
.enter().append("p").attr("id", "b")
.text("This paragraph is appended to <html>
because the selectAll statement is called directly on the root.");
d3.selectAll("body").select("p#c")
.data([1])
.enter().append("p").attr("id", "c")
.text("This paragraph is also appended to <html>
because the last selectAll statement was called directly from the root.");
d3.select("body").selectAll("p#d")
.data([1])
.enter().append("p").attr("id", "d")
.text("This paragraph is appended to <body>
because the selectAll statement is a sub-selection of the body selection.");
d3.selectAll("body").selectAll("p#e")
.data([1])
.enter().append("p").attr("id", "e")
.text("This paragraph is also appended to <body>
because the final selectAll statement is a sub-selection of the body.");
http://fiddle.jshell.net/eLF4H/ http://fiddle.jshell.net/eLF4H/
It is unusual to use an enter chain after a select
statement (versus selectAll), because usually you are selecting multiple elements if you are going to do a data join. 在
select
语句之后使用输入链是不常见的(与selectAll相比),因为如果要进行数据连接,通常会选择多个元素。 However, if you want to create the element if it doesn't exist or update it if it does , you have two options: 但是, 如果要创建元素(如果它不存在)或者更新它,则有两个选项:
use a selectAll statement followed by the data join 使用selectAll语句后跟数据连接
var pdata1 = d3.select("body").selectAll("p#data") //select element if it exists .data([dataObject]); //join to the current data pdata1.enter().append("p").attr("id", "data"); //create element if required pdata1.text(function(d){return d.textValue;}); //set or update the element based on the data
use an if statement to create the element if necessary and use .datum()
to bind the data 如果需要,使用if语句创建元素,并使用
.datum()
绑定数据
var pdata1 = d3.select("p#data") //select element if it exists if ( pdata1.empty() ) { pdata1 = d3.select("body").append("p").attr("id", "data"); //create element if required } pdata1.datum(dataObject) //note that you don't need to put the data into an array .text(function(d){return d.textValue;}); //set or update the element based on the data
As suggested in the comments, the way to do what you're trying to do is to use .selectAll()
. 正如评论中所建议的那样,你要做的就是使用
.selectAll()
。 The difference between .select()
and .selectAll()
is that .select()
returns elements while .selectAll()
returns elements grouped by ancestor . 之间的差
.select()
和.selectAll()
是.select()
返回元件,同时.selectAll()
返回由祖先分组元素 。 This then affects any subsequent .data()
operations in terms of what the elements are appended to. 然后,这将根据元素的附加内容影响任何后续的
.data()
操作。 From the documentation : 从文档 :
Grouping by selectAll also affects subsequent entering placeholder nodes.
selectAll分组也会影响后续进入的占位符节点。 Thus, to specify the parent node when appending entering nodes, use select followed by selectAll:
因此,要在添加进入节点时指定父节点,请使用select后跟selectAll:
d3.select("body").selectAll("div")
d3.select( “身体”)。全选( “分区”)
there is no p element to select, so I would suggest appending the p element before entering your data: 没有p元素可供选择,所以我建议在输入数据之前附加p元素:
var pData1 = d3.select("body").append("p")
pData1.data([1])...
do whatever else you need to do after .data, although there is no need to append another p 做任何你需要做的事情.data,虽然没有必要追加另一个p
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.