2013-05-02 28 views
9

D3.js. ile çalışıyorum D3.js: Dur geçişleri kesintiye uğradı mı?

Bu

bir JSFiddle sorunu sergilemekte ilki sona ermeden önce ikinci bir geçiş başlarsa: Ben geçişler güzel çalışma var, ama sadece tek bir sorun var http://jsfiddle.net/kqxhj/11/

Çalışıyor zaman ince çoğu - CDG ve LAX, veri değiştikçe eklenir ve kaldırılır - ancak düğmeye art arda iki kez tıklarsanız, yeni öğelerin görünmediğini fark edersiniz.

Bu

benim kod et:

function update(data) { 

    var g = vis.selectAll("g.airport").data(data, function(d) { 
    return d.name; 
    }); 
    var gEnter = g.enter().append("g") 
    .attr("class", function(d) {  
    return "airport " + d.name; 
    }); 
    // Perform various updates and transitions... 
    [...] 

    // Remove exited elements. 
    g.exit().transition() 
    .duration(1000) 
    .attr("transform", "translate(0," + 1.5*h + ")"); 
    g.exit().transition().delay(1000) 
    .remove(); 
} 

d3.select('#clickme').on("click", function() { 
    update(current_data); 
}); 

ben neler olduğunu anlamaya biraz ayıklama ifadeleri eklemek için denedim ama görebildiğim bütün o olur, çıkış seçimi olmasıdır 4 element in, 3 değil - neden olduğunu anlamıyorum.

D3'te veya temel JavaScript'te geçişlerin çakışmamasını sağlayabileceğimin bir yolu var mı?

+1

['end' event] 'i (https://github.com/mbostock/d3/wiki/Transitions#wiki-each) dinlemeniz ve yalnızca bir sonraki geçişi yalnızca gerçekleştikten sonra başlatmanız gerekir. Alternatif olarak, ['transition.transition()'] 'a bakın (https://github.com/mbostock/d3/wiki/Transitions#wiki-transition). İşte bir [harika makale] (http://bost.ocks.org/mike/transition/#life-cycle) kontrol etmelisiniz. –

+1

Ayrıca, geçiş işleminin sonunda gerçekleşir, bu nedenle yalnızca düğümleri kaldırmak için iki çıkış geçişi oluşturmanız gerekmez. [Transition.remove belgelerine bakın] (https://github.com/mbostock/d3/wiki/Transitions#wiki-remove). – mbostock

cevap

5

D3'te, daha yeni geçişler her zaman eski geçişleri kesintiye uğratır ve geçersiz kılar. Tasarım sorununuzu, the each() method within your selection., ör. Neler oluyor

d3.select('.animated') 
.transition() 
.duration(1000) 
.attr({ 
    ... // Change something 
}) 
.each('end', function() { 
    d3.select(this) 
    .attr({ 
     ... // Change something else, after previous transition 
    }); 
}); 
+0

Teşekkürler. Bunu benim özel durumuma nasıl uygulayacağımı bilmiyorum, ancak - her bir yöntemi benim güncelleme geçişlerime eklemek gibi bir şeyden bahsediyorsunuz, sonra da "her" aramanın içerisine çıkış geçişini koydunuz mu? – Richard

8

veri temsilidir "yeniden girer" (sizin remove() çağrısı bir geçiş zincirleme olması nedeniyle) o DOM kaldırıldı önce. Ancak, veri gösterimi henüz DOM'dan kaldırılmamışsa, enter() seçimi zaten var olduğundan bu veriyi içermez! Yine de, geçişiniz yürütmeye devam edecek ve veri girişiniz "yeniden girme" şansına sahip olmadan ortadan kalkacaktır.

Yapmanız gereken şey, çıkan öğeleri bir çeşit tanımlayıcıya vermektir. Örneğin: Bir eleman "damgalı" eğer

g.exit().classed('exiting', true); 

Ardından, seçiminizi güncellemek zaman, çıkan geçişi iptal edip orijinal haline geri getirmek: Ben ettik

g.filter('.exiting') 
    .classed('exiting', false) 
    .transition() // new transition cancels the old one so that remove() isn't called 
     .attr('foo', 'bar'); // return to original state 

çözümü göstermek için keman tweaked: http://jsfiddle.net/xbfSU/

+1

Bu yaklaşım akıllıydı. Teşekkürler! – swenedo

9
: Burada http://jsfiddle.net/hX5Tp/

açıkça sorunu (ve çözümü) göstermek için keman aşağı elimden enGÜNCELLEŞTIRME: D3'ün 3.5 sürümünden (Ekim 2014) beri, named transitions kullanılarak öğeler üzerinde eşzamanlı geçişler gerçekleştirmek mümkündür. Her geçişe farklı bir ad eklemeniz yeterlidir.

+3

Bunu faydalı buldum. Bir nesneye aynı adla iki geçiş eklendiğinde, geçişler münhasırdır, yani, ikinci ilk geçişi keser/iptal eder. – swenedo

+3

Aradığım cevap buydu – gray