D3.js 中节点上的偏力

2023-12-03

我想分别向节点的几个子部分施加多个力(forceX 和forceY)。

为了更具说明性,我将此 JSON 作为我的节点的数据:

[{
    "word": "expression",
    "theme": "Thème 6",
    "radius": 3
}, {
    "word": "théorie",
    "theme": "Thème 4",
    "radius": 27
}, {
    "word": "relativité",
    "theme": "Thème 5",
    "radius": 27
}, {
    "word": "renvoie",
    "theme": "Thème 3",
    "radius": 19
},
....
]

我想要的是将一些力量专门应用于具有“主题 1”作为主题属性的节点,或对“主题 2”值施加其他力量,等等......

我一直在查看源代码以检查我们是否可以将模拟节点的子部分分配给力,但我还没有找到。

我的结论是我必须实施一些辅助措施d3.simulation()并且仅应用节点各自的子部分来处理我之前提到的力。 这是我想在 d3 伪代码中执行的操作:

mainSimulation = d3.forceSimulation()
                        .nodes(allNodes)
                        .force("force1", aD3Force() )
                        .force("force2", anotherD3Force() )
cluster1Simulation = d3.forceSimulation()
                        .nodes(allNodes.filter( d => d.theme === "Thème 1"))
                        .force("subForce1", forceX( .... ) )
cluster2Simulation = d3.forceSimulation()
                        .nodes(allNodes.filter( d => d.theme === "Thème 2"))
                        .force("subForce2", forceY( .... ) )

但我认为考虑到计算,这根本不是最佳的。

是否可以在模拟节点的子部分上施加力,而无需创建其他模拟?

实施高积云的第二个解决方案:

我尝试了这样的解决方案:

var forceInit;
Emi.nodes.centroids.forEach( (centroid,i) => {

    let forceX = d3.forceX(centroid.fx);
    let forceY = d3.forceY(centroid.fy);
    if (!forceInit) forceInit = forceX.initialize;  
    let newInit = nodes => { 
        forceInit(nodes.filter(n => n.theme === centroid.label));
    };
    forceX.initialize = newInit;
    forceY.initialize = newInit;

    Emi.simulation.force("X" + i, forceX);
    Emi.simulation.force("Y" + i, forceY);      
});

我的质心数组可能会改变,这就是为什么我必须采用动态方式来实现我的子力。 不过,我最终在模拟滴答声中遇到了这个错误:

09:51:55,996 TypeError: nodes.length is undefined
- force() d3.v4.js:10819
- tick/<() d3.v4.js:10559
- map$1.prototype.each() d3.v4.js:483
- tick() d3.v4.js:10558
- step() d3.v4.js:10545
- timerFlush() d3.v4.js:4991
- wake() d3.v4.js:5001

我的结论是过滤后的数组没有分配给nodes,我不明白为什么。 PS:我检查了console.log:nodes.filter(...)确实返回了一个填充的数组,所以这不是问题的根源。


要仅对节点子集施加力,您基本上必须选择:

  1. 实施你自己的力量,这并不像听起来那么困难,因为

    力只是一个修改节点位置或速度的函数;

–或者,如果您想坚持标准力–

  1. 创建标准力并覆盖其force.initialize()方法,这将

    将节点数组分配给该力。

    通过过滤节点并仅分配您感兴趣的节点,您可以控制力应作用于哪些节点:

    // Custom implementation of a force applied to only every second node
    var pickyForce = d3.forceY(height);
    
    // Save the default initialization method
    var init = pickyForce.initialize; 
    
    // Custom implementation of .initialize() calling the saved method with only
    // a subset of nodes
    pickyForce.initialize = function(nodes) {
        // Filter subset of nodes and delegate to saved initialization.
        init(nodes.filter(function(n,i) { return i%2; }));  // Apply to every 2nd node
    }
    

以下代码片段通过初始化来演示第二种方法d3.forceY与节点的子集。在整组随机分布的圆圈中,每隔一个圆圈就会受到力,从而移动到底部。

var width = 600;
var height = 500;
var nodes = d3.range(500).map(function() {
  return {
    "x": Math.random() * width,
    "y": Math.random() * height 
  };
});

var circle = d3.select("body")
  .append("svg")
    .attr("width", width)
    .attr("height", height)
  .selectAll("circle")
  .data(nodes)
  .enter().append("circle")
    .attr("r", 3)
    .attr("fill", "black");

// Custom implementation of a force applied to only every second node
var pickyForce = d3.forceY(height).strength(.025);

// Save the default initialization method
var init = pickyForce.initialize; 

// Custom implementation of initialize call the save method with only a subset of nodes
pickyForce.initialize = function(nodes) {
    init(nodes.filter(function(n,i) { return i%2; }));  // Apply to every 2nd node
}

var simulation = d3.forceSimulation()
		.nodes(nodes)
    .force("pickyCenter", pickyForce)
    .on("tick", tick);
    
function tick() {
  circle
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
}
<script src="https://d3js.org/d3.v4.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

D3.js 中节点上的偏力 的相关文章

