Help us understand the problem. What is going on with this article?

d3.js Force Simulation の世界

More than 3 years have passed since last update.
var simulation = d3.forceSimulation();

とは、

d3js_force_simulation.png

http://bl.ocks.org/mbostock/4062045

のような、グラフ可視化ができるシステム。リンク先を見ればコードの書き方はだいたい分かるけれども、実際に自分のデータでやってみると、いい感じになるパラメータの調整が意外と難しいので、この世界を簡単に解説する。詳しい説明は、
https://github.com/d3/d3-force

力あれ

1. 摩擦力

この世界には摩擦力があるので、動いているものはやがて止まる。

simulation.velocityDecay(0.01)

で摩擦係数を指定できる。いい感じになる前に止まってしまう場合は小さく、ふらふら動き続けて困る場合は大きくする。デフォルトは 0.4.

2. 重力

アリストテレスの重力よろしく、世界の中心に落ちていく力 d3.forceCenter

simulation.force("center", d3.forceCenter(width / 2, height / 2))

一点ではなくて一直線上に落ちていくようにしたい場合は d3.forceX(x) d3.forceY(y) がある。

3. バネ

いわゆるフックの法則。グラフの edge/link/枝が distance よりも長い場合はその伸びに比例して引っ張られ、短い場合は押し合う。力は strength で指定できるが、2より大きい値を入れるとなぜか爆発する。

simulation.force("link", d3.forceLink().id(function(d) { return d.id; }))

simulation.force("link")
          .links(graph.links)
          .distance(function(){ return 10;})
          .strength(function(){ return 2; })

4. クーロン力/万有引力

simulation.force("charge", d3.forceManyBody())

simulation.force("charge")
          .strength(function() { return -0.1; })

strength に負の数を入れると互いに反発して、正の数だと引かれ合う。

5. 接触力

d3.forceCollide([radius])

グラフの vertex/node/頂点 が半径 radius の球のようにぶつかるようになる。

固定

node0 = simulation.nodes()[0]
node0.fx = x;
node0.fy = y;

node0 を (x,y) に固定する。

alpha

alpha というのは砂時計のようなもので、時間とともに減っていって、何ステップ世界が動くかを司る。

simulation.alpha([alpha])  // = 1
simulation.alphaMin([min]) // = 0.001
simulation.alphaDecay([decay]) // = 0.0228 = 1 - pow(0.001, 1/300)
simulation.alphaTarget([target]) // = 0

1ステップで(単位時間あたり)速度が摩擦力で

velocity <- velocity * velocityDecay

だけ減少して、alpha が、

alpha <- alpha + (alphaTarget - alpha) * alphaDecay

になる。alphaalphaMin を下回ると止まり、デフォルトのパラメタでは300ステップに相当する。なぜこんなパラメタなのかわからないけれども:

  • alphaalphaTarget に漸近する。
  • よって、alphaTargetalphaMin 以上だと止まらない。
  • alphaDecay が大きければ少ないステップでalphaTargetに近づいて止まる。

将棋の序盤をグラフしてみたけれども、はみだしたりしてなかなか思うようにいかない...
https://junkoda.github.io/kyokumen/graph/2016_1.html

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away