3

我已经构建了一个使用 D3.js V4 动态加载数百个(有时数千个)节点的图表。尽管我试图调整它的力量,但有一些节点集群可能会变得不那么混乱,但因此排斥力会将没有边缘的节点推到画布的边界。

似乎没有简单的方法来设置没有边缘的单个节点倾向于离中心更近的距离

以下是截图(注意右上角的节点): 在此处输入图像描述

以下是涉及的力量:

    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));

期待有其他方法来调整或优化特别不边缘的节点......

4

1 回答 1

5

尝试施加两个额外的力:

forceY并且forceX,这些可以作为引力来保持节点聚集在中心周围。从 API 文档:

x 和 y 定位力将节点推向沿给定维度的所需位置,具有可配置的强度。径向力是相似的,除了它将节点推向给定圆上的最近点。力的强度与节点位置和目标位置之间的一维距离成正比。虽然这些力可用于定位单个节点,但它们主要用于适用于所有(或大多数)节点的全局力。(API 文档

使用这些力可能是一种简单的解决方案,可以防止节点由于排斥力而游走太远。申请:

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() 是确定节点是否孤独的函数。如果是,则应用非零强度,如果它具有链接,则将方向力强度设置为零。这是一个快速块。您可能需要修改强度值以使节点在您的力布局中保持可见。

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

于 2017-11-29T20:52:06.623 回答