实时更新时未出现D3节点

时间:2018-07-23 18:47:12

标签: d3.js

我正在玩Mike Bostock的mobile patent suits example

我正在JSFiddle中使用forEach循环添加约100个节点;实际上,这些节点将由外部服务实时传递。

该页面最初正在加载一些静态节点。 reset按钮调用forEach循环以使用函数add_prc创建新节点。此方法将节点推送到nodes列表(用于在SVG中显示),然后调用refresh方法,但节点未正确显示在屏幕上。

我在屏幕的左上方看到一个点,但是我无法选择它或将其拖动到中心。

1 个答案:

答案 0 :(得分:2)

一旦使用forEach循环添加了节点/链接,就不会在任何地方翻译它们。查看控制台的以下屏幕截图:

Console screenshot

正如我在评论中提到的那样,tick函数将transform应用于先前添加的path, circle and text,但是它是否对新添加的节点,链接添加了任何内容?没有。这就是缺少的东西。据我所知,您正在向其中添加代码:

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) {
  return "translate(" + d.x + "," + d.y + ")";
});

现在,这将在(100,100)处添加所有节点(我知道您只是在测试东西)。无论如何,我使用了随机的xy。这是一个代码段和一个JSFIDDLE

.node {
  fill: #000;
}

.cursor {
  fill: green;
  stroke: brown;
  pointer-events: none;
}


.node text {
  pointer-events: none;
  font: 10px sans-serif;
}

path.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}



.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}

#licensing {
  fill: green;
}

.link.licensing {
  stroke: green;
}

.link.resolved {
  stroke-dasharray: 0,2 1;
}

circle {
  fill: green;
  stroke: red;
  stroke-width: 1.5px;
}

text {
  font: 10px sans-serif;
  pointer-events: none;
  text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
  <button id="reset" onclick="reset()">reset</button>
    <button id="ref" onclick="refresh()">refresh</button>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <script>
    var width = 960,    height = 500;
    var links = [{source:"simulator",target:"monitor" ,type:"resolved"} , {source:"web",target:"monitor" ,type:"resolved"} ];

 var links1 = [{"source":"ctfa","target":"tfa"},
 {"source":"cea","target":"tea"},
 {"source":"ctfe","target":"tfe"},
 {"source":"ctee","target":"tee"},
 {"source":"ctfu","target":"tfu"},
 {"source":"cteu","target":"teu"},
 {"source":"rfa","target":"tfa"},
 {"source":"rea","target":"tea"},
 {"source":"rfe","target":"tfe"},
 {"source":"ree","target":"tee"},
 {"source":"rfu","target":"tfu"},
 {"source":"reu","target":"teu"},
 {"source":"r1fa","target":"rfa"},
 {"source":"r1fa","target":"gfa"},
 {"source":"r1fa","target":"ggf"},
 {"source":"r1ea","target":"rea"},
 {"source":"r1ea","target":"gea"},
 {"source":"r1ea","target":"gge"},
 {"source":"r1fe","target":"rfe"},
 {"source":"r1fe","target":"gfe"},
 {"source":"r1fe","target":"ggf"},
 {"source":"r1ee","target":"ree"},
 {"source":"r1ee","target":"gee"},
 {"source":"r1ee","target":"gge"},
 {"source":"r1fu","target":"rfu"},
 {"source":"r1fu","target":"gfu"},
 {"source":"r1fu","target":"ggf"},
 {"source":"r1eu","target":"reu"},
 {"source":"r1eu","target":"geu"},
 {"source":"r1eu","target":"gge"},
 {"source":"hh1fa","target":"ggf"},
 {"source":"hh1ea","target":"gge"},
 {"source":"hh1fe","target":"ggf"},
 {"source":"hh1ee","target":"gge"},
 {"source":"hh1fu","target":"ggf"},
 {"source":"hh1eu","target":"gge"},
 {"source":"dbfa","target":"gfa"},
 {"source":"dbea","target":"gea"},
 {"source":"dbfe","target":"gfe"},
 {"source":"dbee","target":"gee"},
 {"source":"dbfu","target":"gfu"},
 {"source":"dbeu","target":"geu"},
 {"source":"hflse","target":"tee"},
 {"source":"hfnyse","target":"teu"},
 {"source":"hfnse","target":"teu"},
 {"source":"hfret","target":"tfu"},
 {"source":"hfebs","target":"tfe"},
 {"source":"hfint","target":"tfu"},
 {"source":"c1e","target":"ctee"},
 {"source":"c1e","target":"gge"},
 {"source":"c2e","target":"ctee"},
 {"source":"c3e","target":"cteu"},
 {"source":"c4e","target":"cteu"},
 {"source":"c5e","target":"ggf"},
 {"source":"d1e","target":"ctee"},
 {"source":"c1f","target":"ctfe"},
 {"source":"c2f","target":"ctfe"},
 {"source":"c3f","target":"ggf"},
 {"source":"c4f","target":"gge"},
 {"source":"c5f","target":"ctfa"},
 {"source":"d1f","target":"ctfe"}];

var nodes1 = [{"id":"tfa"},
 {"id":"tea"},
 {"id":"tfe"},
 {"id":"tee"},
 {"id":"tfu"},
 {"id":"teu"},
 {"id":"ctfa"},
 {"id":"cea"},
 {"id":"ctfe"},
 {"id":"ctee"},
 {"id":"ctfu"},
 {"id":"cteu"},
 {"id":"rfa"},
 {"id":"rea"},
 {"id":"rfe"},
 {"id":"ree"},
 {"id":"rfu"},
 {"id":"reu"},
 {"id":"r1fa"},
 {"id":"r1ea"},
 {"id":"r1fe"},
 {"id":"r1ee"},
 {"id":"r1fu"},
 {"id":"r1eu"},
 {"id":"hh1fa"},
 {"id":"hh1ea"},
 {"id":"hh1fe"},
 {"id":"hh1ee"},
 {"id":"hh1fu"},
 {"id":"hh1eu"},
 {"id":"dbfa"},
 {"id":"dbea"},
 {"id":"dbfe"},
 {"id":"dbee"},
 {"id":"dbfu"},
 {"id":"dbeu"},
 {"id":"gfa"},
 {"id":"gea"},
 {"id":"gfe"},
 {"id":"gee"},
 {"id":"gfu"},
 {"id":"geu"},
 {"id":"gge"},
 {"id":"ggf"},
 {"id":"hflse"},
 {"id":"hfnyse"},
 {"id":"hfnse"},
 {"id":"hfret"},
 {"id":"hfebs"},
 {"id":"hfint"},
 {"id":"c1e"},
 {"id":"c2e"},
 {"id":"c3e"},
 {"id":"c4e"},
 {"id":"c5e"},
 {"id":"d1e"},
 {"id":"c1f"},
 {"id":"c2f"},
 {"id":"c3f"},
 {"id":"c4f"},
 {"id":"c5f"},
 {"id":"d1f"}];
 
 
    var nodes = [ {"id":"monitor", "grp":"system"}, {"id":"simulator", "grp":"system"}, {id:"web", grp:"client"}];


      function reset() {
        nodes1.forEach(function(d){ add_prc(d)  });
        links1.forEach(function(d){ add_con(d)  });
    }

 
    function add_prc(newNode) {
        //console.log(newNode);
        addNodeCanvas(newNode.id,newNode.grp);
    }

    function add_con(newConnection) {
        //console.log(newConnection);
        addLinkCanvas( newConnection.source,newConnection.target);  
    }

    //setInterval(refresh, 15000);

    function addNodeCanvas(nodeName,g) {
        var node1 = {        x: Math.floor(Math.random()*200+100),    y: Math.floor(Math.random()*200+100),        id: nodeName,    grp:g  };
        var n = nodes.push(node1);
        //console.log(node1);
        refresh();
    }
    

    function addLinkCanvas(idSrc, idTarget) {
        if (idSrc != idTarget) {
            var s = {},        t = {};
            nodes.forEach(function(curNode) {
                if (typeof curNode.id != "undefined") {
                    if (curNode.id == idSrc) {          s = curNode;        }
                    if (curNode.id == idTarget) {          t = curNode;        }
                }
            });

            //console.log( { s,t});
            links.push({     source: s,      target: t    });
        };
        refresh();
    }



var width = 900,
  height = 600,
    radius = 8;


var map = {}
nodes.forEach(function(d,i){
  map[d.id] = i;
})

links.forEach(function(d) {
  d.source = map[d.source];
  d.target = map[d.target];
})

    var force = d3.layout.force()
    .nodes(d3.values(nodes))
    .links(links)
    .size([width, height])
    .linkDistance(50)
    .charge(-200)
    .on("tick", tick)
    .start();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);


