d3js在编码解码数据之后工作

Mat*_*ieu 5 javascript json d3.js

我正在研究d3js和分层布局的数据可视化.我的数据如下:

       0
     / | \
    /  |  \ 
   1   5   3
    \  |   |
     \ |   |
       4  /
       | /
       2
Run Code Online (Sandbox Code Playgroud)

因为我无法链接到多个父节点,所以我复制了显示的节点:

       0
     / | \
    /  |  \ 
   1   5   3
   |   |   |
   |   |   |
   4   4   |
   |   |   |
   2   2   2
Run Code Online (Sandbox Code Playgroud)

我做了一个小提琴演示来展示我的问题:

  • 当我在JSON输入中使用正确的数据时,我有良好的布局(蓝色边框图形).
  • 当我使用循环来解析我的JSON输入时,我有奇怪的图形(绿色边框图形).

这是我用来解析输入的循环:

for (i in root[2].Arcs){
  var d = root[1].Nodes[root[2].Arcs[i].D];
  var s = root[1].Nodes[root[2].Arcs[i].S];
  if (!d.children){
    d.children = [];
  }
  d.children.push(s);
}
Run Code Online (Sandbox Code Playgroud)

对我来说:控制台中的两个打印元素都是相同的,但不是布局的渲染.对象引用中可能存在一些不同之处.

我发现一个糟糕的解决方案是解码然后编码我的var:

    var root = JSON.parse(JSON.stringify(root));
Run Code Online (Sandbox Code Playgroud)

然后脚本运行良好.但我root是一个很长的数组,解析需要很长时间......

有什么想法解释为什么我需要使用编码/解码来显示相同​​的东西?

谢谢

Lax*_*nge 1

您应该对 JSON 进行编码/解码以防止浅复制。要了解有关深层复制和浅层复制的更多信息,请参阅以下链接。 深拷贝和浅拷贝有什么区别?

作为 var root = JSON.parse(JSON.stringify(root)); 防止浅复制的错误方法是,您可以使用jquery的clone方法或简单的javascripts slice方法来深度复制javascript数组。

例如。

var d=[1,2,3,4,5,6];//create array
var b=d;//copy array into another array (shallow copy/reference copy)
var e=d.slice();//clone array in another variable (deep copy)
d[0]=9; //change array element
console.log(d)// result : [9,2,3,4,5,6] (changed array)
console.log(b)// result : [9,2,3,4,5,6] (changed array due to reference)
console.log(e)// result : [1,2,3,4,5,6] (unchanged array due to deep copy)
Run Code Online (Sandbox Code Playgroud)

还有另一种解决方案是使用下划线。如果您不想要 underscore 的完整 javascript 代码,那么您可以选择 underscore 库中的克隆部分。

在下划线中,您可以使用以下方式克隆对象数组:

var a = [{f: 1}, {f:5}, {f:10}];
var b = _.map(a, _.clone);       // <----
b[1].f = 55;
console.log(JSON.stringify(a));
Run Code Online (Sandbox Code Playgroud)

它将打印

[{"f":1},{"f":5},{"f":10}]
Run Code Online (Sandbox Code Playgroud)