Javascript 了解d3多焦点部队布局

Javascript 了解d3多焦点部队布局,javascript,d3.js,Javascript,D3.js,我试图理解这个美丽的例子是如何运作的 我看到聚类是通过节点的颜色来完成的,但我对碰撞检测函数中的线条感到困惑 r = d.radius + quad.point.radius + (d.color !== quad.point.color) * padding; 如何“添加”颜色“d.color”和“quad.point.color”比较的结果?我认为这只会返回一个真/假?不管怎样,我不确定我只遵循这个颜色的引用是否会产生按颜色聚类的预期效果 无论如何,我还没有找到任何关于碰撞检测功能工作原

我试图理解这个美丽的例子是如何运作的

我看到聚类是通过节点的颜色来完成的,但我对碰撞检测函数中的线条感到困惑

r = d.radius + quad.point.radius + (d.color !== quad.point.color) * padding;
如何“添加”颜色“d.color”和“quad.point.color”比较的结果?我认为这只会返回一个真/假?不管怎样,我不确定我只遵循这个颜色的引用是否会产生按颜色聚类的预期效果

无论如何,我还没有找到任何关于碰撞检测功能工作原理的逐行描述,所以我真的希望这里有人能很好地理解它,帮助我解释这一点

我最终想要实现的就是通过另一个非数字节点属性(例如,d.person\u name!==quad.point.person\u name)使示例适应集群


谢谢

您询问的线路正在计算节点之间的允许距离,将节点之间的距离(
l
)与
r
进行比较,以确定
d
四点之间是否存在冲突。如果节点具有相同的颜色,则将值
padding
添加到节点之间的允许距离中。布尔结果被上下文强制为数字类型。
与其假设JS做了什么,不如打开浏览器工具,只需键入表达式即可查看结果


但是碰撞检测不涉及聚类,这是由这段代码处理的

// Move nodes toward cluster focus.
function gravity(alpha) {
  return function(d) {
    d.y += (d.cy - d.y) * alpha;
    d.x += (d.cx - d.x) * alpha;
  };
}
如果您有一些数据,并且希望使用相同的代码按特定属性对它们进行分组,则需要向数据中添加
cx
cy
属性,以便具有相同属性值(该值不需要是数字)的项具有相同的
cx
cy


示例(的修改版本)
var宽度=600,
高度=200,
padding=6,//节点之间的间隔
最大半径=6;
var n=200,//节点总数
姓名=[“吉文斯”、“克劳德”、“兰尼斯特”、“巴拉森”、“斯塔克”],
m=names.length;//不同簇的数目
var color=d3.scale.category10()
.域(d3.范围(m));
var x=d3.scale.ordinal()
.域名
.范围点([0,宽度],1),
图例=d3.svg.axis()
.比例(x)
.东方(“顶部”)
var节点=d3.range(n).map(函数(){
var i=数学地板(数学随机()*m),
v=(i+1)/m*-Math.log(Math.random());
返回{
半径:数学sqrt(v)*最大半径,
颜色:颜色(i),
cx:x(名称[i]),
cy:高度/2
};
});
var-force=d3.layout.force()
.节点(节点)
.尺寸([宽度、高度])
.重力(0)
.收费(0)
.on(“滴答”,滴答)
.start();
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度),
gLegend=svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0“+高度*0.9+”))
.通话(图例);
gLegend.selectAll(“.tick text”)
.attr(“填充”,函数(d,i){
返回颜色(i);
});
var circle=svg.selectAll(“circle”)
.数据(节点)
.enter().append(“圆”)
.attr(“r”,函数(d){
返回d.radius;
})
.样式(“填充”,功能(d){
返回d.color;
})
.呼叫(强制拖动);
功能勾号(e){
圆圈
.每个(重力(.2*e.alpha))
.每个(碰撞(.5))
.attr(“cx”,功能(d){
返回d.x;
})
.attr(“cy”,函数(d){
返回d.y;
});
}
//将节点移向群集焦点。
函数重力(α){
返回函数(d){
d、 y+=(d.cy-d.y)*α;
d、 x+=(d.cx-d.x)*α;
};
}
//解决节点之间的冲突。
函数碰撞(alpha){
var四叉树=d3.geom.quadtree(节点);
返回函数(d){
var r=d.半径+最大半径+填充,
nx1=d.x-r,
nx2=d.x+r,
ny1=d.y-r,
ny2=d.y+r;
四叉树访问(函数(四叉树,x1,y1,x2,y2){
if(quad.point&&(quad.point!==d)){
var x=d.x-四点x,
y=d.y-四点y,
l=数学sqrt(x*x+y*y),
r=d.radius+quad.point.radius+(d.color!==quad.point.color)*填充;
if(lnx2 | x2ny2 | y2
圆圈{
行程:#000;
}
.x轴路径{
填充:无;
}
.x轴文本{
字体系列:纸莎草、Console、Menlo、摩纳哥、Lucida Console、Liberation Mono、DejaVu Sans Mono、Bitstream Vera Sans Mono、Courier New、monospace、Sans serif;
}
身体{
背景色:黑色;
}

谢谢你的回答,酷蓝-真的很有帮助!对于非数值属性,只需再问一个问题。似乎我所需要做的就是创建一个新的比例(而不是比例“x”),其范围与x相同,但域不同,以覆盖d.person_name的可能值,然后在节点定义中为cx属性指定“cx:personScale(d.person_name)”。我只是不知道如何用刻度来做,在API中找不到。例如,如果我有10个名字,其中5个是Bob,5个是John,那么我能把它转换成0-1的范围吗@d3wannabe可以用一个完整的示例查看我的更新答案,包括分组依据的序号。@d3wannabe,不用担心,我玩得很开心:)