kol*_*bok 5 d3.js force-layout
我建立了一个力导向图,但是,对于我来说,我也有一个带有80px * 80px框的网格。我希望图形中的每个节点不仅根据现有的重力和力进行定位,而且还应位于最近的网格框的中间(不固定)。可以在d3js中执行此操作吗?
你必须应用你的自定义力量
force.on("tick", function() {
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
});
Run Code Online (Sandbox Code Playgroud)
所以没有内置的方法来做这样的事情......
因此,在您的情况下,您必须找到靠近的网格盒中心,并使用节点和盒中心之间的距离以及一些重力方程来计算 x 和 y 值。
在你的情况下
node
.attr("cx", function(d) {
d.x += f(d).x;
return d.x;
})
.attr("cy", function(d) {
d.y += f(d).y;
return d.y;
});
Run Code Online (Sandbox Code Playgroud)
其中f(d)是重力矢量,取决于盒子中心和实际节点之间的距离d。例如
var blackHole = function (d) {
var gc = {
x: 100,
y: 100
};
var k = 0.1;
var dx = gc.x - d.px;
var dy = gc.y - d.py;
return {
x: k * dx,
y: k * dy
};
};
Run Code Online (Sandbox Code Playgroud)
很难找出f(d)真正适用于多个重心的算法,因此我建议您阅读有关此类力的算法。我尝试了一些有趣的例子,但没有一个能按照你想要的方式工作。;-)
现在至少:
var grid = function (d) {
var fx = d.px % 100;
if (fx < 0)
fx += 100;
if (fx > 50)
fx -= 100;
var fy = d.py % 100;
if (fy < 0)
fy += 100;
if (fy > 50)
fy -= 100;
var k = -1;
return {
x: k * fx,
y: k * fy
};
};
Run Code Online (Sandbox Code Playgroud)
这是一个 100px 的密集网格,具有非常简单的力...但我想结果不是您所期望的,节点可以重叠,因为通过强制布局,只有具有公共链接的节点才会相互排斥,至少这是我的经验(编辑:那是因为负电荷)...我认为使用 d3 四边形构建自定义力布局可能会更容易...