【问题标题】:A d3.select... equivalent to jQuery.children()一个 d3.select... 相当于 jQuery.children()
【发布时间】:2013-11-26 05:17:58
【问题描述】:

我正在使用 d3 在 enter() 上附加一些元素,然后稍后更新它们。但是,下次我尝试选择这些元素时,选择比原来的要大得多。这是因为原始选择元素现在具有相同类型的子元素,例如; <g><svg>。我希望 selectAll() 只能在像 jQuery.children() 这样的第一个死者级别上工作,在 d3 中是否有等价物?如果不是,那么最有效的方法是什么?

【问题讨论】:

    标签: javascript jquery d3.js


    【解决方案1】:

    没有与jQuery.children() 等价的东西。这通常通过为要一起选择的元素分配一个区分类来处理,例如像这样的。

    svg.selectAll("g").data(data)
       .enter()
       .append("g")
       .attr("class", "parent")
       .append("g")
       .attr("class", "child");
    
    svg.selectAll("g"); // all g elements
    svg.selectAll("g.parent"); // only parents
    svg.selectAll("g.child"); // only children
    

    【讨论】:

    • 谢谢,我最终使用该方法来标记我正在寻找的节点。就性能而言,执行另一个选择与 d3.select(_.filter(svg.parent().node().children, function (el) { return el.nodeName == 'g';}) 相比如何)?在我的情况下,我可以在 DOM 中有 10k + 个节点,所以我有点选择偏执......
    • D3 使用通常的 DOM 选择器,所以不应该有太多的开销。在您的情况下,最好明确指定要选择的节点,但是在两种方法之间切换和分析它们不应该太繁重。
    • 如果我们想访问this 的孩子怎么办? d3.select(this.some_class) 会起作用吗?
    • 只需添加另一个.select() -- d3.select(this).select(child)
    【解决方案2】:

    这是一个更好的方法:

    var parent = d3.selectAll(".myParentClass");
    parent.each(function(d,i) {            
       var children = d3.selectAll(this.childNodes);
       console.log(children);
    });
    

    这样您就不需要向可能有 100 个(甚至更多)的子节点添加不必要的类。

    【讨论】:

    • 简单且按预期工作,这与其他答案一样有效。
    【解决方案3】:

    您也可以仅使用 CSS 选择器来选择子级。这里我正在做什么从索引中选择孩子:

    d3.select(`#${parentId} > *:nth-child(${index + 1})`)
    

    所以我想这可行:

    d3.selectAll(`#${parentId} > *`)
    

    【讨论】:

      【解决方案4】:

      迟到了,但至少在d3 版本 4 中,selection.selectAll() 可以采用一个函数,其结果是一个数组,其中包含要根据先前选择中的选定元素选择的新元素:

      var parent = d3.selectAll(".myParentClass");
      var children = parent
          //Convert selection to selection representing the children
          .selectAll(function() { return this.childNodes; })
          //Apply filter to children
          .filter('g')
          ;
      

      与之前的答案相比,这种方法的主要好处是 selection.data() 函数仍然可以正常工作。先前提出的方法(从新的单独的 d3.select() 调用分配结果)不允许这样做。

      【讨论】:

        【解决方案5】:

        就像 Lars 所说,在 D3 中没有等效于 'children()' 的方法,但这里对我编写的 d3.selection 原型进行了一点扩展。我希望对你有帮助(这么晚了)。

        d3.selection.prototype.children = function(d){
            var that = this.node();
            return this
                .selectAll(d)
                .filter(function(){ return that == this.parentNode; });
        };
        

        【讨论】:

          猜你喜欢
          • 2021-09-24
          • 1970-01-01
          • 2012-10-10
          • 2018-08-10
          • 2017-01-16
          • 2011-07-11
          • 2011-05-14
          • 2022-11-01
          • 2012-03-16
          相关资源
          最近更新 更多