2017-03-02 4 views
0

In der Version d3 v3 war ein gemeinsamer Workflow für mich mehrere svg Gruppenelemente zu erstellen und dann eine Anzahl von anderen untergeordneten Elemente an jedes g anhängen. Als Beispiel habe ich unten drei Gruppenelemente erstellt und jeder Gruppe einen Kreis hinzugefügt. Ich verwenden Sie dann die selection.each Methode den Radius jeden Kreis zu aktualisieren:Schwierigkeit Verständnis d3 Version 4 Auswahl Lebenszyklus mit verschachtelten Elementen

var data = [2, 4, 8] 

    var g = d3.select('svg').selectAll('.g').data(data) 
    g.each(function(datum) { 
    var thisG = d3.select(this) 
    var circle = thisG.selectAll('.circle') 

    circle.transition().attr('r', datum * 2) 
    }) 

    var enterG = g.enter().append('g').attr('class', 'g') 
    enterG.append('circle') 
    .attr('class', 'circle') 
    .attr('r', function(d) { return d }) 

    g.exit().remove() 

Was ist der richtige Weg, dies zu tun in d3 v4? Ich bin sehr verwirrt darüber, wie man das am besten macht. Hier ist ein Beispiel dafür, was ich versuche:

var data = [2, 4, 8] 

    var g = d3.select('svg').selectAll('.g').data(data) 

    g.enter() 
    // do stuff to the entering group 
    .append('g') 
    .attr('class', 'g') 
    // do stuff to the entering AND updating group 
    .merge(g) 

    // why do i need to reselect all groups here to append additional elements? 
    // is it because selections are now immutable? 
    var g = d3.select('svg').selectAll('g') 
    g.append('circle') 
     .attr('class', 'circle') 
     .attr('r', function(d) { return d }) 

    // for each of the enter and updated groups, adjust the radius of the child circles 
    g.each(function(datum) { 
    var thisG = d3.select(this) 
    var circle = thisG.selectAll('.circle') 

    circle.transition().attr('r', datum * 2) 
    }) 

    g.exit().remove() 

Vielen Dank im Voraus für jede Hilfe, die Sie anbieten können. Ich habe d3 v3 für eine lange Zeit verwendet und fühle mich ziemlich wohl damit. Allerdings fällt es mir sehr schwer, einige der verschiedenen Verhaltensweisen in v4 zu verstehen.

Antwort

1

Ich denke, Ihr Code wie folgt (nicht getestet, so unsicher) modifiziert werden könnte:

var data = [2, 4, 8] 

var g = d3.select('svg').selectAll('.g').data(data); 

// do stuff to the entering group 
var enterSelection = g.enter(); 
var enterG = enterSelection.append('g') 
.attr('class', 'g'); 

//Append circles only to new elements 
enterG.append('circle') 
    .attr('class', 'circle') 
    .attr('r', function(d) { return d }) 

// for each of the enter and updated groups, adjust the radius of the child circles 
enterG.merge(g) 
    .select('.circle') 
    .transition() 
    .attr('r',function(d){return d*2}); 
g.exit().remove() 

Wenn die erste .selectAll verwenden, werden nur vorhandene Elemente ausgewählt. Dann erstellen Sie durch Eingabe neue Elemente, die eine neue Auswahl erzeugen. Wenn Sie alle aktualisieren müssen, fügen Sie einfach die neuen und vorhandenen Elemente in einer einzigen Auswahl zusammen. Und dann den Radius durch die Bindung API aktualisieren, die mich Anruf von Herstellung eines .each verhindert -

Aus dieser Auswahl, habe ich einfach all .circle (ein Element pro g Einzel wählen) ausgewählt. Ich bin unsicher, wie diese beiden vergleichen, ich habe es einfach immer so gemacht.

Schließlich ist here ein bl.ocks, das das Muster demonstriert.

+0

Vielen Dank! Das funktioniert tatsächlich. Die Zusammenführung gefolgt von Auswahl war der Trick. Ich kannte dieses Muster nicht. Danke noch einmal! – turtle

+0

Herzlich Willkommen! Ich habe das auch kürzlich gesehen –