如何在d3.js中的不同元素上进行链式转换?
我想对不同的元素进行链式转换。 在整个计划中,我想运行一系列转换。 在元素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>
看到这JSfiddle
感谢Gerardo Furtado,这里有一个可能的解决方案。
第一步:你必须用相同的类标记所有相应的元素,即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);}
});
}
<script src="https://d3js.org/d3.v4.js"></script>
链接地址: http://www.djcxy.com/p/83719.html
上一篇: How to do chained transitions on different elements in d3.js?