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

时间:2013-05-20 22:44:40

标签: html d3.js

我是d3的新手,我需要一些帮助来理解html元素重用。

这是一个小提琴:http://jsfiddle.net/m1erickson/qmEBE/

我在主体中放置了一个现有的段落元素:

<body>
        <p> Old Text.</p>
</body>

然后我定义了一个包含3个数字的数据集,并像这样执行.selectAll(“p”):

var dataset = [10,20,30];

d3.select("body").selectAll("p")
    .data(dataset)
    .enter()
    .append("p")
    .text( function(d){ return("#"+d); } ) ;

我明白了:

Old Text.
#20
#30

有两件事困扰着我:

为什么d3没有创建新的p-tag并显示#10?

当我查看预先存在的段落元素(“旧文本”)时,d3已分配d3数据属性== 10。如果d3捕获了这个p-tag,为什么不用它来显示数据呢?

d3如何决定在“更新选择”中包含哪些预先存在的网页元素?

到目前为止BTW-on d3:首先定义数据并遵循设计的想法让我感到宽慰。

[编辑:我有这个权利吗? ]

根据@ meetamit的信息性答案......

以下内容在元素

中创建更新选择
    elements =d3.select(“body”).selectAll(“p”).data(dataset) 

以下原因导致d3创建一个输入选择,其中为20和30创建了p标记。

    elements.enter() .append("p")

问题:

此时更新选择是否已与输入选择合并?

以下设置所有3个p标签中的文本,因为它们都在合并的更新选择中。

    elements.text(function(d){return("#"+d);});

问题:

由于d3将从网页捕获现有的p-tag等,通常的做法是将初始d3.select指向一个容纳d3结果的容器,如下所示:

    elements = d3.select(“#myD3Div”)    ….

1 个答案:

答案 0 :(得分:8)

当你调用data(dataset)并且页面上已有一个元素时,d3决定该元素与10 - 第一个数组元素的数据相关联。那是因为该元素是页面上的第0个<p>,因此它必须与数据集的第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

现在d3将在每种情况下比较d - 第0个元素为10,而预先存在的null<p> - 并且决定,因为它们不是等于,它需要在enter()返回的选择中包含第0个元素,然后为它附加一个元素。

此时,就d3而言,应删除预先存在的元素,它会在exit()选项中返回,因此您可以在其上调用remove()。< / p>

或者,根据您的目标,您可以保留data()调用单个参数,并更新其文本 - 而不是来自enter()选项,而是来自主, “更新”选择。 See this jsFiddle