Javascript 具有离散点和延迟的线图上的迭代/链式变换

Javascript 具有离散点和延迟的线图上的迭代/链式变换,javascript,select,d3.js,transition,Javascript,Select,D3.js,Transition,我创建了一个JSFIDLE 我确实有一个图形,在这个例子中是正弦波,我想沿着这条线移动一个圆(由点击事件触发),在这个图形上的某些x和y值对处停止,然后继续移动到图形的最后一点,从那里它再次跳到第一个点(理想情况下,这应该一直持续到我按下停止按钮为止) 我目前的问题是,圆只在水平方向上移动,但不在纵坐标方向上移动,而且延迟仅在一开始时可见一次 相关代码如下(整个运行示例可在上面的链接中找到): 创建圆: // the circle I want to move along the graph

我创建了一个JSFIDLE

我确实有一个图形,在这个例子中是正弦波,我想沿着这条线移动一个圆(由点击事件触发),在这个图形上的某些x和y值对处停止,然后继续移动到图形的最后一点,从那里它再次跳到第一个点(理想情况下,这应该一直持续到我按下停止按钮为止)

我目前的问题是,圆只在水平方向上移动,但不在纵坐标方向上移动,而且延迟仅在一开始时可见一次

相关代码如下(整个运行示例可在上面的链接中找到):

创建圆:

// the circle I want to move along the graph
  var circle = svg.append("circle")
                .attr("id", "concindi")
                .attr("cx", x_scale(xval[0]))
                .attr("cy", y_scale(yval[0]))
                .attr("transform", "translate(" + (0) + "," + (-1 * padding + 15) + ")")
                .attr("r", 6)
                .style("fill", 'red');
移动过程:

var coordinates = d3.zip(xval, yval);

svg.select("#concindi").on("click", function() {

    coordinates.forEach(function(ci, indi){
      //console.log(ci[1] + ": " + indi);
      //console.log(coordinates[indi+1][1] + ": " + indi);
      if (indi < (coordinates.length - 1)){
        //console.log(coordinates[indi+1][1] + ": " + indi);
        console.log(coordinates[indi + 1][0]);
        console.log(coordinates[indi + 1][1]);
        d3.select("#concindi")
          .transition()
          .delay(2000)
          .duration(5000)
          .ease("linear")
          .attr("cx", x_scale(coordinates[indi + 1][0]))
          .attr("cy", y_scale(coordinates[indi + 1][1]));
      }

    });
var坐标=d3.zip(xval,yval);
svg.select(“#concindi”)。在(“单击”,函数()上{
坐标.forEach(函数(ci,indi){
//console.log(ci[1]+“:”+indi);
//console.log(坐标[indi+1][1]+“:”+indi);
如果(独立<(坐标长度-1)){
//console.log(坐标[indi+1][1]+“:”+indi);
console.log(坐标[indi+1][0]);
console.log(坐标[indi+1][1]);
d3.选择(“#concindi”)
.transition()
.延迟(2000年)
.持续时间(5000)
.ease(“线性”)
.attr(“cx”,x_标度(坐标[indi+1][0]))
.attr(“cy”,y_比例(坐标[indi+1][1]);
}
});
我很确定我使用循环的方式是错误的。我的想法是从第一对x/y开始,然后移动到下一对(需要5秒),在那里等待2秒,然后再移动到下一对,以此类推。目前,延迟只在最初可见,然后只是水平移动


如何正确执行此操作?

为什么不使用Bostock的函数

function translateAlong(path) {
    var l = path.getTotalLength();
    return function(d, i, a) {
        return function(t) {
            var p = path.getPointAtLength(t * l);
            return "translate(" + p.x + "," + p.y + ")";
        };
    };
}
以下是演示:

//用于生成某些数据的函数
函数get_sin_val(值){
返回30*Math.sin(值*0.25)+35;
}
var宽度=400;
var高度=200;
var=50;
var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var xrange_min=0;
var xrange_max=50;
var yrange_min=0;
var yrange_max=100;
var x_scale=d3.scale.linear()
.domain([xrange\u min,xrange\u max])
.范围([填充,宽度-填充*2]);
变量y_scale=d3.scale.linear()
.domain([yrange\u min,yrange\u max])
.范围([高度-填充,填充]);
//创建数据
var xval=d3.量程(最小量程,最大量程,1);
var yval=xval.map(get_sin_val);
//只是为了方便
var坐标=d3.zip(xval,yval);
//定义线图
var lines=d3.svg.line()
.x(功能(d){
返回x_标度(d[0]);
})
.y(功能(d){
返回y_标度(d[1]);
})
.插入(“线性”);
//作图
var sin_graph=svg.append(“路径”)
.attr(“d”,线(坐标))
.attr(“笔划”、“蓝色”)
.attr(“笔划宽度”,2)
.attr(“填充”、“无”);
//我想沿着图形移动的圆
var circle=svg.append(“circle”)
.attr(“id”、“concindi”)
.attr(“变换”、“平移”(+(x_比例(xval[0]))+”,“+(y_比例(yval[0]))+”)
.attr(“r”,6)
.样式(“填充”、“红色”);
svg.select(“#concindi”)。在(“单击”,函数()上{
d3.选择(this).transition()
.持续时间(5000)
.attrween(“transform”,translateAlong(sin_graph.node());
});
//返回用于沿指定路径元素进行转换的属性。
函数translateLong(路径){
var l=path.getTotalLength();
返回函数(d,i,a){
返回函数(t){
var p=path.getPointAtLength(t*l);
返回“translate”(“+p.x+”,“+p.y+”);
};
};
}

谢谢,看起来已经不错了(投票结果).再问几个问题:由于
forEach
不起作用,是否有另一个循环可以做到这一点?在您的第二个示例中,
计数器
可能是未定义的;一旦到达图形的末尾,是否很难将
计数器
设置回0,以便它从开头开始?!关于第一个示例问题是,我想在svg的另一部分中使用
坐标中的值;如果我使用您介绍的方法,我也会收到未存储在
坐标中的坐标,这将导致代码的另一部分出现问题。javascript中的所有循环都会立即运行到末尾
counter
就是这样,一个普通的例子:你必须根据你的需要修改它。这里有一个非常简单的
if
将计数器设置回零:好的,这应该让我从我的实际例子开始;如果我遇到问题,我将打开一个新问题。非常感谢你的详细回答;对我帮助很大!