D3.js v4/v5 force simulation 座標更新アルゴリズム/実行関数 まとめ
D3、forceSimulationの座標更新アルゴリズムと実行関数を紹介します。
ノード間の相互作用力の設定についてはこちらを、リンクの設定についてはこちらを確認ください。
座標の更新について
D3.jsのforceSimulationは、原点を(0, 0)とし、1ステップの位置変化量を(vx, vy)とすると以下の関数で位置変化量を計算します。
1 2 3 4 5 6 7 |
function force(alpha) { for (var i = 0, n = nodes.length, node, k = alpha * 0.1; i < n; ++i) { node = nodes[i]; node.vx -= node.x * k; node.vy -= node.y * k; } } |
原点(指定したx,y)からの距離に、alpha×0.1をかけた分の座標を更新します。alphaが1の場合、10%ずつ原点に近づいていく挙動になります。
また、alphaはシミュレーションの1ステップごとに
(alphaTarget – alpha) × alphaDecay
が加算されて更新されます。デフォルトのalphaTargetは0、alphaDecayは0.0228なので徐々にalphaが減少していきます。このalphaがalphaMin(デフォルト:0.001)を下回った際にシミュレーションがstopします。デフォルトでは約300回反復計算が行われる設定です。以下の関数でこれらの設定とシミュレーションの実行を制御することができます。
simulation 実行関数
simulation.restart() | シミュレーションを再起動します。ドラッグなどのイベント時に停止したシミュレーションを起動したいときに使います。 |
simulation.stop() | シミュレーションを停止します。既に停止している場合は何も行いません。 |
simulation.tick() | シミュレーションの内部関数です。シミュレーション作成時、またはrestart()によって呼び出されます。 |
simulation.node() | ノードを指定します。使用方法はこちらを参照ください。 |
simulation.alpha() | alphaの値を0.0~1.0の間で設定します。デフォルトは1です。値が指定されていない場合は、現在のalpha値を返します。 |
simulation.alphaMin() | alphaMinの値を0.0~1.0の間で設定します。デフォルトは0.001です。値が指定されていない場合は、現在のalpha値を返します。シミュレーションは、現在のalphaがalphaMinよりも小さい場合に停止します。 |
simulation.alphaDecay() | alphaDecayの値を0.0~1.0の間で設定します。デフォルトは0.0228(=1-pow(0.001、1/300))です。値が指定されていない場合は、現在のalphaDecay値を返します。alphaDecayが大きいほど、シミュレーションはより早く収束しますが、局所解に留まる可能性があります。alphaDecayの値を小さくするとシミュレーションの実行に時間がかかりますが、より良いレイアウトに収束します。シミュレーションを永久に続けるには、alphaDecayを0に設定するか、alphaTargetをalphaMinより大きな値に設定します。 |
simulation.alphaTarget() | alphaTargetの値を0.0~1.0の間で設定します。デフォルトは0です。値が指定されていない場合は、現在のalphaTarget値を返します。 |
simulation.velocityDecay() | ノードの速度減衰係数を設定します。0.0~1.0の値を設定可能です。 値が設定されていない場合は、現在の速度減衰係数を返します。デフォルトは0.4です。現在の速度に(1-velocityDecay)の値が乗算され、値が大きいほど速度減衰が大きくなります。0にするとノードが振動し続け、1にすると速度変動しなくなります。 |
simulation.force() | ノード間および、リンクの相互作用を設定する関数です。ノード間はこちらを、リンクはこちらを参照ください。 |
simulation.find(x,y[,radius]) | 指定された探索半径で位置(x、y)に最も近いノードを返します。 radiusが指定されていない場合は探索半径が無限大になります。探索領域内にノードが存在しない場合、undefinedを返します。 |
simulation.on(typenames, [listener]) | イベントリスナーを登録します。イベントリスナーがすでに同じタイプおよび名前で登録されている場合、新しいリスナーが上書きされます。listenerがnullの場合、イベントリスナーを削除します。typenamesは「tick」と「end」を指定可能です。 tick:シミュレーションステップ更新時 end:シミュレーション完了時(alpha<alphaMin) |
まとめ
ここでは、シミュレーションの実行関数についてまとめました。応用編として、ラジアルフォースのサンプル、ノードに複数のsvgを含める方法、クリックしたノードと関連リンクをハイライトする方法をまとめています。