2015-01-16 56 views
0

我有一些问题与d3js,我无法弄清楚发生了什么事情。这个想法是从一些端点数据(第一个img)绘制初始图形,这很好。每个节点都是可点击的,点击ajax调用该节点并返回数据,根据该点处的某些条件nodes.push(xx),links.push(xx)恰好添加新节点并调用restart()绘制新节点和链接。问题在于主图做的是正确的事情(截图中没有显示,因为我必须在第一个图上放置假数据,即调用端点/记录/ ID /第一个不返回数据),但有一堆随机节点出现在右下角。D3js强制重复输入节点()

你也可以看到下面的例子,即使在点击第一个/第二个/第三个数据后没有改变,但在重新启动()之后的node.enter()出现了错误,并且传入了相同的数据。 。

JS FIDDLE:http://jsfiddle.net/5754j86e/

initial graph

after click

var w = 1200, 
     h = 1200; 

var nodes = []; 
var links = []; 
var node; 
var link; 
var texts; 

var ids = []; 

var circleWidth = 10; 

var initialIdentifier = "marcin"; 

nodes = initialBuildNodes(initialIdentifier, sparql); 

links = initialBuildLinks(sparql); 

//Add SVG 

var svg = d3.select('#chart').append('svg') 
    .attr('width', w) 
    .attr('height', h); 

var linkGroup = svg.append("svg:g").attr("id", "link-group"); 
var nodeGroup = svg.append("svg:g").attr("id", "node-group"); 
var textGroup = svg.append("svg:g").attr("id", "text-group"); 

//Add Force Layout 

var force = d3.layout.force() 
    .size([w, h]) 
    .gravity(.05) 
    .charge(-1040); 

force.linkDistance(120); 

restart(); 


function restart() { 

    force.links(links) 

    console.log("LINKS ARE: ", links) 

    link = linkGroup.selectAll(".link").data (links); 

    link.enter().append('line') 
     .attr("class", "link"); 

    link.exit().remove(); 

    force.nodes(nodes) 

    console.log("NODES ARE: ", nodes) 

    node = nodeGroup.selectAll(".node").data (nodes); 

    node.enter().append("svg:g") 
      .attr("class", "node") 
      .call(force.drag); 

    node.append('circle') 
     .attr('cx', function(d) { return d.x; }) 
     .attr('cy', function(d) { return d.y; }) 
     .attr('r', circleWidth) 
     .attr('fill', function(d, i) { 
      if (i>0) { return palette.pink } 
      else { return palette.blue } 
     }) 

     .on("click", function(d) { 
      nodeClicked (d); 
     }) 

     .on('mouseenter', function(d){ 
      nodeMouseEnter(d) 
      }) 
     .on('mouseout', function(d){ 
      nodeMouseOut(d) 
     }); 


    node.exit().remove(); 

    var annotation = textGroup.selectAll(".annotation").data (nodes); 

    annotation.enter().append("svg:g") 
      .attr("class", "annotation") 
      .append("text") 
      .attr("x", function(d) { return d.radius + 4 }) 
      .attr("y", ".31em") 
      .attr("class", "label") 
      .text(function(d) { return d.name; }); 
    annotation.exit().remove(); 


    force.start(); 
} 


function nodeClicked (d) { 

    // AJAX CALL happens here and bunch of nodes.push({name: "new name"}) happen 

} 


force.on('tick', function(e) { 
     link 
      .attr('x1', function(d) { return d.source.x }) 
      .attr('y1', function(d) { return d.source.y }) 
      .attr('x2', function(d) { return d.target.x }) 
      .attr('y2', function(d) { return d.target.y }) 

     node.attr('transform', function(d, i) { 
      return 'translate('+ d.x +', '+ d.y +')'; 
     }) 

     svg.selectAll(".annotation").attr("transform", function(d) { 
      var labelx = d.x + 13; 
      return "translate(" + labelx + "," + d.y + ")"; 
     }) 



    }); 
+0

你可以支持一个小提琴,代码墙比小提琴更有帮助! – Pogrindis

+0

http://jsfiddle.net/5754j86e/,链接不工作,但你可以看到点击重启()更新会发生什么 - 数据没有改变... – Marcin

回答

1

好吧,我去t将其基础上的文档(https://github.com/mbostock/d3/wiki/Selections#enter):

var update_sel = svg.selectAll("circle").data(data) 
update_sel.attr(/* operate on old elements only */) 
update_sel.enter().append("circle").attr(/* operate on new elements only */) 
update_sel.attr(/* operate on old and new elements */) 
update_sel.exit().remove() /* complete the enter-update-exit pattern */ 

从我的代码,你可以看到我输入(),然后我再一次在一个单独的语句添加节点圈。

node = nodeGroup.selectAll(".node").data (nodes); 

    node.enter().append("svg:g") 
      .attr("class", "node") 
      .call(force.drag); 

    node.append('circle') 
     .attr('cx', function(d) { return d.x; }) 
     .attr('cy', function(d) { return d.y; }) 
     .attr('r', circleWidth) 
     .attr('fill', function(d, i) { 
      if (i>0) { return palette.pink } 
      else { return palette.blue } 
     }); 

加入圈子应该是进入的范围内(),否则它发生所有节点不仅节点,因此它应该是:

node.enter().append("svg:g") 
     .attr("class", "node") 
     .call(force.drag) 

     .append('circle') 
     .attr('cx', function(d) { return d.x; }) 
     .attr('cy', function(d) { return d.y; }) 
     .attr('r', circleWidth) 
     .attr('fill', function(d, i) { 
      if (i>0) { return palette.pink } 
      else { return palette.blue } 
     });