2013-05-12 89 views
1

这是一个很难解释,但希望它的一个容易回答......承担与我......我认为js摆弄它,但我会必须重写很多代码,因为它使用的数据来自我的内部服务器。D3:问题与节点= vis.selectAll(“。节点”)

我写了大量的js来模拟一个网络地图,它的时间太长了,问题的实质是我可以用最初的数据绘制地图,但有时候我会更新它 - 也就是当我从原始地图中删除节点(虽然我可以添加新节点很好)

我相信问题是由于我绘制svg对象的方式。

我想在飞行中工作d3,所以我可能会无意中偏离什么是正确的。

首先,我定义了vis(window.vis,因为它现在是我可以用控制台测试它) - 我认为一些示例使用变量svg for。

window.vis = d3.select("body") 
    .append("svg:svg") 
    .attr("pointer-events", "all") 
    .append('svg:g') 
    .call(d3.behavior.zoom().on("zoom", redraw)) 
    .append('svg:g'); 

然后我做一些其他的东西,创造nodeArray(我想要的节点的数组)和linkArray(链接数组我想要的)然后我得出节点和链接:

link = vis.selectAll("line").data(linkArray); 
     link.enter().append("line") 
     .attr("stroke-opacity", function (d, i) { 
      if (d.class == 'link reallink') { 
       return '0.8'; 
      } else { 
       return '0'; 
      }; 
     }) 
     .attr("stroke-width", function (d, i) { 
      if (d.class == 'link reallink') { 
       return '3'; 
      } else { 
       return '0'; 
      }; 
     }) 
     .style("stroke", function (d, i) { return d.color; }); 



     node = vis.selectAll("g.node").data(nodeArray); 
     node.enter().append("svg:g") 
     .attr("class", function (d) { return d.class }) 
     .attr("id", function (d) { return d.id }) 
     .call(force.drag); 


     //append to each node an svg circle element 
     vis.selectAll(".realnode").append("svg:circle") 
     .attr("r", function (d, i) { 
      if (d.status != "0") { 
       return r*2; 
      } else { 
       if (d.iconimage == "") { return r; } else { return 1; } 
      } 
     }) 
     .style("fill", function (d, i) { if (d.status != "0") { if (d.status == "1") { return "#ff0000"; } else { return "#FFBF00"; } } else { return "#FFFFFF"; }}) 
     .style("stroke", function (d) { 
      if (d.style !== 'filled') { return d.color; }; 
     }) 
     .style("stroke-width", "4"); 


     //attach images to the nodes 
     vis.selectAll(".realnode").append("image") 
     .attr("xlink:href", function (d) { return d.iconimage; }) 
     .attr("x", -16) 
     .attr("y", -16) 
     .attr("width", 32) 
     .attr("height", 32); 

注意:我使用的节点类是节点(所有节点)和真实节点(真实对象)(因为我以后还将文本标签建模为不同的类标签节点)。 nodeArray只是一个格式为节点的对象数组,而linkArray只是一个链接数组。

你可以看到我定义了'链接'和'节点' - 就像所有的例子一样 - 但是如果我使用了node.selectAll(“。realnode”),我发现圆圈和图片没有正确附加。追加...但工作正常,如果我使用vis.selectAll(“。realnode”)。追加...所以我只是这样做,移动

但我想我需要解决这种缺乏理解!

稍后,当我从nodeArray中删除节点并链接出linkArray并更新显示时,我又在与'vis'混合使用'node'和'link'对象 - 在这一点上它所有错误和腐败。尽管页面上的svg元素仍然具有定义的正确对象,但是图像交换,文本交换和链接自身浮动,而不需要节点!我检查了nodeArray和linkArray,它们是完全正确的,如果我在第一次加载页面时使用更新后的“新”数据作为原始数据,它会呈现很好,所以我对我的数据对象相当有信心。

我认为最好的方式是让我回答任何问题,并随着我的进行更新,因为我希望有人看到这个,看看我做错了什么。真正令人讨厌的是初始页面加载总是完美的,但数据的更新使我比从头开始的整个初始页面绘制代码更长!

感谢

--Chris

+0

看起来你在'.selectAll(“。realnode”)'之后缺少'.data()'调用? – 2013-05-12 19:24:23

+0

它最初的工作..不争议你是对的,但我不明白为什么如果这种情况下,它的作品呢? – zuzzy 2013-05-12 19:45:00

+0

它看起来已经有了这个类的一些元素,否则它根本不起作用。 – 2013-05-12 20:57:02

回答

0

如果我理解的代码和说明权,nodeArray有一些项目进行node类和其他人realnode类。创建节点时,只选择类node的节点,这允许创建每个类的组,但只将选择限制到类node的组。我认为你需要用两个类

nodes = vis.selectAll('g') 
    .data(nodeArray) 
    ... 
    .call(force.drag); 

创建节点,然后通过基于类的元素的选择操作:

nodes.selectAll('g.realnode') 
    // ... set attributes here 

另外,我建议使用CSS设置属性

links = vis.selectAll('line') 
    .classed('real-link', function(d) { return d.class == 'link reallink'; }); 

并在CSS:

链路和节点的类0
+0

这不是一个坏主意,我需要给它一个去看看它是否修复了问题(希望)或只是改善了代码(绝对!)。也就是说,所有节点都是类节点,但是真正的节点是node&realnode,标签是node&labelnode,链接也是如此。但这样做可能会让我为每种类型的节点维护单独的变量,这可能会更好。我仍然不明白为什么我所有的工作,以及为什么如果它工作对nodeArray和linkArray的后续更新,并重新运行此代码会破坏模型? – zuzzy 2013-05-13 10:11:41

+0

(我会提高答案,但我需要更多的代表这样做) – zuzzy 2013-05-13 10:15:37

+0

要为一个元素指定多个类,请不要使用attr(“class”,function),请使用classed(“class”,function )方法:https://github.com/mbostock/d3/wiki/Selections#wiki-classed。 – 2013-05-13 11:27:45