如何在 D3.js 中制作多个组网络节点的凸包

How can I make convex hulls of multiple group network nodes in D3.js

我正在尝试制作网络图,其中节点按 属性 分组,并且它们按组捆绑在一起,同时具有位置(力布局)和使用凸包。喜欢 this 但没有点击 collapse/expand。那个model/code对于初学者来说有点太复杂了,难以剖析和学习。

我的问题可以简单的说:是否有网络+分组能力的示例代码,包括节点在多个组中的可能性?

有时候一组会只有一个节点,少于三个基本凸包就不行了。上面的示例对此有一个修复(我不明白),this one 创建不可见节点也可能更容易。

组可以多层嵌套。 This tutorial 提供了使用 d3.nest() 在层次结构中获取数据所需的所有信息。但它可能不是层次结构,它可能是一个节点在多个组中并且需要位于正确的外壳和位置中。一些节点将不在任何组中,但仍会连接在网络中。

我知道力布局中的力是相加的,所以让组和链接以简单的方式影响节点位置应该不是问题,但我还没有看到一个简单的例子这个的。我的方法是将网络连接添加到多焦点示例中,看看我是否可以让它工作。

作为奖励,节点不应重叠,对于分层元素,基础层节点应围绕一个圆圈放置,以便多个组中的节点位于这些组之间 like this。我现在提到这些是因为对这些功能的渴望可能会影响上述需求的最佳解决方案。

我将从 this JSFiddle 开始进行此构建;随着我自己在代码上取得进展,我将继续更新和完善这个问题。我将不胜感激任何指向比可折叠代码更接近我想要的代码的指针,对 D3 的 limitations/problems 的警告(比如需要 1-2 个节点的凸包的变通方法),以及提供一个的代码这些功能以易于理解和模块化的方式实现最终目标。真的,感谢任何帮助。

虽然这个问题在过去一周没有引起太多关注,但希望这个答案对某些人有用。我设法为 linkDistance 使用了一个函数,该函数从大开始并缩小,具体取决于 (1) 源和目标是否在同一集合中,以及 (2) 该集合的级别——即组或子组或子子组。

基本的解决思路来自only example I could find of this capability。我实际使用的 linkDistance 函数是一种有点简单的方法,但它可以很好地完成工作并且可以很容易地适应许多其他人的许多其他目的(我希望如此)。根据您的分组,您可能希望通过我在此处使用的功能调整 link 的其他功能(如颜色)。

force
    .nodes(graph.nodes)
    .links(graph.links)
    .linkDistance(function(thisLink) { 
        var myLength = 100, theSource = thisLink.source, theTarget = thisLink.target;
        groupNodes.forEach(function(groupList) { 
            if (groupList.indexOf(theSource) >= 0 && groupList.indexOf(theTarget) >= 0) {
                myLength = myLength * 0.7;
            }
        });
        subgroupNodes.forEach(function(groupList) { 
            if (groupList.indexOf(theSource) >= 0 && groupList.indexOf(theTarget) >= 0) {
                myLength = myLength * 0.4;
            }
        });
        subsubgroupNodes.forEach(function(groupList) { 
            if (groupList.indexOf(theSource) >= 0 && groupList.indexOf(theTarget) >= 0) {
                myLength = myLength * 0.2;
            }
        });
        return myLength; } )
    .linkStrength(function(l, i) { return 1; } )
    .gravity(0.05)   
    .charge(-600)   
    .friction(0.5)  
    .start();

可以在 this JSFiddle 找到此解决方案的一个版本以及其他改进。

虽然这通过按组成员调整 link 力来回答我的问题,但它并没有按照我最初打算的方式组合 links + 组的力。我仍然希望能够让子子组 "desire" 彼此远离角落,但受到连接它们的边缘的限制(而不是强迫它们处于圆形布局)。

请注意,我的组被外生定义为列表的列表。如果您的组成员身份是一个节点 属性,那么您可以使用 d3.nest() 函数生成我必须使用 map 函数创建的节点组,但我认为这不会如果组有重叠成员,则工作。

这是一个很好的例子,包括 cytoscape.js 在内的许多网络库都不允许这种复杂的分组。 我有 2 个问题:

  1. 参考:“此功能剩下的就是让分组适当地影响部队布局”这会对更大的网络产生重大影响吗?这基本上允许布局算法考虑组 ?

  2. 我正在尝试将您的方法迁移到 d3 v4,只是想知道您是否已经尝试过这样做?