javascript - D3 Javascript - 这些行不会移动

标签 javascript html animation d3.js

正在从事 D3 项目,并成功地为一些随机移动的圆圈制作了动画。我想在它们和某个点之间画一条线(我已经这样做了),但这些线似乎没有随着圆圈更新!

我的印象是,由于 D3 的数据绑定(bind),UI 总是会反射(reflect)数据,所以我需要做的就是修改底层数据!

请参阅下面的我的问题(对于冗长的代码帖子,我深表歉意)。

function play() {
	run = !run;
}

var run = false;

var canvas = d3.select('html')
		.append('svg')
		.attr('width', screen.width)
		.attr('height', screen.height);

var text = canvas.append("svg:text")
		.attr("x", 300)
		.attr("y", 100)
		.attr('id', 'fps');
	
var start = Date.now(),
	frames = 0;

function agent(_x, _y, _vx, _vy, _color) {
	this.x = _x;
	this.y = _y;
	this.vx = _vx;
	this.vy = _vy;
	this.color = _color;
	this.lines = [];
}

function line(_x1, _y1, _x2, _y2) {
	this.x1 = _x1;
	this.y1 = _y1;
	this.x2 = _x2;
	this.y2 = _y2;
}

var data = d3.range(3).map(function() {
	return new agent(
		(Math.random()-0.5)*5,
		(Math.random()-0.5)*5,
		0,
		0,
		'rgb(255, 0, 213)');
});

data.forEach(function(d) {
	d.lines.push(new line(d.x, d.y, 0, 0));
});

var x = d3.scaleLinear()
	.domain([-5, 5])
	.range([0, screen.width/3]);

var y = d3.scaleLinear()
	.domain([-5, 5])
	.range([0, screen.height/3]);

var circles = canvas.selectAll('circle')
		.data(data)
		.enter().append('circle')
		.attr('cx', function(d) {
			return x(d.x);
		})
		.attr('cy', function(d) {
			return y(d.y);
		})
		.attr('r', 5)
		.attr('fill', function(d) {
			return d.color;
		});

var lines = canvas.selectAll('line')
		.data(data)
		.enter().append('line')
		.attr('x1', function(d) {
			return x(d.lines[0].x1);
		})
		.attr('y1', function(d) {
			return y(d.lines[0].y1);
		})
		.attr('x2', function(d) {
			return x(d.lines[0].x2);
		})
		.attr('y2', function(d) {
			return y(d.lines[0].y2);
		})
		.attr('stroke', 'white')
		.attr('stroke-width', 1);

//initializes circles at center to begin
render();

d3.timer(function() {
	//Update FPS
	var now = Date.now(), duration = now - start;
	text.text(~~(++frames * 1000 / duration));
	if (duration >= 1000) frames = 0, start = now;

	if (run) {
		rendezvous();
		render();
	}
});

function render() {
	circles.attr('transform', function(d) {
		return 'translate(' + d.x + ',' + d.y + ')';
	}).attr('fill', function(d) {
		return d.color;
	});
    //Transform the line here???
}


function rendezvous() {
	data.forEach(function(d) {
		d.vx += (Math.random()-0.5)*0.5;
		d.vy += (Math.random()-0.5)*0.5;
		d.x += d.vx;
		d.y += d.vy;

		d.lines[0].x1 = d.x;
		d.lines[0].y1 = d.y;
		d.lines[0].x2 = 0;
		d.lines[0].y2 = 0;
	});
}
body {
	background-color: rgb(39, 40, 34);
	position: absolute;
}

h1 {
	font-family: Helvetica;
	color: white;
}

#fps {
	font-family: Helvetica;
	fill: white;
}
<!DOCTYPE html>
<meta charset="utf-8">
<html>
	<head>
		<link rel="stylesheet" type="text/css" href="styles.css">
		<script src="https://d3js.org/d3.v4.js"></script>
	</head>
	<body id = "body">
		<h1>Swarm Demo: </h1>
		<button type="button"onclick = "play();">Play/Pause</button>
	</body>
	<script src="js/rendezvous.js" type="text/javascript"></script>
</html>

最佳答案

这不是最佳解决方案,但考虑到您现在的代码,这是一个可能解决方案:

if (run) {
    lines.attr('x1', function(d) {
            return +(d3.select(this).attr("x1")) + d.vx;
        })
        .attr('y1', function(d) {
            return +(d3.select(this).attr("y1")) + d.vy;
        })
}

这是演示:

function play() {
	run = !run;
}

var run = false;

