gpt4 book ai didi

javascript - 递归函数和这个 D3.JS

转载 作者:行者123 更新时间:2023-11-29 23:15:40 24 4
gpt4 key购买 nike

我有一个包含 point={x,y,nextPoint} 的点数组。目的是在每个点之间画一条线并在其上移动一个圆圈。数组中最后一个点的 nextPoint 为 null。

我能够通过在点上调用 [number of points]-1 方法来移动圆圈。这一点都不灵活,我想递归地做。我正在创建一个这样的圆圈:

function addCercle() {
var ret = svg.append("circle") //svg is declared before
.attr("cx", points[0].x) // points = the array of points
.attr("cy", points[0].y)
.attr("r", "3%");
return ret;
}

不起作用的函数是这样的:

function move(p) {
for (var i = 0; i < points.length-1; i++) {
p = d3.select(this)
.transition()
.duration(speed) //
.attr("cx", points[i].x)
.attr("cy", points[i].y);
}
}

我想这样调用它以使圆在所有线上运行:

var test = addCercle();
console.log(test);
move(test);

有人可以解释一下我在函数移动中必须更改的内容吗?还是在通话中?

最佳答案

如果你想让你的move函数递归,你需要从它自身内部调用它。一如既往,有很多方法可以做到这一点,但如果你有一个点数组,你可以传入点数组,或者传入点数组中的当前位置。以下是您传入点数组的示例:

// p is the element being moved, points is the array of points
function move(p, points) {
if (points.length > 0) { // one point or more in the array => move the element
p.transition()
.duration(speed) //
.attr("cx", points[0].x)
.attr("cy", points[0].y)
// when the transition ends, call this function with the array of points minus the first point
.on('end', () => move(p, points.slice(1)));
}
}

const arrayOfPoints = [{x: 100, y: 200},{x: 200, y: 200}, {x: 300, y: 300}]
// call the function
move(circle, arrayOfPoints);

工作示例,我生成了一个点数组,然后沿着这些点描述的路径移动了一个圆:

var svg = d3.select('svg'),
radius = 100,
pts = d3.range(0, 2 * Math.PI, 0.01 * Math.PI) // NOTE: this produces an array
.map( d => d3.pointRadial(d, radius) ),// of arrays; slightly different
// to your data structure
speed = 50

function addCercle(points) {
var ret = svg
.append('g')
.attr('transform', 'translate(150,150)')
.append("circle") //svg is declared before
.attr("cx", points[0][0]) // points = the array of points
.attr("cy", points[0][1])
.attr("r", "3%");
return ret;
}

function move(p, points) {
if (points.length > 0) {
p.transition()
.duration(speed) //
.attr("cx", points[0][0])
.attr("cy", points[0][1])
.on('end', () => move(p, points.slice(1)));
}
}

var test = addCercle(pts);
move(test, pts);
<script type="text/javascript" src="http://d3js.org/d3.v5.js"></script>
<svg width="960" height="960"></svg>

您可以通过补间过渡产生更平滑的路径和动画。

这是一个略有改动的示例,它遵循相同的原则,但使用您在问题中描述的数据结构;所有改变的是函数设置 cxcy 值的方式,以及它如何决定是否有更多的点要显示。

var svg = d3.select('svg'),
radius = 300,
pts = d3.range(0, 2 * Math.PI, 0.01 * Math.PI).map( d => d3.pointRadial(d, radius) ),
speed = 50

function makeWeirdDataStructure ( pts ) {
return {
x: pts[0][0],
y: pts[0][1],
nextPt: pts.length > 1 ? makeWeirdDataStructure( pts.slice(1) ) : null
}
}

function addCercle(points) {
var ret = svg
.append('g')
.attr('transform', 'translate(400,400)')
.append("circle") //svg is declared before
.attr("cx", points.x) // points = the array of points
.attr("cy", points.y)
.attr("r", "3%");
return ret;
}

function move(p, points) {
if ( points !== null ) {
p.transition()
.duration(speed) //
.attr("cx", points.x)
.attr("cy", points.y)
.on('end', () => move(p, points.nextPt));
}
}

var wds = makeWeirdDataStructure(pts)
var test = addCercle(wds);
move(test, wds);
<script type="text/javascript" src="http://d3js.org/d3.v5.js"></script>
<svg width="960" height="960"></svg>

关于javascript - 递归函数和这个 D3.JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52891619/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com