Как экстернализировать d3.js конфигурация перехода

#javascript #d3.js

#javascript #d3.js

Вопрос:

Я хотел бы определить d3.js конфигурация перехода ( delay , duration и ease ), а затем использовать эту конфигурацию для нескольких переходов. Например, я хотел бы иметь код, который работает следующим образом (запустите его):

 d3.selectAll(".apple")
  .transition()
    .delay(100)
    .duration(5000)
    .ease(d3.easeLinear)
    .style("fill", "red");

d3.selectAll(".orange")
  .transition()
    .delay(2000)
    .attr("cx", "150")
  .transition()
    .delay(100)
    .duration(5000)
    .ease(d3.easeLinear)
    .style("fill", "orange");
  

но без .delay(100).duration(5000).ease(d3.easeLinear) многократного повторения части. Какой самый D3-идиоматический способ добиться этого?

Ответ №1:

Взгляните на https://github.com/d3/d3-transition#transition_call , который ведет себя очень похоже на вызов выбора. Это позволяет связывать выполнение функции при выборе / переходе.

 <!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
  </style>
</head>

<body>
  <div>Click me</div>
  <script>
function applyTransitionConfig(transition, config) {
    transition
        .delay(config.delay)
        .duration(config.duration)
        .ease(config.ease);
}

var transitionConfig = {
    delay: 300,
    duration: 100,
    ease: d3.easeLinear
};

var svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500)

var rect = svg.append('rect')
    .attr('width', 30)
    .attr('height', 30)
    .attr('x', 0)
    .attr('fill', '#f54')
    .on('click', function() {
        var x = Math.random() * 960;
        rect.transition()
            .call(applyTransitionConfig, transitionConfig)
            .attr('x', x);
    })
  </script>
</body>  

Ответ №2:

Если я не ошибаюсь,

Если вы хотите «определить d3.js конфигурация перехода (задержка, длительность и простота), а затем используйте эту конфигурацию при нескольких переходах «. Вы можете определить переход с легкостью, продолжительностью и задержкой следующим образом:

 var t = d3.transition()
  .delay(1000)
  .duration(1000)
  .ease(d3.easeBounce);
  

Затем, чтобы использовать этот переход, мы можем использовать:

 selection.transition(t)
  .attr("...",...) // property to transition.
  

Предоставляя нам:

 var t = d3.transition()
  .delay(1000)
  .duration(1000)
  .ease(d3.easeBounce); 
  
var svg = d3.select("svg");

var circle = svg.append("circle")
  .attr("cx",50)
  .attr("cy",50)
  .attr("r", 20)
  .attr("fill","steelblue");
  
var rect = svg.append("rect")
  .attr("x", 100)
  .attr("y", 100)
  .attr("width",50)
  .attr("height",50)
  .attr("fill","steelblue");
  
circle.transition(t)
  .attr("r", 40)
  .transition(t)
  .duration(5000) // modify pre-configured duration
  .attr("r","20")
  
rect.transition(t)
  .attr("fill","crimson")
  .transition(t)
  .attr("width",80)
  .transition(t)
  .attr("fill","yellow");  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>  

Для идиоматичности этого подхода документация содержит этот пример:

 var t = d3.transition()
    .duration(750)
    .ease(d3.easeLinear);

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

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

Комментарии:

1. Не могли бы вы предоставить код, который использует этот подход для достижения того же результата, что и код в вопросе? Я попытался и потерпел неудачу (второй .orange переход не использует экстернализованную конфигурацию t ).

2. Ах, да, я вижу проблему, я обновлю что-нибудь, когда у меня будет такая возможность.

3. Не забыл, в отпуске еще полторы недели. На мой взгляд, существует решение, которое нужно правильно протестировать, когда я вернусь домой. Извините за задержку.