2017-02-19 45 views
2

我有類似下面的代碼:D3:與級聯轉換事件功能

selection. 
    .transition() 
    .delay(1000) 
    .each("start",f1) 
    ... 
    .transition() 
    .delay(2000) 
    .each("start",f2) 
    ... 
    .transition() 
    .delay(3000) 
    .each("start",f3) 
    ... 

功能f1f2f3改變頁面的一些DOM元素的外觀。

我需要運行函數f1,f2,f3當轉換開始產生效果時,也就是在延遲時間之後。

但首先我需要在發生相應的轉換時運行功能f1,f2f3

相反在我看來,f3f1f2之後立即執行,因此它隱藏了它們的DOM更改。

什麼是正確的做法?

回答

1

如果您的功能正在運行一次,一下子沒有了聽衆而言,這可能是因爲你是你的函數後,連接監聽器的時候把括號:

.each('start',function()); 

雖然你還沒有表示這在你的問題中,你可能已經排除了他們的問題。

如果您需要將參數傳遞給函數,你需要實際編寫的內聯函數來調用你的函數:

.each('start', function() { functionName(param1,param2); }) 

即使括號內是不麻煩的來源,我希望以下示例可能有所幫助

我用d3.js V4在我的答案是:.on方法用在這裏,而不是.each

雖然我已經使用的持續時間,而不是延遲,答案應該還是適用於我簡短的測試。


摘錄:

例如基於你的問題(假設括號內是頭痛的原因):

var svg = d3.select('body').append('svg').attr('width',400).attr('height',200); 
 

 
var data = [4,12,4,12,4,12,4]; 
 

 
svg.selectAll('circle') 
 
    .data(data) 
 
    .enter() 
 
    .append('circle') 
 
    .attr('cx', function(d,i) { return 40 + (i * 20); }) 
 
    .attr('cy', 50) 
 
    .attr('r', function(d) { return d; }) 
 
    .attr('fill','black'); 
 
    
 

 
svg.selectAll('circle') 
 
    // Transition 1 
 
    .transition() 
 
    .attr('r', function(d) { return (d == 4) ? 10 : 4; }) 
 
    .duration(3000) 
 
    .on('start', s1()) 
 
    .on('end', e1()) 
 

 
    // Transition 2 
 
    .transition() 
 
    .attr('fill', function(d) { return (d == 4) ? "steelblue" : "orange"; }) 
 
    .duration(3000) 
 
    .on('start', s2()) 
 
    .on('end', e2()) 
 
    
 
    // Transition 3 
 
    .transition() 
 
    .attr('cy', function(d,i) { return (d==4) ? 30:60; }) 
 
    .attr('r', function(d) { return (d == 4) ? 14 : 18; }) 
 
    .duration(3000) 
 
    .on('start', s3()) 
 
    .on('end', e3()) 
 
    ; 
 
    
 
    function s1() { console.log("Transition 1 Start"); } 
 
    function s2() { console.log("Transition 2 Start"); } 
 
    function s3() { console.log("Transition 3 Start"); } 
 
    function e1() { console.log("Transition 1 End"); } 
 
    function e2() { console.log("Transition 2 End"); } 
 
    function e3() { console.log("Transition 3 End"); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>

所有功能觸發一次,他們觸發一次。


去掉括號會給你:

var svg = d3.select('body').append('svg').attr('width',400).attr('height',200); 
 

 
var data = [4,12,4,12,4,12,4]; 
 

 
svg.selectAll('circle') 
 
    .data(data) 
 
    .enter() 
 
    .append('circle') 
 
    .attr('cx', function(d,i) { return 40 + (i * 20); }) 
 
    .attr('cy', 50) 
 
    .attr('r', function(d) { return d; }) 
 
    .attr('fill','black'); 
 
    
 

 
svg.selectAll('circle') 
 
    // Transition 1 
 
    .transition() 
 
    .attr('r', function(d) { return (d == 4) ? 10 : 4; }) 
 
    .duration(3000) 
 
    .on('start', s1) 
 
    .on('end', e1) 
 

 
    // Transition 2 
 
    .transition() 
 
    .attr('fill', function(d) { return (d == 4) ? "steelblue" : "orange"; }) 
 
    .duration(3000) 
 
    .on('start', s2) 
 
    .on('end', e2) 
 
    
 
    // Transition 3 
 
    .transition() 
 
    .attr('cy', function(d,i) { return (d==4) ? 30:60; }) 
 
    .attr('r', function(d) { return (d == 4) ? 14 : 18; }) 
 
    .duration(3000) 
 
    .on('start', s3) 
 
    .on('end', e3) 
 
    ; 
 
    
 
    function s1() { console.log("Transition 1 Start"); } 
 
    function s2() { console.log("Transition 2 Start"); } 
 
    function s3() { console.log("Transition 3 Start"); } 
 
    function e1() { console.log("Transition 1 End"); } 
 
    function e2() { console.log("Transition 2 End"); } 
 
    function e3() { console.log("Transition 3 End"); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>

沒有爲選擇沒有過渡,每個元素都被單獨轉移,導致多次調用每個函數(這可能是需要的,我不確定它是否在你的情況)。


如果你想一次觸發每個功能,那麼你就需要計算有多少元素已經完成轉換(我已經做了以下這爲結束事件)。或者如果您確信所有轉換幾乎同時完成,您可以通過使用if語句在特定元素開始或結束時觸發事件(我已經爲下面的開始事件完成此操作),從而每次選擇調用該函數一次:

var svg = d3.select('body').append('svg').attr('width',400).attr('height',200); 
 

 
var data = [4,12,4,12,4,12,4]; 
 

 
svg.selectAll('circle') 
 
    .data(data) 
 
    .enter() 
 
    .append('circle') 
 
    .attr('cx', function(d,i) { return 40 + (i * 20); }) 
 
    .attr('cy', 50) 
 
    .attr('r', function(d) { return d; }) 
 
    .attr('fill','black'); 
 
    
 

 
var n = 6; 
 
var m = 6; 
 

 
svg.selectAll('circle') 
 
    // Transition 1 
 
    .transition() 
 
    .on('start',function(d,i) { if (i == 6) { log('transition 1 started'); } }) 
 
    .on('end',function(d,i) { if(--m == 0) { m = 6; log('transition 1 ended'); } }) 
 
    .attr('r', function(d) { return (d == 4) ? 10 : 4; }) 
 
    .duration(3000) 
 

 
    // Transition 2 
 
    .transition() 
 
    .on('start',function(d,i) { if (i == 6) { log('transition 2 started'); } }) 
 
    .on('end',function(d,i) { if(--m == 0) { m = 6; log('transition 2 ended'); } }) 
 
    .attr('fill', function(d) { return (d == 4) ? "steelblue" : "orange"; }) 
 
    .duration(3000) 
 
    
 
    // Transition 3 
 
    .transition() 
 
    .on('start',function(d,i) { if (i == 6) { log('transition 3 started'); } }) 
 
    .on('end',function(d,i) { if(--m == 0) { m = 6; log('transition 3 ended'); } }) 
 
    .attr('cy', function(d,i) { return (d==4) ? 30:60; }) 
 
    .attr('r', function(d) { return (d == 4) ? 14 : 18; }) 
 
    .duration(3000) 
 
    ; 
 
    
 
    function log(string) { 
 
    console.log(string); 
 
    }
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>--> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>

+0

你猜對了!謝謝! – tic