我正试图使用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.
如果你查看linkDistance
0的第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
的人,但我觉得我在这里已经做了足够的工作,不会被打扰。请随意向他们报告这一点,并将我在这里的帖子作为参考。