gex*_*tra 4 d3.js d3-force-directed
我构建了一个使用 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));
Run Code Online (Sandbox Code Playgroud)
期待调整或优化特别无边缘的节点的替代方法......
尝试施加两个额外的力:
\n\nforceY并且forceX,这些可以充当重力来保持节点聚集在中心周围。来自 API 文档:
\n\n\nx 和 y 定位力以可配置的强度沿着给定维度将节点推向所需位置。径向力是类似的,只不过它将节点推向给定圆上最近的点。力的强度与节点\xe2\x80\x99s位置和目标位置之间的一维距离成正比。虽然这些力可用于定位各个节点,但它们主要用于应用于所有(或大多数)节点的全局力。(API文档)
\n
使用这些力可能是防止节点由于排斥力而漂移太远的简单解决方案。申请:
\n\nsimulation.force("forceX", d3.forceX(width/2).strength(k) )\n .force("forceY", d3.forceY(height/2).strength(k) );\nRun Code Online (Sandbox Code Playgroud)\n\n虽然这种方法应该有效,但如果您只想将这些力施加到未链接的节点,则可以有选择地施加力:
\n\n simulation\n .force("forceX",d3.forceX(width/2).strength(function(d){ return hasLinks(d) ? 0 : 0.05; }) )\n .force("forceY",d3.forceY(height/2).strength(function(d){ return hasLinks(d) ? 0 : 0.05; }) )\nRun Code Online (Sandbox Code Playgroud)\n\n其中 hasLinks() 是确定节点是否孤独的函数。如果是,则应用非零强度,如果有链接,则方向力强度设置为零。这是一个快速块。您可能需要修改强度值,以使节点处于力布局的可见范围内。
\n\n如果您担心强度的固定值可能不适用于动态数据,则如果在边界框/svg 之外检测到节点,则可以增加这两个力的强度。
\n