d3更新选择:d3如何决定捕获哪些现有的html元素供自己使用?

mar*_*rkE 3 html d3.js

我是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)

mee*_*mit 8

当你调用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.