2013-12-17 12 views
6

Für jedes Datenelement füge ich eine Gruppe (g class = "parent") mit einem Kreis hinzu. Hinzufügen und Einstellen ihrer Eigenschaften funktioniert gut.D3.js - Animierter Exit für verschachteltes Objekt

Aber ich kann nicht herausfinden, wie man mit dem Entfernen umgehen kann. Wie animiere ich ein verschachteltes Objekt beim Beenden?

// parents 
var parents = svg.selectAll("parent").data(glyphs); 
parents.enter() 
    .append("g") 
    .attr("class", "parent") 
    .attr("transform", function (glyph) { 
     return "translate(" + glyph.x + "," + glyph.y + ")"; 
    }); 

// children 
var circles = parents.append("circle"); 
circles 
    .attr("r", 0) 
    .attr("fill", function (glyph) { return glyph.color; }); 
// animated entry 
circles.transition() 
    .attr("r", function (glyph) { return glyph.radius; }); 

Hier ist der Teil, der nicht funktioniert. Ich bin mir nicht sicher, wie ich die Kinder beim Verlassen animieren soll.

// animate exit 
circles 
    .exit() // <-- not valid 
    .transition() 
    .duration(250) 
    .attr("r", 0); 
parents 
    .exit() 
    .transition() 
    .delay(250) 
    .remove(); 

Kann mir jemand Tipps geben oder auf ein gutes Beispiel hinweisen?

+0

statt Kreise .exit(), versuche den Übergang auf eltern.exit(). –

+0

Ok, ich sehe, du machst das schon. Sie können versuchen, eltern.selectAll ('g'). Transition(). Duration() ... remove() Aber tun Sie es, bevor Sie die Eltern entfernen. –

Antwort

10

Die Daten werden an die Eltern gebunden, so müssen Sie die Eingabe/Übergang/Ausgang für die Kreise im Verhältnis zu den Eltern hinzufügen:

function draw(glyphs){ 
    console.log(glyphs) 
    // parents 
    var parents = svg.selectAll(".parent").data(glyphs); 
    parents.enter() 
    .append("g") 
    .attr("class", "parent") 
    .attr("transform", function (glyph) { 
     return "translate(" + glyph.x + "," + glyph.y + ")"; 
    }) 
    // Parent's data enter -> add circle -> do entry animation 
    .append("circle") 
     .attr("r", 0) 
     .attr("fill", function (glyph) { return glyph.color; }) 
     .transition() 
     .duration(250) 
     .attr("r", function (glyph) { return glyph.radius; }); 

    // parents data changes -> select circles -> transition nested circles 
    parents.select("circle") 
    .transition() 
    .duration(250) 
    .attr("r", function (glyph) { return glyph.radius; }); 

    // Parent's data exit -> select circle -> do exit animation  
    parents.exit() 
    .select("circle") 
     .transition() 
     .duration(250) 
     .attr("r", 0); 

    // Delay removal of parent for 250. 
    parents.exit() 
    .transition() 
    .duration(250) 
    .remove();  
} 

draw(glyphs); 

setTimeout(function(){ 
    draw(glyphs.map(function(g){g.radius = g.radius + 20; return g;})); 
}, 1000); 

setTimeout(function(){ 
    glyphs.pop(); 
    glyphs.pop(); 
    glyphs.pop(); 
    glyphs.pop(); 
    glyphs.pop(); 
    draw(glyphs); 
}, 3000); 

Hier ist ein Beispiel: http://jsfiddle.net/3M4xh/2/

+0

Perfekt! Vielen Dank! – sharoz

+1

Wirklich hilfreich - danke. Fühlte mich, als hätte ich alles versucht, bis ich das sah. Jetzt verstehe ich es, hier ist ein weiteres Beispiel, das möglicherweise etwas einfacher ist als der Beispielcode hier: http: //tributary.io/inlet/8157723 – RobinL