D3.js 使用selection.select防止不需要的数据继承

D3.js 使用selection.select防止不需要的数据继承,d3.js,D3.js,在d3中,selection.select具有从原始选择中的父节点继承数据的副作用。在父节点和子节点之间共享数据的情况下,这是可取的,这样绑定到父节点的更新数据将被推送到子节点,而不需要在每个级别进行数据联接 但是,如果绑定到父级的数据与绑定到子级的数据之间没有明确的关系,那么情况又如何呢?在这种情况下,selection.select可能是隐蔽的,因为只要选择一个节点,就会导致该节点的数据与不相关的父数据发生冲突 避免这种情况的最佳方法是什么?我可以想出几个选择,但两个都不太好: 始终使用选择

在d3中,
selection.select
具有从原始选择中的父节点继承数据的副作用。在父节点和子节点之间共享数据的情况下,这是可取的,这样绑定到父节点的更新数据将被推送到子节点,而不需要在每个级别进行数据联接

但是,如果绑定到父级的数据与绑定到子级的数据之间没有明确的关系,那么情况又如何呢?在这种情况下,
selection.select
可能是隐蔽的,因为只要选择一个节点,就会导致该节点的数据与不相关的父数据发生冲突

避免这种情况的最佳方法是什么?我可以想出几个选择,但两个都不太好:

  • 始终使用
    选择。除需要隐式数据继承的情况外,在任何地方选择All
    。但是,这并不理想,因为它使用了
    选择。选择
    d3不一致。选择
    ,它仅用于选择单个节点(这正是我想对
    选择执行的操作。选择

  • 使用
    d3。选择带有而不是
    选项的
    。选择
    以隔离特定节点。使用
    selection.select
    最方便的一点是,它隐式地将选择限制为起始选择的后代。用选择器实现这一点并不是那么好

  • 就我个人而言,我不太喜欢在API中一些最常用函数的特定形式中使用DOM状态修改副作用。我想如果有一个明确的调用,比如
    selection.update(selector)
    selection.append
    selection.insert
    对称,我会发现更容易理解


    但是在当前的API中,我想知道在使用
    选择时是否有其他机制可以有效地中断继承。选择

    我确实在D3 Github上提交了一个问题:。没有任何解决方案,但(我认为)对这个问题进行了有趣的讨论。在最底层,Mike确实提供了一个可行的解决方案,为了方便起见,我将其粘贴在这里:

    这不是一个很好的答案,但防止数据继承的一种方法是使用一个没有绑定数据的中间节点

    var intermediary = selection.append("div")
        .datum(function() { return null; });
    
    然后,来自中介的任何选择都不会传播来自父选择的数据。但当然,DOM中的中间节点有些不幸

    您可以使用:

    d3.select(selection.node().querySelector(selector))
    

    在这篇文章中可以看到,它使用selectWithoutDataPropagation()方法扩展了选择原型。

    可能需要提出一些问题,我同意这可能会有问题。我正在使用d3绘制包含嵌套svg元素的复杂图形,每当我想要选择某个元素的子元素时,我都会使用某个元素。select()并且绑定到子元素的数据会丢失!!我花了一段时间才弄明白问题出在哪里。。。虽然我不能说这种隐式功能在某些情况下可能很方便,但在其他情况下它也会导致不必要的结果。如果您能选择禁用此默认行为,我们将不胜感激。使用
    .datum([])
    剥离数据的子选择是否会有所帮助?我不确定我的想法是否正确。