D3对其他需求文件中的节点哈希值变化没有反应



我有一个使用RequireJS的javascript项目。我有一个d3和svg.js文件,这里是它的预览:

var nodes = {
    "at":   {id: "at", importance: 1, type: 'exercise', displayName: 'pigeonhole principal'},
    "b":    {id: "b", importance: 8, type: "theorem", displayName: 'pigeonhole theorem'},
},
    links = []
var width = $(window).width(),
    height = $(window).height()
var force = d3.layout.force()
    .nodes(nodes) // here is where the nodes go in
    .links(links)
    .size([width, height])
    .charge(-400)
    .linkStrength(0.2)
    .gravity(0.05)
    .on('tick', updateSVGNodeAndLinkPositions)

我已经修改了我的d3库来接受哈希,像这样:

force.nodes = function(x) {
  if (!arguments.length) return nodes;
  // setup helper function
  function hash_to_array(hash) {
    var array = [];
    for( key in hash ){ if( hash.hasOwnProperty(key) ){
      array.push( hash[key] );
    }}
    return array;
  };
  nodes = hash_to_array(x); // this means that .nodes() takes a HASH as input and uses the values
  // nodes = x; // what it used to say
  return force;
};

在我的main.js文件中,我启动了d3力动画,如下所示:

d3AndSVG.processNewGraph();

,它工作!它的工作原理!但有趣的是,如果我在d3-and . svg.js文件中将nodes替换为空散列,然后通过main.js文件填充它,如下所示:

d3AndSVG.nodes = {
    "at":   {id: "at", importance: 1, type: 'exercise', displayName: 'pigeonhole principal'},
    "b":    {id: "b", importance: 8, type: "theorem", displayName: 'pigeonhole theorem'},
}
d3AndSVG.processNewGraph();

那么它不工作。为什么不呢?我唯一能想到的是哈希值是引用,当d3和svg.js在另一个文件中时无法访问它们。但我不确定,也想不出一个好的解决办法。

使用您所展示的代码,它无法工作。您定义nodes:

var nodes = ...

,这可能是本地的模块的工厂(你传递给define的函数)。然后将其用作:

var force = d3.layout.force()
    .nodes(nodes) // here is where the nodes go in
    ...

nodes,再次本地到您的模块的工厂。也许您忘记了实际导出节点,这是使用exports.nodes = nodes完成的。然而,仅凭这一点还不能。看,当你在模块外这样做时:

d3AndSVG.nodes = // whatever

您正在更改nodes导出值(即您使用exports.nodes = ...设置的值)以引用不同的对象。但是, nodes本地值保持不变,这是您实际使用force的值。这种情况与这个交互式Node.js会话中的情况相同:

> var a = { foo: 'a'}
> a
{ foo: 'a' }
> var b = a
> b
{ foo: 'a' }
> b = { foo: 'b' } // We assign a new object to `b`.
{ foo: 'b' }
> b
{ foo: 'b' }
> a
{ foo: 'a' }

当我给b分配一个新对象时,a的值没有改变。

你可以做的是让你的代码使用nodes的代码使用exports.nodes代替d3AndSVG.nodes:

var force = d3.layout.force()
    .nodes(exports.nodes) // here is where the nodes go in
    ...

最新更新