2017-05-08 80 views
1

我有一个图表,可能有1000个节点具有非常嵌套的结构,所以当我单击一个节点时,它会添加更多的子节点,等等。有些孩子可以有多个父母,有些孩子可以有不同父母的兄弟姐妹。我已经把一个简单的fiddle放在一起来演示我到目前为止的样子,为了简洁起见,只有两个级别的数据。如何在D3中组织节点位置Force布局

这是我的仿真设置...

var simulation = d3.forceSimulation(mergedData.nodes) 
    .velocityDecay(0.55) 
    .force('charge', d3.forceManyBody().strength(-100).distanceMin(10000)) 
    .force('collide', d3.forceCollide(25)) 
    .force('link', d3.forceLink(mergedData.links) 
    .id((d) => { return d.id; }) 
    .distance(400) 
    .strength(0.1) 
) 
    .force('y', d3.forceY(height/2)) 
    .force('x', d3.forceX(width/2)) 
    .on('tick', ticked); 

我试图安排节点的布局,使父>孩子的关系更加清晰。理想情况下,我想给用户两个选择,一个树状结构,和径向/分组结构如下所示:

illustration to demonstrate node layout

我真的很挣扎,看我怎么去这样做,所以任何帮助将不胜感激。

谢谢!

P.S.我使用的是V4 API

回答

1

您可以组织节点作为使用d3.forceY左图像,这在:

沿着创建对于给定位置y,y轴新的定位力。

.force("yPosition", d3.forceY(function(d){ 
    return d.r === 20 ? 100 : 300 
}).strength(2)) 

进出口使用比推荐一个strength更高(:

因此,使用您的代码,则可以例如位置100在垂直方向的红色圆圈和灰色圆圈在300与坐标在0和1之间)只是为了使圆圈在y位置更好地对齐。

这是你更新的提琴:https://jsfiddle.net/rLf054zy/

PS:我改变了你mergedData阵列,这是不正确的合并d1d2

+0

谢谢!一旦你点击了一个红色圆圈,数据就会合并,但是你的更新会使它更加明显。也感谢您的答案。我在tick函数中一直搞乱节点'cx'和'cy'属性,没有太多的运气。 – DanV

+0

@DanV对不起,我错过了那个事件处理程序。关于'cx'和'cy'属性,你可以将'd3.forceX/Y'与scale结合起来。例如,这是一个强制导向的图表,我将它们组合在一起:https://gf.neocities.org/ohp/ohp.html –

+0

再次感谢@Gerardo!这真的很有帮助。我会给你的答案一个绿色的勾号,但我想先得到更多的答案,并希望得到一些洞察其他布局。 – DanV