【发布时间】:2016-09-19 14:12:33
【问题描述】:
我想分别对节点的几个子部分应用几个力(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
},
....
]
我想要的是将一些力专门应用于具有“Thème 1”作为主题属性的节点,或其他力用于“Thème 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
我得出的结论是,过滤后的数组没有分配给 节点,我不知道为什么。 PS:我检查了 console.log:nodes.filter(...) 确实返回了一个填充数组,所以这不是问题的根源。
【问题讨论】:
-
请提供相关源代码供审核。
-
对不起,我虽然有文字解释就足够了^^我用一些伪代码编辑了主要帖子!
-
@elTaan 我很高兴,可能回答有助于解决您的问题。但是,您不应该将自己的解决方案编辑到您的问题中,因为它只是一个问题。这只会让未来的读者感到困惑。如果您自己找到了解决方案,您可能会改为self-answer 您的问题。你应该考虑accepting任何你认为最适合你的问题的答案;这很可能是您自己的答案。
-
好的,谢谢你的提示!我接受了你的回答,因为你的 sn-p 代码正在工作,尽管我的不是:D
标签: javascript d3.js