我是d3的新手,我需要一些帮助来理解html元素的重用.
这是一个小提琴:http: //jsfiddle.net/m1erickson/qmEBE/
我在主体中放置了一个现有的段落元素:
<body>
<p> Old Text.</p>
</body>
Run Code Online (Sandbox Code Playgroud)
然后我定义了一个3个数字的数据集,并像这样做一个.selectAll("p"):
var dataset = [10,20,30];
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text( function(d){ return("#"+d); } ) ;
Run Code Online (Sandbox Code Playgroud)
我明白了:
Old Text.
#20
#30
Run Code Online (Sandbox Code Playgroud)
有两件事困扰着我:
为什么d3没有创建新的p-tag并显示#10?
当我查看预先存在的段落元素("旧文本")时,d3已分配d3数据属性== 10.如果d3捕获了这个p-tag,为什么不用它来显示数据呢?
d3如何决定在"更新选择"中包含哪些预先存在的网页元素?
到目前为止BTW-on d3:首先定义数据并遵循设计的想法让我感到自由.
[编辑:我有这个权利吗?]
基于来自@ meetamit的信息性答案......
以下内容在元素内创建更新选择
elements =d3.select(“body”).selectAll(“p”).data(dataset)
Run Code Online (Sandbox Code Playgroud)
以下原因导致d3创建一个输入选择,其中为20和30创建了p标签.
elements.enter() .append("p")
Run Code Online (Sandbox Code Playgroud)
题:
此时更新选择是否已与输入选择合并?
以下设置了所有3个p标签中的文本,因为它们都在合并的更新选择中.
elements.text(function(d){return("#"+d);});
Run Code Online (Sandbox Code Playgroud)
题:
由于d3将从网页捕获现有的p-tag等,通常的做法是将初始d3.select指向一个容纳d3结果的容器,如下所示:
elements = d3.select(“#myD3Div”) ….
Run Code Online (Sandbox Code Playgroud)
当你调用data(dataset)并且页面上已有一个元素时,d3决定将该元素与10- 第一个数组元素的数据相关联.那是因为该元素是<p>页面上的第0个元素,因此它必须与数据集的第0个元素相关联.换句话说,它是根据数组中的索引确定持久性.结果,函数不10返回预先存在的元素和与该值相关联的将要元素enter(),因为它们不被认为是新元素,只是替换与现有元素相关联的数据.
如果您希望它根据实际数据确定持久性,则必须将第二个参数传递给data()函数:
data(dataset, function(d, i) { return d; })
// NOTE: "return i;" would have the same effect as not passing in the 2nd param
Run Code Online (Sandbox Code Playgroud)
现在d3将d在每种情况下进行比较- 对于第0个元素是10并且null对于预先存在的<p>- 并且由于它们不相等而决定它需要在返回的选择中包括第0个元素enter(),这将是反过来为它添加一个元素.
此时,就d3而言,应该删除预先存在的元素,它将在exit()选择中返回它,因此您可以调用remove()它.
或者,根据您的目标,您可以保持data()呼叫单参数,并更新其文本 - 不是来自enter()选择,而是来自主要的"更新"选择.看到这个jsFiddle.