d3力导向图向下力模拟

nor*_*lli 6 javascript tree svg d3.js force-layout

也许这不是最好的方法,但是现在我已经走下了兔子洞,我想知道它是如何运作的.我正在尝试使用d3来创建一个树,其中节点将向下沉降,就像有重力一样.我希望这一点,以及每个节点的电荷以及绳索中的张力将使它最终看起来像我想象的那样,并将其平衡.我试图在d3中模拟这种恒定的向下加速度,但我是d3的初学者,并且不知道具体如何.我也遇到了模拟停止运行的问题,并且d3.timer(force.resume)没有帮助.

基本上,我希望将一个根节点固定在某个位置,如枢轴,子节点从它上面脱离,重力,电荷和张力存在,这样孩子们就会自动解决并平衡自己成为树状结构.

Viv*_*idD 22

强制定向模拟是布局树,图或图形的好方法.此方法用于许多开源和商业库和应用程序,因此D3只是其中之一.此外,该主题不断吸引应用数学家的注意.

我只是想告诉你这是一个很大的话题.如果只将自己限制在D3,那么仍然有很多方法可以做你在问题中描述的内容.由于这个答案必须有一个合理的长度,我将尝试通过3个D3示例向您展示一些亮点.我将从一个简单的强制导向树布局示例开始(这不是你想要的,它很简单),每个例子都将建立在之前,并且将更接近你想要实现的目标.

例1

链接到jsfiddle

在此输入图像描述

这是通过D3力布局以径向方式布置的树的基本示例.您确实需要了解所使用的所有代码.我在这里只提一些亮点:

  • function getData()返回一个测试树(它是所谓的"flare"测试树的一个方便的子集);
  • 函数flatten()将树对象转换为数组,这是初始化D3强制布局所需的格式;
  • 初始化所有节点的位置(否则D3力布局会表现得有点奇怪和不可预测);
  • 根节点位置初始化为图的中心,根节点声明为固定 ;
  • 提供了函数"ontick",它只是在模拟过程中完全按照它们的行为绘制链接和节点;
  • D3力布局算法初始化为D3重力0.2和D3充电-200;
  • D3力布局算法通过调用其方法start()来启动.

如果您有与此示例相关的其他问题,请与我们联系.我知道对于没有D3经验的人来说代码看起来有点奇怪 - 但是,实际上,一旦你得到D3力布局就知道它非常简单,易于理解.您可以使用不同的D3重力和D3充电,以更好地理解为什么选择特定值0.2和-200.

当然,这不是你想要的,但它可以作为我们的"规范范例".

例2

链接到jsfiddle

在此输入图像描述

Codewise,这个例子与previus有两点不同:

  • 根节点位置初始化为(宽度/ 2,100)而不是(宽度/ 2,高度/ 2) - 这是"悬挂"布局的根的自然位置
  • 自定义力在"ontick"函数中定义如下:

var ky = e.alpha;

links.forEach(function(d, i) {

d.target.y += (d.target.depth * 100 - d.target.y) * 5 * ky;

});

该自定义力将相同深度的节点吸引到相同的水平线.这足以产生图中的图表.

但是,您可以注意到图中某些节点的不自然的安排 - 通常,它们看起来不像是从父节点"悬挂".下一个例子将尝试解决这个问题.

例3

链接到jsfiddle

在此输入图像描述

这看起来比以前的例子更自然.

在这个例子中,新的只是一个自定义力量:一个将所有父母"居中"到他们孩子的水平位置中间的力量.您可以在"ontick()"函数中轻松找到负责该代码的代码.

这看起来更接近你想要的东西.我并不是说这是一个满足您需求的理想布局.但是,它可以作为一个很好的起点.一旦理解了所有这些示例,您就可以修改它们,并且如果需要,可以根据不同的自定义力量创建不同的模拟.

因此,最后一个例子不是基于物理引力的模拟,但它具有类似于物理引力的效果.如果你想模拟物理引力,这将需要更多的代码 - 但如果效果几乎相同,你真的需要它吗?

希望这可以帮助.如果您有疑问,需要澄清等,请告诉我.