web-dev-qa-db-ja.com

D3.jsは有向グラフを強制し、エッジを互いに反発させることでエッジの交差を減らします

だから私はすでに示されているような力指向のグラフを描くページを持っています here

そして、それはうまくいきます。私は here のJSを使用していますが、ノードを少し広げるためにいくつかの調整を加えています。

これらは多かれ少なかれ唯一の違いです:

d3.json("force.json", function(json) {
  var force = d3.layout.force()
      .gravity(0.1)
      .charge(-2000)
      .linkDistance(1)
      .linkStrength(0.1)
      .nodes(json.nodes)
      .links(json.links)
      .size([w, h])
      .start();

リンクの強度を下げると、リンクがバネのように見えるため、よく使用される Fruchterman&Reingold の手法と同様になります。これはかなりうまくいきますが、かなり小さなグラフに対してのみです。より大きなグラフでは、交差の数はちょうど増加します-予想されるように、それが着陸するソリューションは通常最適からはほど遠いです。最適なソリューションを取得する方法を探しているのではありません。それは非常に難しいことです。ノードと同様にラインを強制的に分離しようとする粗雑な追加があったらいいのですが。

ノード間だけでなく、リンク間にも反発力を追加する方法はありますか? D3フォースの動作に慣れていないので、これを説明するものを見つけることができないようです。可能です...

51
will

残念ながら、あなたの質問に対する答えはありません。

エッジをはじく、またはエッジの交差を最小限に抑えるD3の組み込みメカニズムはありません。 Edgeに課金を実装するのはそれほど難しいことではないと思われるかもしれませんが、ここではそうです。

さらに、一般的にエッジの交差を減らすメカニズムanywhereはないようです。私は何十もの視覚化ライブラリとレイアウトアルゴリズムを調べましたが、それらのどれも、一般的な無向グラフでのエッジの交差を減らすことに対応していません。

平面グラフ、2レベルグラフ、またはその他の単純化に適しているアルゴリズムは多数あります。 dagre は、2レベルのグラフでは理論的にはうまく機能しますが、ドキュメントがまったくないため、操作がほとんど不可能です。

この理由の一部は、グラフのレイアウトがhardであることです。特に、エッジの交差を最小限に抑えることはNP困難であるため、ほとんどのレイアウトデザイナーがその問題にぶつかり、キーボードに頭を数回ぶつけて、あきらめたと思います。

誰かがこれのための良いライブラリを思いついた場合は、残りの人のためにそれを公開してください:)

12
GreySage

エッジを強制的にはじくよりも簡単なのは、システムの交差する線の量が少なくなるまでノードを揺らすことです。

http://en.wikipedia.org/wiki/Simulated_annealing

接続数が最も少ないノードから始めて、小刻みに動かします。

エッジをノードとして使用すると、同じ空間ロックの問題が発生するだけだと思います。解決策は、エッジの交差がある場所と、それらが解決できるかどうかを把握することです。エッジ交差の多くを解決することは不可能であることがわかるかもしれません

視覚化のより横方向のアプローチは、一度にノードと接続のサブセットのみを表示するようにアニメーション化することです。または、ユーザーがノードにマウスフォーカスを置くまでエッジを透明にして、関連するエッジがより見やすくなるようにします。

5
VoronoiPotato

フォースエディタの例に従って、chargelinkDistanceの値を設定すると問題が解決することを確認しました。

  ...
  .charge(-200)
  .linkDistance(50)
  ...

スクリーンショット:

enter image description here

0
Ionică Bizău