2017-02-19 4 views
2

У меня есть код вроде следующего:D3: функции событий с каскадными переходами

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

Функции f1, f2 и f3 изменить внешний вид некоторых DOM-элементов на странице.

Мне нужно запустить функции f1, f2, f3, когда переходы начнут давать эффекты, то есть по истечении времени, указанного задерживанием.

Но прежде всего мне нужно выполнить функции f1, f2 и f3, когда происходят соответствующие переходы.

Вместо этого Мне кажется, что f3 выполняется сразу после f1 и f2, и поэтому он скрывает их изменения 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

Смежные вопросы