Javascript 在循环d3.js转换中使用选择索引

Javascript 在循环d3.js转换中使用选择索引,javascript,html,svg,d3.js,Javascript,Html,Svg,D3.js,使用d3.js中的转换,我试图使用其中元素的索引更新选择的属性(即(d,I)=>(t=>f(I,t))。第一次运行动画效果很好,但是当第二次运行循环时,传递到我的转换函数中的索引i对于每个元素默认为0,因此每个元素开始以相同的方式运行。我包含了一个最小的演示(请注意,虽然有更好的方法解决这个实际问题,但我正在研究的实际问题并非如此) 取消注释console.log(i)我注释掉的地方确认了问题 我觉得d3.js的内部工作机制有些东西我在这里遗漏了。我(模糊的)解释是,第二次调用d3.active

使用d3.js中的转换,我试图使用其中元素的索引更新选择的属性(即
(d,I)=>(t=>f(I,t)
)。第一次运行动画效果很好,但是当第二次运行循环时,传递到我的转换函数中的索引
i
对于每个元素默认为0,因此每个元素开始以相同的方式运行。我包含了一个最小的演示(请注意,虽然有更好的方法解决这个实际问题,但我正在研究的实际问题并非如此)

取消注释
console.log(i)
我注释掉的地方确认了问题

我觉得d3.js的内部工作机制有些东西我在这里遗漏了。我(模糊的)解释是,第二次调用
d3.active(this)
时,事情就偏离了轨道,导致选择以某种方式被分解为其组成部分


让svg=d3.选择(“svg”)
.attr(“宽度”,700)
设pts=[0,10,20,30,40,50]
让rects=svg.append(“g”)
.selectAll(“rect”)
.数据(临时秘书处)
.输入()
.append(“rect”)
.attr(“x”,d=>d*12)
.attr(“y”,0)
.attr(“宽度”,100)
.attr(“高度”,100)
.attr(“不透明度”,(d,i)=>i/10)
rects.transition()
.持续时间(3000)
.ease(d3.easeLinear)
.on(“开始”,函数重复(){
d3.主动(本)
.attrTween(“不透明度”,(d,i)=>{
返回函数(t){
//控制台日志(i)
返回i/10+t
}
})
.transition()
.持续时间(3000)
.ease(d3.easeLinear)
.attrTween(“不透明度”,(d,i)=>{
返回函数(t){
返回1-t*(1-i/10)
}
})
.transition()
.on(“开始”,重复)
})

对于不同的初始不透明度,使用一个函数,根据初始不透明度在一个时间间隔内将非零不透明度转换为零,然后使用恒定超时将其转换回1:

const transitOpacity = el => {
      const opacity = parseFloat(el.attr('opacity'));
      let delay, target;
      if (opacity > 0) {
        delay = 3000 * opacity;
        target = 0;
      }
      else {
        delay = 3000;
        target = 1;
      }
      el.transition().duration(delay).attr('opacity', target);
      setTimeout(() => transitOpacity(el), delay);
    }
请参见代码段中的工作原理:

让svg=d3.select(“svg”).attr(“width”,700)
设pts=[0,10,20,30,40,50]
常量传输容量=el=>{
const opacity=parseFloat(el.attr('opacity'));
让延迟,目标;
如果(不透明度>0){
延迟=3000*不透明度;
目标=0;
}
否则{
延迟=3000;
目标=1;
}
el.transition().duration(delay).attr('opacity',target));
设置超时(()=>传输容量(el),延迟);
}
让rects=svg.append(“g”)
.selectAll(“rect”)
.数据(临时秘书处)
.输入()
.append(“rect”)
.attr(“x”,d=>d*12)
.attr(“y”,0)
.attr(“宽度”,100)
.attr(“高度”,100)
.attr(“不透明度”,(d,i)=>i/pts.长度)
.each(函数({
常数el=d3。选择(此);
过渡容量(el);
})