随机推荐

  • 堆栈宽度始终与 CPU 寄存器大小相同吗?

    例如 对于8位CPU 堆栈大小预计为8位宽 而16位CPU vs 16位堆栈宽度 以及32位 64位CPU等 对于所有架构都是如此吗 CPU有数据总线和地址总线 它们可以具有相同的宽度 但通常不是 堆栈指针是指向内存的指针 因此它通常与地址
  • 消息“安全点期间合并操作”的含义

    java 应用程序使用以下标志运行 XX PrintSafepointStatistics 然后 在标准输出控制台上生成以下行 2 个虚拟机操作在安全点期间合并 有人愿意解释一下这是什么意思吗 更一般地说 是否有 Java 参考手册详细介绍
  • 将 http:// 添加到所有不带协议的链接

    我使用 VB NET 并且想添加http 指向所有尚未以 http https ftp 等开头的链接 I want to add http here a href target self Google a but not here a hr
  • 尝试理解 ASP.NET 和 HttpClient() 的“常见”异步死锁

    在遇到 常见 异步死锁并进一步了解之后异步最佳实践我尝试在 ASP NET 中模拟这个问题 试图找出为什么我们以前从未遇到过这个问题 看起来的区别在于 我们之前使用的是 http 客户端获取异步方法 但这并没有引起问题 public cla
  • 支持使用 AVCaptureSession 后台录制视频

    我正在尝试在后台录制视频 但目前当应用程序进入后台时 我的代码正在前台录制视频 void captureOutput AVCaptureFileOutput captureOutput didFinishRecordingToOutputF
  • Python:在 for 循环中访问迭代器对象

    我想在循环内显式地步进循环迭代器 有没有比以下 更好 的方法来做到这一点 idx iter range 0 10 for i in idx print i if i 5 print consuming i in step i next id
  • 操作现有的 CSV 文件,同时保持列顺序。 (CsvReader/CsvWriter)

    我需要通过以下操作操作现有的 CSV 文件 从现有 CSV 文件读取 gt 然后向其追加新行 我有以下代码 该代码在第三行中令人窒息 因为该文件已被第一行中的代码使用 我不知道如何正确阅读它 然后向其添加新行 public bool Sav
  • 阻止 WordPress 将脚本包含在 CDATA 中

    我正在使用 WordPress 的 HTML 导入插件导入 HTML 页面 我有一个谷歌地图的代码片段 它是导入的 但是 导入后 它会包含script tag in CDATA 如果我删除 CDATA 地图就可以正常工作 如何阻止 Word
  • powercfg 电池报告的 GUI

    我正在尝试为 powercfg 电池报告创建一个 GUI 我已经写了下面的内容 但似乎不起作用 有人可以帮忙吗 Thanks private void button1 Click object sender EventArgs e var
  • Web 浏览器控制:禁用跨站 XSS 过滤或其他在 HTML 上完整处理 JS 的方法

    我正在尝试使用我的网络浏览器控件从特定页面获取日期 包括所有子页面内容 问题是某些子页面位于单独的域上 因此当我尝试访问框架 通过 document windows frames i document 时 我收到权限设计错误 现在我明白了发
  • 为什么 numpy std() 给出的结果与 matlab std() 不同?

    我尝试将 matlab 代码转换为 numpy 并发现 numpy 与 std 函数有不同的结果 在Matlab中 std 1 3 4 6 ans 2 0817 in numpy np std 1 3 4 6 1 8027756377319
  • SQL 状态:42601 在“11”处或附近出现语法错误

    我有一张桌子address all并且它被多个地址表继承 address history继承自父表history all并保留当前地址信息 我正在创建继承的新表address all表并从中复制信息address history到新表 我的
  • 在 Neovim 中运行的 Bash 脚本忽略“读取”命令 [重复]

    这个问题在这里已经有答案了 考虑以下 Bash 脚本 usr bin env bash read rp gt INPUT echo Your input is INPUT echo Done 当我在常规 Vim 中打开这个文件并运行 bas
  • 如何在被覆盖的输入框获得焦点时向下滚动页面?

    看一眼这一页 我有一个带有较低 浮动 固定位置 div 的页面 它覆盖了屏幕底部的某些部分 具有高 z 索引和一堆输入框 问题是 当下面的输入框之一被聚焦时 通过按 TAB 键 它们的内容会被 div 部分隐藏 我想检测下部输入框何时获得焦
  • C# WinForms BindingList 和 DataGridView - 不允许编辑会阻止创建新行?我该如何解决这个问题?

    关于我将 DataGridView 与 BindingList 一起使用 我将禁用编辑当前行 但允许添加新行 我遇到的问题是 当我禁止编辑时 这似乎阻止了添加新行项目 因为当您将表格放入该新行的单元格时 它似乎不允许编辑 知道如何解决这个问
  • 计算字符串中元音的简单方法?

    如果我定义一个简单的字符串变量 我将如何以最简单的方式计算并输出字符串中的元音数量 我搜索并发现了许多类似的方法来做到这一点 但大多数似乎比必要的更复杂 它们都很实用 也许复杂性是必要的 但我正在寻找尽可能简单的解决方案 我的字符串变量类似
  • 输出中的括号和引号

    有时 当我使用打印功能时 输出中会出现括号和引号 我正在使用 Python 3 4 并在 Mac 上的 Sublime Text 中编写代码 这是一个例子 Input a 2 print a a Output a 2 我只想显示 a 和 2
  • java求二维数组之和

    我正在开发一个项目 我必须读取文件并将内容输入到二维数组中 然后我必须对矩阵的每一行 每一列和周长求和 到目前为止 除了外围之外 一切都正常 我试图为顶行 底行和两个外列的中间创建单独的 for 循环 矩阵文件如下所示 1 2 3 4 2
  • 在运行时更改嵌入的资源文件

    我编写了一个程序 该程序使用资源 嵌入的文本文件 作为程序的默认配置 我希望能够允许用户更改此默认行为 我想知道如何修改嵌入式资源文件 以便下次使用程序时它将使用修改后的版本 感谢您的帮助 我认为你正在寻找的是settings文件 嵌入的资
  • D3.js 中节点上的偏力

    我想分别向节点的几个子部分施加多个力 forceX 和forceY 为了更具说明性 我将此 JSON 作为我的节点的数据 word expression theme Th me 6 radius 3 word th orie theme T