// Per-type markers, as they don't inherit styles.
svg.append("defs").selectAll("marker")
    .data(["suit", "licensing", "resolved"])
  .enter().append("marker")
    .attr("id", function(d) { return d; })
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", -1.5)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
  .append("path")
    .attr("d", "M0,-5L10,0L0,5");

var path = svg.append("g").selectAll("path")
    .data(force.links())
  .enter().append("path")
    .attr("class", function(d) { return "link " + d.type; })
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

var circle = svg.append("g").selectAll("circle")
    .data(force.nodes())
  .enter().append("circle")
    .attr("r", 6)
    .call(force.drag);

var text = svg.append("g").selectAll("text")
    .data(force.nodes())
  .enter().append("text")
    .attr("x", 8)
    .attr("y", ".31em")
    .text(function(d) { return d.id; });

var node = svg.selectAll(".node"),
  link = svg.selectAll(".link");

  
function mousedownNode(d, i) {
  nodes.splice(i, 1);
  links = links.filter(function(l) {
    return l.source !== d && l.target !== d;
  });
  d3.event.stopPropagation();

  refresh();
}
  
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
  path.attr("d", linkArc);
  circle.attr("transform", transform);
  text.attr("transform", transform);
  
  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) {
    return "translate(" + d.x + "," + d.y + ")";
  });  
}

function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = Math.sqrt(dx * dx + dy * dy);
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

function transform(d) {
  return "translate(" + d.x + "," + d.y + ")";
}


 function refresh(){
  node = node.data(nodes);

  node.enter().insert("circle", ".cursor")
    .attr("class", "node")
    .attr("r", 5)
    .on("mousedown", mousedownNode);

  node.exit()
    .remove();

  link = link.data(links);

  link.enter().insert("line", ".node")
    .attr("class", "link");
  link.exit()
    .remove();

  force.start();


    }

    </script>