我制作了一个交互式气泡图,我正致力于将数据拆分为两组,这两组移动到屏幕的两侧。我使用中心力进行模拟,因为我认为它比使用forceX和forceY更好,更一致地显示数据。但是,我在分割数据方面遇到了麻烦。
我有这样的想法,因为你可以将一个匿名函数作为参数传递给forceX来确定一个节点是向左还是向右移动,理论上你可以对定心力中的x值做同样的事情。我的中心部队代码如下:
var forceCenterSplit = d3.forceCenter(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}, height/2)
为了比较,下面是执行相同操作的forceX的代码:
var forceXsplit = d3.forceX(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}).strength(.05);
不幸的是,控制台说"意外的值NaN解析cx属性。"当我运行定心力并将所有数据推到cx = 0(默认值)时。
我错过了一些基本的东西吗?你能否将匿名函数作为参数传递给定心力?如果没有,有更好的方法吗?
谢谢!
// nicer looking splitting forces that use forceCenter
var forceCenterCombine = d3.forceCenter(width/2, height/2);
var forceCenterSplit = d3.forceCenter(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}, height/2);
// simple splitting forces that only use forceX
var forceXSplit = d3.forceX(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}).strength(.05);
var forceXCombine = d3.forceX(width/2).strength(.05);
// collision force to stop the bubbles from hitting each other
var forceCollide = d3.forceCollide(function(d){
console.log("forceCollide");
return radiusScale(d[radiusParam]) + 1;
}).strength(.75)
// This code is for the simulation that combines all the forces
var simulation = d3.forceSimulation()
.force("center", forceCenterCombine)
.force("collide", forceCollide)
.on('end', function(){console.log("Simulation ended!");});
function ticked() {
circles
.attr("cx", function(d){
return d.x;
})
.attr("cy", function(d){
return d.y;
})
}
var splitFlag = false;
// dynamically divide the bubbles into two (or probably more later on) groups
$scope.split = function() {
// split them apart
if (!splitFlag){
console.log("splitForce");
simulation.force("center", forceXSplit)
.force("y", d3.forceY(height/2).strength(.05))
.alphaTarget(.25)
.restart();
splitFlag = true;
}
// bring them back together
else {
console.log("combineForce");
simulation.force("center", forceCenterCombine)
.alphaTarget(.25)
.restart();
splitFlag = false;
}
};
答案 0 :(得分:2)
不幸的是,答案似乎是没有。
由于d3.forceCenter
的本质,("将匿名函数作为参数" 传递)是不可能的。 API说:
中心力均匀地转换节点,使得所有节点的平均位置(如果所有节点具有相等的权重,则为质心)位于给定位置⟨x,y⟩。 (强调我的)
因此,这里没有访问者功能的空间。另一方面forceX
和forceY
......
将坐标访问者设置为指定的数字或功能。 (再次强调我的)
......并且可能最适合你。