2017-01-06 6 views
-1

У меня есть SVG и диаграмма, которая отображает внутри SVG на основе ширины и высоты. Я хотел бы создать страницу, где есть несколько SVG, каждая из которых содержит диаграмму, а SVG, который щелкнут, затем немного расширяется. Я могу сделать это без перехода, но я бы хотел сделать его визуально привлекательным. Было бы замечательно, если бы я мог сделать что-то вроде:D3 Переходы - внесение изменений во время перехода

svg.transition().duration(whatever).attr("width",whatever); 

, но я хочу, чтобы быть в непрерывном режиме функции график изменения размера, как переход происходит. Конечно, я мог бы начать переход на svg, а затем отдельный переход на элементы диаграммы, но я понимаю, что не гарантируется прогресс в том же темпе и что сроки на переходах не гарантируются точно. Самый простой способ, которым я могу это сделать, - установить какой-то слушатель в атрибуте width SVG, но некоторые попытки переполнения стека показывают, что это невозможно. Все они предлагают функцию setter, которая вызывает слушателя, а затем сбрасывает значение, но это не работает здесь, потому что переход заботится обо всем этом.

Также как только я закончу, я буду делать больше, чем просто регулировать ширину, мне не нужна помощь, я просто хотел бы знать, есть ли способ запустить функцию изменения размера диаграммы в качестве перехода прогрессирует здесь так или иначе, что, поскольку svg-переходы, график будет по-прежнему иметь правильный размер.

Спасибо.

ответ

1

d3 версия 4, transitions now take an optional parameter другого перехода, который может использоваться для синхронизации переходов между элементами. Из этой документации здесь пример:

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
    
 
    var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width',600) 
 
     .attr('height',500); 
 
     
 
    svg.append('circle') 
 
     .attr('class', 'apple') 
 
     .attr('r', 200) 
 
     .attr('cx', 200) 
 
     .attr('cy', 250) 
 
     .style('fill', 'black'); 
 
     
 
    svg.append('circle') 
 
     .attr('class', 'orange') 
 
     .attr('r', 200) 
 
     .attr('cx', 400) 
 
     .attr('cy', 250) 
 
     .style('fill', 'black'); 
 
    
 
    var t = d3.transition() 
 
     .duration(7000) 
 
     .ease(d3.easeLinear); 
 

 
    d3.selectAll(".apple").transition(t) 
 
     .style("fill", "red"); 
 

 
    d3.selectAll(".orange").transition(t) 
 
     .style("fill", "orange"); 
 
    </script> 
 
    </body> 
 

 
</html>

Альтернативный подход заключается в создании пользовательской функции анимации, которая будет выполнять обе анимации в один переход:

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
    
 
    var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width',600) 
 
     .attr('height',500); 
 
     
 
    svg.append('circle') 
 
     .attr('class', 'apple') 
 
     .attr('r', 200) 
 
     .attr('cx', 200) 
 
     .attr('cy', 250) 
 
     .style('fill', 'black'); 
 
     
 
    svg.append('circle') 
 
     .attr('class', 'orange') 
 
     .attr('r', 200) 
 
     .attr('cx', 400) 
 
     .attr('cy', 250) 
 
     .style('fill', 'black'); 
 
    
 
    var t = d3.transition() 
 
     .duration(7000) 
 
     .ease(d3.easeLinear) 
 
     .tween("attr.fill", function() { 
 
     var apple = d3.selectAll(".apple"), 
 
      orange = d3.selectAll(".orange"), 
 
      i1 = d3.interpolateRgb(apple.style("fill"), "red"), 
 
      i2 = d3.interpolateRgb(orange.style("fill"), "orange"); 
 
     return function(t) { 
 
      apple.style("fill", i1(t)); 
 
      orange.style("fill", i2(t)); 
 
     }; 
 
     }); 
 
    </script> 
 
    </body> 
 

 
</html>

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