Javascript 在.each()回调(D3)中触发平滑转换

Javascript 在.each()回调(D3)中触发平滑转换,javascript,d3.js,Javascript,D3.js,我已经创建了一个在D3的选择中调用的转换。each(),但是回调和转换之间有一点延迟。我希望过渡看起来是连续的,而不是有一点延迟。我尝试过使用不同的持续时间和延迟值,但没有效果。这是相关代码 transition(); function transition() { data.map( (d) => { d.x = d3.random.normal(d['x'], 5)(); d.y = d3.random.normal(d['y'], 5)()

我已经创建了一个在D3的
选择中调用的转换。each()
,但是回调和转换之间有一点延迟。我希望过渡看起来是连续的,而不是有一点延迟。我尝试过使用不同的持续时间和延迟值,但没有效果。这是相关代码

transition();

function transition() {

    data.map( (d) => {
        d.x = d3.random.normal(d['x'], 5)();
        d.y = d3.random.normal(d['y'], 5)();
        return d;
    });

    g.selectAll('path')
        .data(data)
        .transition()
        .duration(400)
        .attr('d', (d, i) => line( getPath(d, i) ) )
        .each('end', transition);

}
正如您在中所看到的,在转换之间有一点延迟。我希望过渡看起来是连续的。我怎样才能做到这一点呢?

有几点

  • d3转换中的默认缓和不是线性的,因此您会感觉到延迟
  • 您实际上是在每个单独的路径转换完成后设置一个新的转换。
    each
    方法为选择中的每个节点回调,d3转换中没有内置的endall事件,但如下所示
  • 第一点可能是最重要的。第二点是避免不必要地重新应用转换并中断先前应用的转换。可能感觉不到,但无论如何都是良好的实践

    下面是一个工作示例

    var颜色=[
    "FFAA5C",,
    "DA727E",,
    "AC6C82",,
    "685C79",,
    “#455C7B”
    ]
    var line=d3.svg.line()
    .x((d)=>d.x)
    .y((d)=>d.y)
    .插入(“线性”);
    var svg=d3.select('body')。append('svg');
    var svgW=d3.select('svg').node().clientWidth;
    var svgH=d3.select('svg').node().clientHeight;
    var w=svgW/4;
    var h=svgH/4;
    var data=[{x:w/2,y:-h/4},{x:0,y:-h/2},{x:w/2,y:-h/4},
    {x:w/Math.PI,y:h/2.5},{x:-w/4,y:h/2.5}];
    var getPath=(d,i)=>{
    var路径=[];
    var startPoint={x:0,y:0};
    //第1点
    路径推送(起始点);
    //第2点
    路径推送(d);
    //第3点
    push(数据[i+1]| |数据[0]);
    //第4点
    路径推送(起始点);
    返回路径;
    }
    var g=svg.append('g')
    .attr('transform','translate('+svgW/2+','+svgH/2+'));
    g、 选择全部('路径')
    .数据(数据)
    .enter().append('path')
    艾特先生({
    填充:(d,i)=>颜色[i]
    });
    过渡();
    函数转换(){
    data.map((d)=>{
    d、 x=d3.随机.正态(d['x'],5)();
    d、 y=d3.随机.正态(d['y'],5)();
    返回d;
    });
    g、 选择全部('路径')
    .数据(数据)
    .transition()
    .ease(“线性”)
    .期限(50)
    .attr('d',(d,i)=>line(getPath(d,i)))
    .call(endall,function(){window.requestAnimationFrame(transition)});
    }
    函数endall(转换,回调){
    如果(transition.size()==0){callback()}
    var n=0;
    过渡
    .each(函数(){++n;})
    .each(“end”,function(){if(!--n)callback.apply(this,arguments);});
    }
    正文{
    背景色:#181818;
    显示器:flex;
    证明内容:中心;
    对齐项目:居中;
    高度:100vh;
    宽度:100%;
    }
    svg{
    溢出:可见;
    宽度:100%;
    身高:100%;
    }

    有趣的实现。另外,我完全认为线性是默认的,默认的缓和函数。感谢您深思熟虑的回复。干杯@Himmel我是受您的演示设计启发的。美好的