这是一篇关于在 R 中创建蜂群图的文章。
还有用于 beeswarm plot 的 R 包。接下来的两张图片说明了该软件包提供的一些可能性:
但是,我现在尝试使用d3.js的强制导向布局来实现它。
我的计划是让自定义重力将这些点拉向一条垂直线及其适当的 y 值,并且碰撞检测使这些点彼此远离。
我有一个半工作原型:
不幸的是,我找不到解决两个问题的方法——我怀疑这确实是同一个问题:
我的观点一直重叠,至少有点重叠。
当点数在布局中心堆积后,随着防撞部队和“来到中心”部队的战斗,正在进行一场“洗牌”。
我希望这些要点能够很快就他们应该住在哪里达成一致,并且最终不会重叠。
我正在使用的强制代码(如果你想在这里而不是在 bl.ocks.org 上看到它)是:
force.on("tick", function(e) {
var q,
node,
i = 0,
n = nodes.length;
var q = d3.geom.quadtree(nodes);
while (++i < n) {
node = nodes[i];
q.visit(collide(node));
xerr = node.x - node.true_x;
yerr = node.y - node.true_y;
node.x -= xerr*0.005;
node.y -= yerr*0.9;
}
svg.selectAll("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
function collide(node) {
var r = node.radius,
nx1,
nx2,
ny1,
ny2,
xerr,
yerr;
nx1 = node.x - r;
nx2 = node.x + r;
ny1 = node.y - r;
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
// we're colliding.
var xnudge, ynudge, nudge_factor;
nudge_factor = (l - r) / l * .4;
xnudge = x*nudge_factor;
ynudge = y*nudge_factor;
node.x -= xnudge;
node.y -= ynudge;
quad.point.x += xnudge;
quad.point.y += ynudge;
}
}
return x1 > nx2
|| x2 < nx1
|| y1 > ny2
|| y2 < ny1;
};
}
这是我第一次涉足强制导向的布局,所以如果这是noobish,请道歉......