简体   繁体   中英

Struggling with D3 general update pattern and groups

I want to update a legend dynamically using D3, using SVG group and text elements. This is my function that gets called when it is time to update the legend.

The goal is that it will add text elements if they don't already exist. If they do exist, it will update the content of those text elements in line with the new data.

function updateCountryLegend(data) { 
  var countries = rightPanel.selectAll('g.country').data(data);    
  var cEnter = countries.enter()
                      .append('g')
                      .attr('class', 'country');    
  var countryText = cEnter.append('text')
         .attr('x', 0)
         .attr('y', 10);
  countryText.text(function(d) { return d.name; }); 
}

The current code is adding the elements OK, but not updating them. I think this is because the text is only being set on the enter selection. But no matter what I try I can't work out how to set the text on the update selection.

I want to continue to use SVG group elements, so that I can add rectangles to indicate legend colour, etc.

JSFiddle with full code here: http://jsfiddle.net/1qhnbqbw/1/

The difficulty in your case is that the update selection contains the g elements, but you want to change the text elements. To do this, call another .select() on the update selection -- countries.select("text") . This new selection will contain the text elements that you can now update in the usual manner and at the same time inherit the new data from the g to the text elements.

Complete demo here . I've replaced the g s with div s for the HTML, removed a few unnecessary variables, and handled the exit selection as well.

You don't need to create additional variables cEnter and countryText . You can just use the original countries in all operations. The updated fiddle now updates text fine.

function updateCountries(data) { 

    console.log('data', data);

    var countries = rightPanel.selectAll('g.country').data(data);

    countries.enter()
             .append('g')
             .attr('class', 'country');

    countries.append('text')
             .attr('x', 0)
             .attr('y', 10);

    countries.text(function(d) { return d.name; });

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM