首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >d3js在编解码数据之后工作。

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

Stack Overflow用户
提问于 2014-11-18 08:56:50
回答 4查看 257关注 0票数 5

我正在用d3js和分层布局实现数据的可视化。我的数据如下:

代码语言:javascript
运行
复制
       0
     / | \
    /  |  \ 
   1   5   3
    \  |   |
     \ |   |
       4  /
       | /
       2

由于无法链接到多个父节点,所以我重复显示的节点:

代码语言:javascript
运行
复制
       0
     / | \
    /  |  \ 
   1   5   3
   |   |   |
   |   |   |
   4   4   |
   |   |   |
   2   2   2

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

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

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

代码语言:javascript
运行
复制
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);
}

对我来说:控制台中的两个打印元素是相同的,但不是布局的呈现。对象引用可能有一些不同之处。

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

代码语言:javascript
运行
复制
    var root = JSON.parse(JSON.stringify(root));

那剧本就好用了。但是我根是一个长数组,解析需要很长的时间.

你知道为什么我需要用那个编码/解码来显示同样的东西吗?

谢谢

EN

回答 4

Stack Overflow用户

发布于 2014-11-26 11:11:10

应该对JSON进行编码/解码,以防止浅层复制。要了解更多关于深度复制和浅拷贝的内容,请看下面的链接。深拷贝和浅拷贝有什么区别?

由于var root =JSON.parse(JSON.stringify(Root))是防止浅层复制的错误方法,您可以使用jquery的克隆方法或简单的javascripts方法来深入复制javascript数组。

例如。

代码语言: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)

另一个解决方案是使用下划线。如果不需要完整的下划线javascript代码,则可以在下划线库中选择克隆部分。

在下划线中,可以使用以下方法复制对象数组:

代码语言:javascript
运行
复制
var a = [{f: 1}, {f:5}, {f:10}];
var b = _.map(a, _.clone);       // <----
b[1].f = 55;
console.log(JSON.stringify(a));

它会打印出来

代码语言:javascript
运行
复制
[{"f":1},{"f":5},{"f":10}]
票数 1
EN

Stack Overflow用户

发布于 2014-11-26 23:17:54

您可以将for循环替换为这样的东西,但不知道性能。小提琴

代码语言:javascript
运行
复制
traverse(root[1].Nodes[0]);
function traverse(node) {
    for (i in root[2].Arcs) {
        var d = root[1].Nodes[root[2].Arcs[i].D];
        if (node.name === root[2].Arcs[i].D) {
            var s = root[1].Nodes[root[2].Arcs[i].S];
            var sCopy={
                "name": s.name
            }
            traverse(sCopy);
            if (!node.children) {
               node.children = [];
            }
            node.children.push(sCopy);
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2014-11-28 07:52:45

注意:的表现不如原来的帖子好,见下面的评论。这种方式是可伸缩的,所以不管对象(和标志是什么样子),它都应该工作。

答案

这是另一个关于“深拷贝”方法的观点,这是由@经颅和@LaxmikantDange提出的。

我建议使用jquery (我喜欢的方法:写得少,做得多),并使用它的extend例程:

代码语言:javascript
运行
复制
<<load jquery>>

root = $.extend(true, {}, root[1].Nodes[0]);
graph(root2,svg);
graph(root,svg2);

确保true作为第一个参数,可以在这里看到http://api.jquery.com/jquery.extend/在JavaScript中深入克隆对象的最有效方法是什么? (顶部答案)。

对表现不太确定,但我希望不会太糟。如果你测试了,请告诉我!

也请不要认为深拷贝可能是可疑的,取决于您的应用程序(断链接等)。例如,我最近开发了一个在图形之间共享事件的react应用程序--共享例如缩放事件(调整呈现的对象)不是“自动共享”(如果您知道我的意思的话,这些对象是独立的)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26990192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档