101

D3.jsを使用してFadeOutメソッド(jQueryと同様)を作成する必要があります。私がする必要があるのは、を使用して不透明度を0に設定することですtransition()

d3.select("#myid").transition().style("opacity", "0");

問題は、移行がいつ終了したかを認識するためにコールバックが必要なことです。コールバックを実装するにはどうすればよいですか?

4

9 に答える 9

149

遷移の「終了」イベントをリッスンする必要があります。

// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);

// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);

のドキュメントからtransition.each([type],listener)

タイプが指定されている場合、「開始」イベントと「終了」イベントの両方をサポートする遷移イベントのリスナーを追加します。遷移に一定の遅延と期間がある場合でも、リスナーは遷移内の個々の要素ごとに呼び出されます。startイベントを使用すると、各要素が遷移し始めるときに瞬間的な変化をトリガーできます。this終了イベントを使用して、現在の要素を選択し、新しい遷移を導出することにより、多段階の遷移を開始できます。終了イベント中に作成されたトランジションは、現在のトランジションIDを継承するため、以前にスケジュールされた新しいトランジションを上書きしません。

詳細については、このトピックに関するこのフォーラムスレッドを参照してください。

最後に、要素がフェードアウトした後(遷移が終了した後)に要素を削除したいだけの場合は、を使用できることに注意してくださいtransition.remove()

于 2012-05-21T20:33:37.153 に答える
66

小さなアップデートを含むv3用のMikeBostockのソリューション:

  function endall(transition, callback) { 
    if (typeof callback !== "function") throw new Error("Wrong callback in endall");
    if (transition.size() === 0) { callback() }
    var n = 0; 
    transition 
        .each(function() { ++n; }) 
        .each("end", function() { if (!--n) callback.apply(this, arguments); }); 
  } 

  d3.selectAll("g").transition().call(endall, function() { console.log("all done") });
于 2013-12-25T14:35:13.883 に答える
44

現在、d3 v4.0には、イベントハンドラーをトランジションに明示的にアタッチする機能があります。

https://github.com/d3/d3-transition#transition_on

遷移が完了したときにコードを実行するには、必要なのは次のとおりです。

d3.select("#myid").transition().style("opacity", "0").on("end", myCallback);
于 2016-07-23T03:54:47.040 に答える
10

それぞれが同時に実行されている多くの要素を持つ多くの遷移がある場合にも機能する、わずかに異なるアプローチ:

var transitions = 0;

d3.select("#myid").transition().style("opacity","0").each( "start", function() {
        transitions++;
    }).each( "end", function() {
        if( --transitions === 0 ) {
            callbackWhenAllIsDone();
        }
    });
于 2014-07-24T19:23:34.373 に答える
6

以下は、Mike Bostockのソリューションの別のバージョンであり、@kashesandrの回答に対する@hughesのコメントに触発されています。transitionの終了時に単一のコールバックを作成します。

与えられたdrop関数...

function drop(n, args, callback) {
    for (var i = 0; i < args.length - n; ++i) args[i] = args[i + n];
    args.length = args.length - n;
    callback.apply(this, args);
}

...次d3のように拡張できます:

d3.transition.prototype.end = function(callback, delayIfEmpty) {
    var f = callback, 
        delay = delayIfEmpty,
        transition = this;

    drop(2, arguments, function() {
        var args = arguments;
        if (!transition.size() && (delay || delay === 0)) { // if empty
            d3.timer(function() {
                f.apply(transition, args);
                return true;
            }, typeof(delay) === "number" ? delay : 0);
        } else {                                            // else Mike Bostock's routine
            var n = 0; 
            transition.each(function() { ++n; }) 
                .each("end", function() { 
                    if (!--n) f.apply(transition, args); 
                });
        }
    });

    return transition;
}

JSFiddleとして

使用transition.end(callback[, delayIfEmpty[, arguments...]])

transition.end(function() {
    console.log("all done");
});

transition...または空の場合はオプションの遅延あり:

transition.end(function() {
    console.log("all done");
}, 1000);

...またはオプションのcallback引数付き:

transition.end(function(x) {
    console.log("all done " + x);
}, 1000, "with callback arguments");

d3.transition.endミリ秒数が指定されている場合、または2番目の引数が真である場合はcallback、空の場合でもtransition 合格を適用します。これにより、追加の引数が(およびそれらの引数のみ)に転送されます。重要なことに、これはデフォルトではifが空の場合には適用されません。これは、このような場合におそらくより安全な仮定です。callbackcallbacktransition

于 2015-05-28T13:03:11.060 に答える
5

D3 v5.8.0 +以降、を使用してこれを行う公式の方法がありますtransition.end。ドキュメントはここにあります:

https://github.com/d3/d3-transition#transition_end

Bostockの実用的な例は次のとおりです。

https://observablehq.com/@d3/transition-end

そして、基本的な考え方は、を追加するだけ.end()で、遷移はすべての要素の遷移が完了するまで解決されないpromiseを返すということです。

 await d3.selectAll("circle").transition()
      .duration(1000)
      .ease(d3.easeBounce)
      .attr("fill", "yellow")
      .attr("cx", r)
    .end();

詳細については、バージョンリリースノートを参照してください。

https://github.com/d3/d3/releases/tag/v5.8.0

于 2019-09-04T22:12:58.927 に答える
0

マイク・ボストックのソリューションは、 kashesandr +コールバック関数に引数を渡すことで改善されました。

function d3_transition_endall(transition, callback, arguments) {
    if (!callback) callback = function(){};
    if (transition.size() === 0) {
        callback(arguments);
    }

    var n = 0;
    transition
        .each(function() {
            ++n;
        })
        .each("end", function() {
            if (!--n) callback.apply(this, arguments);
    });
}

function callback_function(arguments) {
        console.log("all done");
        console.log(arguments);
}

d3.selectAll("g").transition()
    .call(d3_transition_endall, callback_function, "some arguments");
于 2017-01-24T18:08:52.817 に答える
-2

実際、タイマーを使用してこれを行うもう1つの方法があります。

var timer = null,
    timerFunc = function () {
      doSomethingAfterTransitionEnds();
    };

transition
  .each("end", function() {
    clearTimeout(timer);
    timer = setTimeout(timerFunc, 100);
  });
于 2014-05-21T13:10:49.807 に答える
-2

変数を使用してトランジションの期間を設定することで、同様の問題を解決しました。次にsetTimeout()、次の関数を呼び出していました。私の場合、私の例でわかるように、トランジションと次の呼び出しの間にわずかなオーバーラップが必要でした。

var transitionDuration = 400;

selectedItems.transition().duration(transitionDuration).style("opacity", .5);

setTimeout(function () {
  sortControl.forceSort();
}, (transitionDuration * 0.75)); 
于 2015-02-02T18:22:22.883 に答える