の 2 つのインスタンスが必要ですd3.forceCollide()
。1 つは、オーバーラップを防ぐために、すべてのノードを互いに離して配置する方法です。2 番目の方法では、ノードのサブセットのみが互いに押し離され、半径がはるかに大きくなります。
2 つ目の力を実現するために、次のように、initialize メソッドを微調整して着信ノードをフィルター処理します。
function selective(force,filter){
var init = force.initialize;
force.initialize = function(_){return init(_.filter(filter));};
return force;
}
var dpi = 90; // approximate pixels per inch in SVG
var size = dpi * (1/4); // quarter-inch unit size
var universally_applied =
d3.forceCollide()
.radius(size)
.strength(1);
var selectively_applied =
selective(
d3.forceCollide(),
function(d){return d.id === color;}
)
.radius(size*5)
.strength(1);
}
今、これはほとんど機能します。実際の動作を確認するためにフィドルを作成しました: https://jsfiddle.net/jarrowwx/0dax43ue/38/ - すべての色付きの円は、同じ色の他のすべての円を遠くから反発するはずです。他のすべての色は、ぶつかって邪魔にならないように押し出します。
物事が定義される順序を変更しない場合、選択的に適用された力は最初の色 (赤) にのみ適用されます。力を適用する前に配列をシャッフルするとdata
、何が起こるかを正確に定義することは困難ですが、同じ色であっても、一部の円に力が適用され、他のほとんどの円には適用されません。
ここで何が起こっているのか、またはそれを修正する方法はありますか?