1

networkD3パッケージを使用して、R で強制指向ネットワーク グラフを作成しようとしています。すべてがうまく機能します...

devtools::install_github('christophergandrud/networkD3')
library(networkD3)
links2 <- data.frame(
  Source = c(0, 0, 0, 1, 2, 3), 
  Target = c(1, 4, 5, 3, 4, 5), 
  Value = c(1, 9.9, 10, 8.8, 6.6, 7.2))
nodes2 <- data.frame(ID = 0:5, 
  Group = c(1L, 1L, 1L, 2L, 1L, 2L))

# this works
forceNetwork(Links=links2, Nodes=nodes2, 
  Source="Source", Target="Target", Value="Value", 
  NodeID="ID", Group="Group")

linkDistance...私が議論を始めるまで。の機能である必要なものに設定するとValue、デバイスの左上隅にある単一のノードのように見えるもので構成されるネットワーク ダイアグラムが表示されます。

# this doesn't work
forceNetwork(Links=links2, Nodes=nodes2, 
  Source="Source", Target="Target", Value="Value", 
  NodeID="ID", Group="Group",
  linkDistance="function(d) { return d.value; }")

リンクの長さを変化させる方法についての提案をいただければ幸いです。

R Studioバージョン0.98.1103で、パッケージnetworkD3バージョン0.1.2.2でWindows用のRバージョン3.1.3を使用しています。(私は元々、CRAN の networkD3 バージョン 0.1.2.1 を使用して問題を経験しました。そのため、GitHub から最新バージョンをインストールしましたが、同じ問題が発生しました。)

4

2 に答える 2

3

パッケージnetworkD3がすごい!!

徹底的な調査の結果、バグを突き止めました。 によって生成される HTML/CSS/JavaScript コードは、生成された Web コードの中心となるファイルを提供するnetworkD3に依存しているようです。機能がコード化されているのは内部であり、バグが発生するのはそこです。d3jsd3.min.jsd3.min.jslinkDistance

d3js残念ながら、ファイル名が示すように、JavaScript は縮小されていますが、サイト (具体的にはhttps://github.com/mbostock/d3/blob/master/d3.js )から縮小されていないソースにアクセスできます。

の 6307 行目 (およびその周囲のコンテキスト) を見ると、次のd3.jsことがわかります。

force.linkDistance = function(x) {
  if (!arguments.length) return linkDistance;
  linkDistance = typeof x === "function" ? x : +x;
  return force;
};

この関数は、初期化中のある時点で、R 呼び出しで最初に指定した文字列で呼び出されますx(ちなみに、その文字列は、他のすべての入力データと共に JSON データとして生成されるファイルにforceNetwork()埋め込まれます)。index.htmlnetworkD3

繰り返しますxが、文字列です。これは、行 6307 がチェックしているように、 ではなくtypeof(x)を返すことを意味します。したがって、3 項の 2 番目の選択肢である が呼び出されます。これは、 への JavaScript スタイルの強制です。したがって、すべてのリンク距離と座標を介して伝播され、すべてが f*!%ed になります。"string" "function"+xnumberNaNNaN

これは、次のように変更することで修正できます。

linkDistance = typeof x === "string" ? eval('('+x+')') : +x;

明らかに に変更"function"しました"string"が、実際に関数定義を文字列から引き出す呼び出しを追加してeval()、今後動作するすべてのコードが機能するようにする必要linkDistanceがありました。最後に、関数定義が確実に式化されるように括弧で連結する必要がありました。それ以外の場合functionは、コード文字列の先頭のトークンとして使用した場合 (これを行い、networkD3ドキュメントで行いました。これが最も賢明なことです)。つまり、実際の式ステートメントとして解析されず、eval()呼び出しは を返しundefinedNaNコードが最終的にundefined算術式の値であり、同じエラーにつながります。( JavaScript での関数式と宣言の違いは何ですか?およびhttps://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/を参照して、この違いに関するいくつかの優れた情報源を確認してください。 、おそらく他にも何百万ものソースがあります。)

私のマシンで上記の修正をテストしましたが、動作します。これはバグとして人々に報告されるべきだと思いますd3jsが、私はここで十分な仕事をしたと感じており、気にすることはできません. ここでの私の投稿を参考にして、遠慮なく彼らに報告してください。

于 2015-05-26T01:22:55.973 に答える
2

R から JavaScript に渡された値を評価する (つまり、文字列を関数に解決する) 必要がある場合は、値を htmlwidgets::JS 関数で囲みます。例えば:

library(htmlwidgets)
forceNetwork(Links=links2, Nodes=nodes2, 
             Source="Source", Target="Target", Value="Value", 
             NodeID="ID", Group="Group",
             linkDistance=JS('function(d) {', 'return d.value;', '}'))
于 2015-05-26T13:23:43.297 に答える