如果我追加的内容似乎只依赖于.append()调用,那么在数据连接期间我将哪个项传递给d3.selectAll()有关系

Does it matter which term I pass to d3.selectAll() during a data join, if whatever I append seems to rely solely on the .append() call?

本文关键字:连接 selectAll 有关系 d3 数据 追加 依赖于 如果 调用 append      更新时间:2023-09-26

我在d3图表中添加了一些圆圈,并且对传递给svg.selectAll()的参数有些困惑。在这里,我对我的数据和一些圆圈运行一个数据连接:

svg.selectAll("top")
    .data(data)
    .enter()
    .append("circle")
    .attr({
        "cx": function(d,i){return i*50+50},
        "cy": 60,
        "r": function(d) {return rScale(parseFloat(d.value));},
        "class": "top"
    })
    .style({
        "fill": "CornflowerBlue",
        "stroke": "blue",
        "opacity": 0.8
    });

这段代码似乎是,从我玩它,相同的:

    svg.selectAll("circle")
        .data(data)
        .enter()
        .append("circle")
        .attr({
            "cx": function(d,i){return i*50+50},
            "cy": 60,
            "r": function(d) {return rScale(parseFloat(d.value));},
            "class": "top"
        })
        .style({
            "fill": "CornflowerBlue",
            "stroke": "blue",
            "opacity": 0.8
        });

为了节省你寻找两个代码块之间的一个区别的麻烦,它是selectAll("top") vs. selectAll("circle")

每当我检查示例时,我几乎总是看到选择和附加元素之间的匹配,但这似乎无关紧要,至少在我运行上面的代码时不是这样。起初,我认为也许你可以使用的东西沿着类选择和附加元素到它(svg.selectAll(".top")),但这也不起作用。那么d3.selectAll()参数的基本用途是什么呢?

TLDR:是的,这很重要——总是选择要添加的元素。

更长的解释:文档清楚地说明了参数的目的:

选择与指定选择器匹配的所有元素。

你给selectAll()的参数决定了你操作的选择结果。例如,如果选择d3.selectAll("circle"),则所选内容将包含页面上的所有circle元素。请注意,如果没有这样的元素,则选择将为空(这通常是您最初创建可视化时的情况)。

你是对的,在你的情况下,传递什么参数并不重要。这是因为页面上没有元素,无论选择器字符串如何,选择项都是空的。但是,当页面上有您可能想要更新的元素时,这就很重要了。选择的内容决定D3的数据绑定做什么,特别是什么数据绑定到什么元素,哪些元素被确定为"新"(进入选择),"更新"(更新选择),和"旧"(退出选择)(更多关于这个教程)。

简而言之,如果您选择了错误的元素,那么您期望更新的元素将不会被更新,而其他元素将在不应该更新的时候出现。成像选择top, circle元素存在。该选区将为空,因此将为每个数据添加额外的圆圈,即使您实际上想要更新现有的圆圈。

好吧,如果你只是想用输入选项来添加新元素,而不打算更新它们,为什么要关心这个呢?首先,它使您的代码更容易阅读和理解。其次,更重要的是,当您(或其他人)后来决定终究要更新现有元素时,它避免了微妙的错误。

在注释后编辑:如果需要区分相同元素的多个集合,请使用classes:

 d3.selectAll("circle.top").data(top)
   .enter().append("circle").classed("top", true);
 d3.selectAll("circle.bottom").data(bottom)
   .enter().append("circle").classed("bottom", true);

enter()如何处理初始创建的根本原因与所谓的数据连接或进入-更新-退出模式有关。这里有一个链接:http://bost.ocks.org/mike/join/