d3不响应其他require文件中的节点哈希更改

时间:2015-09-25 20:55:43

标签: javascript d3.js hash requirejs

我有一个使用RequireJS的javascript项目。我有一个 d3-and-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-and-svg.js 在它们位于另一个文件中时无法访问它们。但我不确定这一点,也不能想出一个好的解决方案。

1 个答案:

答案 0 :(得分:1)

使用您已显示的代码,它无法正常工作。您定义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' }

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

如果您的代码更改为d3AndSVG.nodes,您可以采取的措施是让您的代码使用nodes代替exports.nodes

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