var canvas = d3.select('html')
		.append('svg')
		.attr('width', screen.width)
		.attr('height', screen.height);

var text = canvas.append("svg:text")
		.attr("x", 300)
		.attr("y", 100)
		.attr('id', 'fps');
	
var start = Date.now(),
	frames = 0;

function agent(_x, _y, _vx, _vy, _color) {
	this.x = _x;
	this.y = _y;
	this.vx = _vx;
	this.vy = _vy;
	this.color = _color;
	this.lines = [];
}

function line(_x1, _y1, _x2, _y2) {
	this.x1 = _x1;
	this.y1 = _y1;
	this.x2 = _x2;
	this.y2 = _y2;
}

var data = d3.range(3).map(function() {
	return new agent(
		(Math.random()-0.5)*5,
		(Math.random()-0.5)*5,
		0,
		0,
		'rgb(255, 0, 213)');
});

data.forEach(function(d) {
	d.lines.push(new line(d.x, d.y, 0, 0));
});

var x = d3.scaleLinear()
	.domain([-5, 5])
	.range([0, screen.width/3]);

var y = d3.scaleLinear()
	.domain([-5, 5])
	.range([0, screen.height/3]);

var circles = canvas.selectAll('circle')
		.data(data)
		.enter().append('circle')
		.attr('cx', function(d) {
			return x(d.x);
		})
		.attr('cy', function(d) {
			return y(d.y);
		})
		.attr('r', 5)
		.attr('fill', function(d) {
			return d.color;
		});

var lines = canvas.selectAll('line')
		.data(data)
		.enter().append('line')
		.attr('x1', function(d) {
			return x(d.lines[0].x1);
		})
		.attr('y1', function(d) {
			return y(d.lines[0].y1);
		})
		.attr('x2', function(d) {
			return x(d.lines[0].x2);
		})
		.attr('y2', function(d) {
			return y(d.lines[0].y2);
		})
		.attr('stroke', 'white')
		.attr('stroke-width', 1);

//initializes circles at center to begin
render();

d3.timer(function() {
	//Update FPS
	var now = Date.now(), duration = now - start;
	text.text(~~(++frames * 1000 / duration));
	if (duration >= 1000) frames = 0, start = now;

	if (run) {
		rendezvous();
		render();
	}
});

function render() {
	circles.attr('transform', function(d) {
		return 'translate(' + d.x + ',' + d.y + ')';
	}).attr('fill', function(d) {
		return d.color;
	});
    //Transform the line here???
  	if(run){
  lines.attr('x1', function(d) {
			return +(d3.select(this).attr("x1")) + d.vx;
		})
		.attr('y1', function(d) {
			return +(d3.select(this).attr("y1")) + d.vy;
		})
	}
}


function rendezvous() {
	data.forEach(function(d) {
		d.vx += (Math.random()-0.5)*0.5;
		d.vy += (Math.random()-0.5)*0.5;
		d.x += d.vx;
		d.y += d.vy;

		d.lines[0].x1 = d.x;
		d.lines[0].y1 = d.y;
		d.lines[0].x2 = 0;
		d.lines[0].y2 = 0;
	});
}
body {
	background-color: rgb(39, 40, 34);
	position: absolute;
}

h1 {
	font-family: Helvetica;
	color: white;
}

#fps {
	font-family: Helvetica;
	fill: white;
}
<!DOCTYPE html>
<meta charset="utf-8">
<html>
	<head>
		<link rel="stylesheet" type="text/css" href="styles.css">
		<script src="https://d3js.org/d3.v4.js"></script>
	</head>
	<body id = "body">
		<h1>Swarm Demo: </h1>
		<button type="button"onclick = "play();">Play/Pause</button>
	</body>
	<script src="js/rendezvous.js" type="text/javascript"></script>
</html>

关于javascript - D3 Javascript - 这些行不会移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41089848/

相关文章:

javascript - JS 在单行代码中创建一个包含 0 到 255(包括)随机数的 3 个元素的数组

javascript - stub 返回 promise 的私有(private)函数

html - 如何在 HTML5 中为 Safari 8.0 添加书签图标?

wpf - StopStoryboard 不会...停止 BeginStoryboard

javascript - 将值作为 onchange() 事件中定义的函数的参数传递

javascript - 如何在 something append 上调用函数

html - 确保内联项始终出现在最后

javascript - Uncaught ReferenceError : phone is not defined javascript error

javascript - Raphael 动画上的工具提示 - 为什么它不起作用?

html - animate.css:如何让 css 动画只在第一次运行?