链式转换不会一步一步触发

Chained transitions don't trigger step-by-step

本文关键字:一步 转换      更新时间:2023-09-26

首先,我研究、尝试了一些相关的项目,但没有得到好的结果。

  • https://stackoverflow.com/questions/28612706/step-by-step-transitions-using-d3-js
  • d3.js中的转换队列;一个接一个
  • 不同形状复合动画的D3.js链转换

接下来,我代码的相关部分:

function moveMarker(i) {
    var curr_i = parseInt(d3.select("#nomad").attr("nomad-index"));
    var target_i = parseInt(i);
    switch (curr_i) {
        case 0:
            switch (target_i) {
                case 0:
                    break;
                case 1:
                    moveToMark(1);
                    break;
                case 2:
                    moveToMark(1);
                    moveToMark(2);
                    break;
                case 3:
                    moveToMark(1);
                    moveToMark(2);
                    moveToMark(3);
                    break;
                case 4:
                    moveToMark(1);
                    moveToMark(2);
                    moveToMark(3);
                    moveToMark(4);
                    break;
            }
        case 1:
            switch (target_i) {
                case 0:
                    moveToMark(0);
                    break;
                case 1:
                    break;
                case 2:
                    moveToMark(2);
                    break;
                case 3:
                    moveToMark(2);
                    moveToMark(3);
                    break;
                case 4:
                    moveToMark(2);
                    moveToMark(3);
                    moveToMark(4);
                    break;
            }
        case 2:
            switch (target_i) {
                case 0:
                    moveToMark(1);
                    moveToMark(0);
                    break;
                case 1:
                    moveToMark(1);
                    break;
                case 2:
                    break;
                case 3:
                    moveToMark(3);
                    break;
                case 4:
                    moveToMark(3);
                    moveToMark(4);
                    break;
            }
        case 3:
            switch (target_i) {
                case 0:
                    moveToMark(2);
                    moveToMark(1);
                    moveToMark(0);
                    break;
                case 1:
                    moveToMark(2);
                    moveToMark(1);
                    break;
                case 2:
                    moveToMark(2);
                    break;
                case 3:
                    break;
                case 4:
                    moveToMark(4);
                    break;
            }
        case 4:
            switch (target_i) {
                case 0:
                    moveToMark(3);
                    moveToMark(2);
                    moveToMark(1);
                    moveToMark(0);
                    break;
                case 1:
                    moveToMark(3);
                    moveToMark(2);
                    moveToMark(1);
                    break;
                case 2:
                    moveToMark(3);
                    moveToMark(2);
                    break;
                case 3:
                    moveToMark(3);
                    break;
                case 4:
                    break;
            }
    }
}
function moveToMark(i) {
    var x = spot[i][7]; // Latitude
    var y = spot[i][8]; // Longitude
    d3.select("#nomad")
        .attr("nomad-index", i)
        .transition()
        .delay(3000)
        .duration(1000)
        .attr("cx", x)
        .attr("cy", y);
}

我要做的要点:

我有一个事件表。在单击表中的任何事件时,我有一个圆圈(nomad),它移动到spot数据集中确定的该事件的相应位置。直接点对点移动不成问题。然而,我有一个特殊的约束:我必须根据事件的时间轴移动。

假设我点击事件#3。我的圈子必须先移动到事件1和事件2,然后他们将停留在事件3。如果圆圈处于任何事件中,单击任何其他事件,无论是低索引还是高索引,它都需要遍历当前位置和目标之间的事件。

我相信我的嵌套开关案例可以进一步解释这一点。我相信我正在尝试的事情并不像我想的那么复杂。然而,我遇到了一个主要的障碍:我的nomad循环没有一步一步地经历事件,而是在延迟后立即跳转到最后一个事件。

我在上面的链接中读到过渡有一个关于链接的问题,或者我必须使用end(...)来完成这项工作。

问题/s:

是否可以将此尝试减少为递归函数?如果有,怎么做?如果没有,我如何使每个moveToMark连续触发?

问题是在D3选择上创建一个过渡会取消任何其他可能已经创建的过渡。也就是说,只有最后一次调用.transition()才会生效,因为之前的所有转换都被取消了。

解决方案是在过渡而不是选择上创建另一个过渡(请参阅文档)。它看起来像下面这样:
var cur_trans;
function moveMarker(i) {
  cur_trans = d3.select("#nomad");
  // more code
}
function moveToMark(i) {
  var x = spot[i][7]; // Latitude
  var y = spot[i][8]; // Longitude
  d3.select("#nomad")
    .attr("nomad-index", i);
  cur_trans = cur_trans
    .transition()
    .delay(3000)
    .duration(1000)
    .attr("cx", x)
    .attr("cy", y);
}

这将在每次调用时用新的转换覆盖cur_trans,从而确保您不会丢失任何转换。

请注意,根据代码的其余部分及其调用结构,可能会有竞争条件等,您可能需要防止。