r-无法更改使用网络D3的forceNetwork创建的网络图中的linkDistance



我正试图使用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")

直到我开始玩CCD_ 1参数。当我把它设置为我想要的,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版中使用R 3.1.3版Windows,包networkD3 0.1.2.2版。(我最初在使用CRAN的networkD3 0.1.2.1版本时遇到了问题。所以我从GitHub安装了最新版本,也遇到了同样的问题。(

如果您希望评估从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;', '}'))

networkD3包太棒了!!

经过详尽的调查,我找到了这个错误:networkD3生成的HTML/CSS/JavaScript代码似乎依赖于d3js,它提供了d3.min.js文件,该文件是生成的web代码的核心。正是在d3.min.js内部对linkDistance特性进行了编码,错误就是在那里发生的。

不幸的是,正如文件名所示,JavaScript被缩小了,但您可以从d3js站点访问未缩小的源代码,特别是在https://github.com/mbostock/d3/blob/master/d3.js.

如果你查看linkDistance0的第6307行(以及周围的上下文(,你会发现:

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

此函数在初始化期间的某个时刻被调用,x是您最初在对forceNetwork()的R调用中提供的字符串(顺便说一句,该字符串嵌入到networkD3作为JSON数据生成的index.html文件中,以及所有其他输入数据(。

重复一遍,x字符串。这意味着typeof(x)将返回"string"而不是"function",因为第6307行正在检查。因此,将调用三进制的第二个替换+x,这是对number的JavaScript样式强制,这将导致NaN。因此,NaN通过所有链路距离和坐标传播,并且所有内容都得到f*!%ed.

这可以通过将其更改为:来解决

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

很明显,我将"function"更改为"string",但我还必须添加一个eval()调用,以实际从字符串中提取函数定义,这样所有未来使用linkDistance的代码都能工作,因为它都假设它是一个函数,而不是字符串。最后,我必须用括号连接,以确保函数定义是表达式化的,否则,如果您使用function作为代码字符串的前导标记(这是您所做的,他们在networkD3文档中也这样做了,这是最明智的做法(,那么它将被视为函数语句,这意味着它不会被解析为实际的表达式语句,而eval()调用将返回undefined,当代码最终尝试在算术表达式中使用undefined值时,您最终会得到NaN,从而导致相同的错误。(请参阅JavaScript中的函数表达式和声明之间的区别是什么https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/对于这一区别的几个好消息来源,可能还有一百万其他消息来源。(

我已经在我的机器上测试了上述修复程序,它可以工作。我想这应该作为一个bug报告给d3js的人,但我觉得我在这里已经做了足够的工作,不会被打扰。请随意向他们报告这一点,并将我在这里的帖子作为参考。

相关内容

  • 没有找到相关文章