没有边的节点在 D3 v4 中逃脱图形

nodes without edges escaping the graph in D3 v4

我构建了一个图表,使用 D3.js V4 动态加载数百(有时数千)个节点。尽管我尝试调整它的力,但有些节点集群可能会变得不那么混乱,但结果是 repel 将没有边缘的节点推向边界 的 canvas.

似乎没有简单的方法来设置没有边缘的单个节点被吸引到离中心更近的距离

截图如下(注意右上角的节点):

以下是相关力量:

    var repelForce = d3.forceManyBody()
                     .strength(-200)
                     .distanceMax(400)
                     .distanceMin(150);



var gSimulation = d3.forceSimulation()
    .force('link', d3.forceLink().id((d) => d.id))
    .force('charge', repelForce)
    .force('center', d3.forceCenter(gwidth / 2, gheight / 2));

期待其他方法来调整或优化特别未加边的节点...

尝试施加两个额外的力:

forceYforceX,这些可以作为重力使节点围绕中心聚集。来自 API 文档:

The x- and y-positioning forces push nodes towards a desired position along the given dimension with a configurable strength. The radial force is similar, except it pushes nodes towards the closest point on a given circle. The strength of the force is proportional to the one-dimensional distance between the node’s position and the target position. While these forces can be used to position individual nodes, they are intended primarily for global forces that apply to all (or most) nodes. (API documentation)

使用这些力可能是防止节点因排斥力而漂移太远的简单解决方案。申请:

simulation.force("forceX", d3.forceX(width/2).strength(k) )
  .force("forceY", d3.forceY(height/2).strength(k) );

虽然这种方法应该有效,但如果您只想将这些力应用于未链接的节点,则可以有选择地施加力:

  simulation
   .force("forceX",d3.forceX(width/2).strength(function(d){ return hasLinks(d) ? 0 : 0.05; }) )
   .force("forceY",d3.forceY(height/2).strength(function(d){ return hasLinks(d) ? 0 : 0.05; }) )

其中hasLinks()是判断节点是否孤独的函数。如果是,则应用非零强度,如果它有链接,则方向力强度设置为零。这是 quick block。您可能需要修改强度值以使力布局中的节点可见。

如果您担心强度的固定值可能不适用于动态数据,则可以在检测到边界外的节点时增加这两种力的强度 box/svg。