Javascript 具有离散点和延迟的线图上的迭代/链式变换
我创建了一个JSFIDLE 我确实有一个图形,在这个例子中是正弦波,我想沿着这条线移动一个圆(由点击事件触发),在这个图形上的某些x和y值对处停止,然后继续移动到图形的最后一点,从那里它再次跳到第一个点(理想情况下,这应该一直持续到我按下停止按钮为止) 我目前的问题是,圆只在水平方向上移动,但不在纵坐标方向上移动,而且延迟仅在一开始时可见一次 相关代码如下(整个运行示例可在上面的链接中找到): 创建圆:Javascript 具有离散点和延迟的线图上的迭代/链式变换,javascript,select,d3.js,transition,Javascript,Select,D3.js,Transition,我创建了一个JSFIDLE 我确实有一个图形,在这个例子中是正弦波,我想沿着这条线移动一个圆(由点击事件触发),在这个图形上的某些x和y值对处停止,然后继续移动到图形的最后一点,从那里它再次跳到第一个点(理想情况下,这应该一直持续到我按下停止按钮为止) 我目前的问题是,圆只在水平方向上移动,但不在纵坐标方向上移动,而且延迟仅在一开始时可见一次 相关代码如下(整个运行示例可在上面的链接中找到): 创建圆: // the circle I want to move along the graph
// 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
将计数器设置回零:好的,这应该让我从我的实际例子开始;如果我遇到问题,我将打开一个新问题。非常感谢你的详细回答;对我帮助很大!