代码之家  ›  专栏  ›  技术社区  ›  Bmil

将所选内容与组合并

  •  1
  • Bmil  · 技术社区  · 6 年前

    我已经为使用新的选择合并制定了一个一致的模式,这对于数据和/或比例可能发生变化的可重用图表来说是非常好的。

    我也成功地使用了这个键函数。

    但是,在输入和附加包含多个元素的组时,我似乎遇到了一个问题。已成功更新组中的数据,但未更新附加的元素。

    我已经通过添加一个补丁(见下文)解决了这个问题,但我确信这是一个非常明显的问题,需要进行更改才能解决。

    有什么想法吗?

    //define data group 
    var my_group = svg.selectAll(".data_group")
                      .data(my_data,function(d){return d.id});
    
    //enter new groups
    var enter = my_group.enter()
                        .append("g")
                        .attr("class","data_group");
    
    //append items to group
    enter.append("text").attr("class","group_item group_text")
    enter.append("circle").attr("class","group_item group_circle");
    
    //merge and remove
    my_group.merge(enter);
    my_group.exit().remove();
    
    //fix added to reset changing data for bars.
    d3.selectAll(".group_item").each(function(d){
      d3.select(this)._groups[0][0].__data__ = d3.select(this)._groups[0][0].parentElement.__data__;
    });
    
    d3.selectAll(".group_text")
      .... add properties to text - ie x,y,fill,text-anchor,text 
    
    d3.selectAll(".group_circle")
         .... add properties to circle - ie cx,cy,fill,stroke,radius
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   Gerardo Furtado    4 年前

    事情很简单:“enter”选择中的子元素有新的数据。您只需要使用父级的选择(与 select() )传播它们。

    someProperty . 你会看到的,用你的 each() ,仅更改“enter”选项中的子元素:

    var svg = d3.select("svg");
    d3.interval(function() {
      var data = d3.range(1 + ~~(Math.random() * 4)).map(function(d) {
        return {
          id: "id" + d,
          "someProperty": ~~(Math.random() * 100)
        }
      });
      update(data);
    }, 2000);
    
    function update(my_data) {
      var my_group = svg.selectAll(".data_group")
        .data(my_data, function(d) {
          return d.id
        });
    
      my_group.exit().remove();
    
      var enter = my_group.enter()
        .append("g")
        .attr("class", "data_group");
    
      enter.append("text").attr("class", "group_item group_text")
      enter.append("circle").attr("class", "group_item group_circle");
    
      my_group = my_group.merge(enter);
    
    
      console.log("---")
    
      d3.selectAll(".group_text").each(function(d) {
        console.log(JSON.stringify(d))
      });
    }
    .as-console-wrapper { max-height: 100% !important;}
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <svg></svg>

    现在,如果我们用你父母的选择。。。

    my_group.select(".group_text").each(function(d) {
        console.log(d)
    })
    

    全部的 属性已更新:

    var svg = d3.select("svg");
    d3.interval(function() {
      var data = d3.range(1 + ~~(Math.random() * 4)).map(function(d) {
        return {
          id: "id" + d,
          "someProperty": ~~(Math.random() * 100)
        }
      });
      update(data);
    }, 2000);
    
    function update(my_data) {
      var my_group = svg.selectAll(".data_group")
        .data(my_data, function(d) {
          return d.id
        });
    
      my_group.exit().remove();
    
      var enter = my_group.enter()
        .append("g")
        .attr("class", "data_group");
    
      enter.append("text").attr("class", "group_item group_text")
      enter.append("circle").attr("class", "group_item group_circle");
    
      my_group = my_group.merge(enter);
    
    
      console.log("---")
    
      my_group.select(".group_text").each(function(d) {
        console.log(d)
      })
    }
    <脚本src=“https://d3js.org/d3.v5.min.js“></脚本>
    <svg></svg>

    最后,在你现在删除的答案中,你正在使用 my_group.selectAll() selectAll() 不传播数据。

    方法 选择()
    选择 选择与选择器字符串匹配的第一个元素 选择与选择器字符串匹配的所有元素
    分组 影响分组
    数据传播 传播数据

    注意安全 传播数据 不传播数据

        2
  •  0
  •   rioV8    6 年前

    将绑定到父级的数据复制到 g 元素

    无需添加修复程序

    d3.selectAll(".group_text")
        .datum(function () { return d3.select(this.parentNode).datum(); } )
        //   .... add properties to text - ie x,y,fill,text-anchor,text 
    
    d3.selectAll(".group_circle")
        .datum(function () { return d3.select(this.parentNode).datum(); } )
        //   .... add properties to circle - ie cx,cy,fill,stroke,radius