如何添加条件转换?

Han*_*ker 3 javascript animation svg d3.js

这个问题是关于 d3.js 的转换,例如矩形的 x 属性的变化。

如果您希望更改立即发生,您可以设置delay = duration = 0

svg.selectAll("rect")
   .transition()
   .delay(delay)
   .duration(duration)
   .attr("x", 0)
Run Code Online (Sandbox Code Playgroud)

但这可能太昂贵了(假设转换比立即更改更消耗 CPU)。那么我如何有条件地添加转换,表现得像

if (delay == 0 && duration == 0) {
    svg.selectAll("rect")
        .attr("x", 0)
} else {
    svg.selectAll("rect")
        .transition()
        .delay(delay)
        .duration(duration)
        .attr("x", 0)
}
Run Code Online (Sandbox Code Playgroud)

但更少冗余和更紧凑,不知何故像x = condition ? 0 : 1

Ger*_*ado 6

这是一个非常奇怪的情况,我想不出一个有用的用例。话虽如此,这里是许多可能的解决方案之一:扩展 D3 选择原型。

在我的方法,我们将扩展原型,以返回两者的情况完全一样的选择delayduration是零,或者返回一个过渡基于当前选择的选择,如果他们不为零:

d3.selection.prototype.conditionalTransition =
  function(cond1, cond2) {
    return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
  };
Run Code Online (Sandbox Code Playgroud)

然后,您只需继续attr()方法链:

d3.selectAll("rect")
  .conditionalTransition(delay, duration)
  .attr("x", 200);
Run Code Online (Sandbox Code Playgroud)

最后要注意的是,常规选择和过渡选择具有不同的同名方法,例如selection.on()transition.on()

这是第一个演示。所有的矩形都在x = 10. 选区变成了过渡选区:

d3.selection.prototype.conditionalTransition =
  function(cond1, cond2) {
    return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
  };
Run Code Online (Sandbox Code Playgroud)
d3.selectAll("rect")
  .conditionalTransition(delay, duration)
  .attr("x", 200);
Run Code Online (Sandbox Code Playgroud)

这里是相同的代码,既delayduration等于零。如您所见,矩形已经位于最终位置,没有过渡:

d3.selection.prototype.conditionalTransition =
  function(cond1, cond2) {
    return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
  };

const rect = d3.selectAll("rect");

const delay = 100,
  duration = 1000;

rect.conditionalTransition(delay, duration)
  .attr("x", 200)

function transitioning(sel) {
  return sel.transition()
    .delay(delay)
    .duration(duration);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
 <rect x="10" y="10" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="40" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="70" width="50" height="20" fill="teal"></rect>
 <rect x="10" y="100" width="50" height="20" fill="teal"></rect>
</svg>
Run Code Online (Sandbox Code Playgroud)