此问题与d3.js的转换有关,例如矩形的x1属性的更改。
如果您希望立即进行更改,则可以将delay = duration = 0
设置为
svg.selectAll("rect")
.transition()
.delay(delay)
.duration(duration)
.attr("x1", 0)
但是这可能太昂贵了(假设转换比立即更改要消耗更多的CPU资源)。因此,我该如何有条件地添加过渡,例如
if (delay == 0 && duration == 0) {
svg.selectAll("rect")
.attr("x1", 0)
} else {
svg.selectAll("rect")
.transition()
.delay(delay)
.duration(duration)
.attr("x1", 0)
}
但是冗余度更低,结构更紧凑,有点像x = condition ? 0 : 1
?
这是一个非常奇怪的情况,我无法考虑这种情况会有用的情况。即使这样,这也是许多可能的解决方案之一:扩展D3选择原型。
在我的方法中,我们将扩展原型以在delay
和duration
都为零的情况下返回完全相同的选择,或者如果不为[],则返回transition选择:
d3.selection.prototype.conditionalTransition =
function(cond1, cond2) {
return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
};
然后,您只需继续attr()
方法链。顺便说一下,<rect>
没有x1
属性,只有x
。
这里是第一个演示。所有的rects都在x = 10
中。该选择变为转换选择:
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);
}
<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>
这是相同的代码,delay
和duration
都等于零。您可以看到矩形立即移动:
d3.selection.prototype.conditionalTransition =
function(cond1, cond2) {
return cond1 && cond2 ? this.transition().duration(duration).delay(delay) : this;
};
const rect = d3.selectAll("rect");
const delay = 0,
duration = 0;
rect.conditionalTransition(delay, duration)
.attr("x", 200)
function transitioning(sel) {
return sel.transition()
.delay(delay)
.duration(duration);
}
<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>