d3js: make new parent data descend into child nodes

后端 未结 2 705
借酒劲吻你
借酒劲吻你 2020-12-24 07:24

I can\'t work out how best to pass changes to the data which occur at a parent node (e.g. an SVG g element) down to it\'s children (e.g. SVG circle

2条回答
  •  渐次进展
    2020-12-24 07:53

    Not sure if you figured it out, but this is definitely not in the documentation. All of the documentation that deals with element grouping does not seem to deal with the child selection and data inheritance to children.

    The answer is to use the .each construct to update the children elements and append the children to the group enter() call.

    data = [{"id":"A","name":"jim"},{"id":"B","name":"dave"},{"id":"C","name":"pete"}];
    
    function draw(data) {
      var g = svg.selectAll("g").data(data, function(d) { return d.id; })
    
      genter = g.enter().append("g");
    
      // This is the update of the circle elements - 
      // note that it is attached to the g data, not the enter()
      // This will update any circle elements that already exist
      g.each(function(d, i) {
        var group = d3.select(this);
        group.select("circle")
        .transition() 
          .attr("r", 3)
          .attr("cx", 100)
          .attr("cy", function(d,i) {return 100 + (i * 30);})
      }
    
      // The data DOES get passed down to the circles, and the enter() statement
      // will create a circle child for each data entry
      genter.append("circle")
          .attr("r", 3)
          .attr("cx", 100)
          .attr("cy", function(d,i) {return 100 + (i * 30);})
    }
    
    // Original drawing
    draw(data);
    
    // Now change the data, and update the groups' data accordingly
    data = [{"id":"A","name":"carol"},{"id":"B","name":"diane"},{"id":"C","name":"susan"}];
    
    // Second drawing, the SVG will be updated
    draw(data);
    

    Let me know if this works.

    [This answer is based on some code grouping from this coderwall post: https://coderwall.com/p/xszhkg ]

提交回复
热议问题