javascript - d3 力有向图向下力模拟

标签 javascript svg d3.js tree force-layout

也许这不是最好的方法,但现在我已经陷入困境,我想知道它是如何工作的。我正在尝试使用 d3 创建一棵树,节点将向下沉降,就像有重力一样。我希望这个,连同每个节点的电荷和绳索的张力,使它最终看起来像我想象的那样,它会自我平衡。我试图在 d3 中模拟这种持续向下的加速度,但我是 d3 的初学者,不知 Prop 体如何。我也遇到了模拟停止运行的问题,而 d3.timer(force.resume) 没有帮助。

所以本质上,我想让一个根节点像枢轴一样固定在某个位置,子节点从它上面脱落,重力、电荷和张力存在,这样子节点就会自动安定下来并平衡成一个树状结构。

最佳答案

力导向模拟是布置树、图表或图形的好方法。这种方法用于许多开源和商业库和应用程序,因此 D3 只是其中之一。此外,这个话题也不断受到应用数学家的关注。

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

示例 1

link to jsfiddle

enter image description here

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

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

  • 如果您有与此示例相关的其他问题,请告诉我。我知道对于没有 D3 经验的人来说,代码看起来有点奇怪 - 但实际上,一旦您了解 D3 强制布局,它就非常简单且易于理解。您可以玩不同的 D3 重力和 D3 电荷,以更好地理解为什么选择特定值 0.2 和 -200。

    这当然不是您想要的,但它可以作为我们的“规范示例”。

    示例 2

    link to jsfiddle

    enter image description here

    Codewise,这个例子与之前的例子有两点不同:
  • 根节点位置初始化为 (width/2, 100) 而不是 (width/2, height/2) - 这是“悬挂”布局的根节点的自然位置
  • 自定义力在“ontick”函数中在以下几行中定义:
  • var ky = e.alpha;links.forEach(function(d, i) {d.target.y += (d.target.depth * 100 - d.target.y) * 5 * ky;});
    这种自定义力会将相同深度的节点吸引到相同的水平线上。这足以产生图中的图表。

    但是,您会注意到图中某些节点的排列有些不自然——通常,它们看起来不像是“悬挂”在父节点上。下一个示例将尝试解决该问题。

    示例 3

    link to jsfiddle

    enter image description here

    这看起来比前面的例子更自然。

    这个例子中的新功能只是另一种自定义力量:一种将所有 parent “集中”到他们 child 水平位置中间的力量。您可以在“ontick()”函数中轻松找到对此负责的代码。

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

    所以,最后一个例子不是基于物理重力的模拟,而是具有类似于物理重力的效果。如果你想模拟物理重力,这将需要更多的代码——但你真的需要它吗,如果效果几乎一样?

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

    关于javascript - d3 力有向图向下力模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21529242/

    相关文章:

    javascript - 在D3中如何仅对特定路径启用缩放?

    javascript - 有没有更好的方法将 JSON 数据包转换为查询字符串?

    javascript - Codeigniter 欢迎页面 JavaScript 通知程序

    javascript - 具有行组的 JQuery 斑马条纹表

    javascript - 找到 svg 形状的中心

    javascript - 在 React 中用内联 svg 替换图像元素

    javascript - 如何在 d3js 转换期间删除轴路径/线

    javascript - 使用 d3 js 引用不同的元素集

    javascript - 在 <Enter> 上提交 jQuery UI 对话框

    javascript - 从 D3 v3 更新,没有错误,但输出 SVG 路径不可见