我想对不同的元素进行链式转换。在整个程序中,我想运行一系列过渡。在元素x完成第一次转换后,我想从元素y的转换开始,依此类推。转换的持续时间应有所不同。
解决问题的一种方法"它基于先前转换的持续时间的总和来延迟所有后面的转换。但这非常难看,因为它非常混乱而且不准确。
这是我尝试完成的一个例子:
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<script src="https://d3js.org/d3.v4.js"></script>
</head>
<body>
<script>
let sel = d3.select("body")
let selFirst = sel.append("h1").attr("class", "first").text("first");
let selSecond = sel.append("h2").attr("class", "second").text("second");
let selThird = sel.append("h3").attr("class", "third").text("third");
let trans = d3.transition("body");
let firstTrans = trans.each(function() {selFirst.transition().style("opacity", 0).transition().style("opacity",1); })
let secondTrans = firstTrans.each(function() {selSecond.transition().style("opacity", 0).transition().style("opacity",1); })
let thirdTrans = secondTrans.each(function() {selThird.transition().style("opacity", 0).transition().style("opacity",1); })
</script>
</body>
</html>
答案 0 :(得分:1)
感谢Gerardo Furtado,这是一个可能的解决方案。
第1步:您必须使用相同的类标记所有相应的元素,即chained-transition
。
let sel = d3.select("body")
let selFirst = sel.append("h1").attr("class", "chained-transition first").text("first");
let selSecond = sel.append("h1").attr("class", "chained-transition second").text("second");
let selThird = sel.append("h1").attr("class", "chained-transition third").text("third");
步骤2:现在您可以创建一个包含应该连续转换的所有元素的选择。要为每个选择设置不同的持续时间,您可以将所需的持续时间(以毫秒为单位)附加到每个元素。 (如果您还没有在步骤1中创建元素,那么可以与其他数据一起使用)
let chainedSel = d3.selectAll(".chained-transition").data([1000,2000,3000]);
步骤3:创建一个函数,一次选择一个,转换它(持续时间)并使用下一个元素调用自身。下面的代码是一个用整个链式选择调用的函数。它过滤到相应的(下一个)元素。
transitionNext(chainedSel);
// function gets the chained selection with
// all the corresponding elements.
// It start with the first one by default.
function transitionNext(_selection, _index = 0){
console.log("index: " + _index);
// start off with the first element (_index === 0)
let newSel =
_selection.filter(function(d,i) { return _index === i;});
newSel.transition()
.duration(d => d) // take the corresponding duration
.style("opacity", 0)
.transition()
.duration(d => d) // as above
.style("opacity",1)
.style("color", "green")
// this function is called after the transition is finished
.on ("end", function() {
_index = _index + 1;
// call function and filter the next element
if (_selection.size() > _index) { transitionNext(_selection, _index);}
});
}
完整的例子在这里:
let sel = d3.select("body")
let selFirst = sel.append("h1").attr("class", "chained-transition first").text("first");
let selSecond = sel.append("h1").attr("class", "chained-transition second").text("second");
let selThird = sel.append("h1").attr("class", "chained-transition third").text("third");
let chainedSel = d3.selectAll(".chained-transition").data([1000,2000,3000]);
transitionNext(chainedSel);
function transitionNext(_selection, _index = 0){
console.log("index: " + _index);
let newSel =
_selection.filter(function(d,i) { return _index === i;});
newSel.transition()
.duration(d => d)
.style("opacity", 0)
.transition()
.duration(d => d)
.style("opacity",1)
.style("color", "green")
.on ("end", function() {
_index = _index + 1;
if (_selection.size() > _index) { transitionNext(_selection, _index);}
});
}
&#13;
<script src="https://d3js.org/d3.v4.js"></script>
&#13;
具有重复函数调用的版本只传递一个元素而非所有元素的选择here。