javascript - D3动态网络实时添加节点时速度慢

标签 javascript d3.js

我正在努力找出为什么我的 codepen当我实时传输节点和链接时速度很慢。

在 codepen 中,我通过使用 links1nodes1 数组模拟了实时内容。 我使用 forEach 添加节点和链接,并分别调用 add_prcadd_conn ,这在内部调用 refresh 来显示新添加的节点或链接。

请点击重置按钮开始模拟。

最佳答案

通过较小的更改来解决主要问题。

这是一个屏幕截图,它将清楚地解释添加节点、链接的速度减慢(这只是通过初始重置单击,想象一下当节点数量增加时它会实时添加的节点数量):

enter image description here

要解决此问题,您必须更改节点输入选择(现在不正确)。这是新节点输入选择:

node = node.data(nodes);

var nodeEnter = node.enter().insert("g").attr("class", "node")
   .call(force.drag);

nodeEnter
 .append("image")
 ...

nodeEnter
 .append('text')
 ...

请注意差异,我不会在每次调用时附加图像文本

这是代码片段:

#nodeConsole {
  width: 80%;
  height: 1px;
  font-family: courier new;
  padding: 1px;
  border: 3px solid gray;
  margin-top: 1px;
  overflow: auto;
}

#linkedNodes {
  width: 80%;
  font-family: courier new;
  padding: 10px;
}

#srcNodes {
  width: 40%;
  font-family: courier new;
  padding: 8px;
}

#targetNodes {
  width: 40%;
  font-family: courier new;
  padding: 8px;
}

rect {
  fill: none;
  pointer-events: all;
}

.node {
  fill: #000;
}

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

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

path.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <button id="ref" onclick="refresh()">refresh </button>
    <button id="reset" onclick="reset()">reset </button>
    <script>
    
    

 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"}];
    //refresh();
    
     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 node = {        x: 900,    y: 900,        id: nodeName,    grp:g  };
        var n = nodes.push(node);
       // console.log(node);
        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 = 960,
  height = 500;

var fill = d3.scale.category20();

var links = [{ source:  "FH", target: "TP" }];
var nodes = [
    { id: "FH", x: 100, y: 110 },
    { id: "TP", x: 200, y: 110 },
    { id: "GW", x: 200, y: 110 },
    { id: "DB", x: 100, y: 110 }
  ]

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()
  .size([width, height])
  .nodes(nodes) .links(links)
  .linkDistance(50)
  .charge(-50)
  .on("tick", tick);

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

// build the arrow.
var arrows = svg
  .append("svg:defs")
  .selectAll("marker")
  .data(["arrow"]) // Different link/path types can be defined here
  .enter()
  .append("svg:marker") // This section adds in the arrows
  .attr("id", String)
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", -1.5)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");


svg
  .append("rect")
  .attr("width", width)
  .attr("height", height);

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


function tick() {
  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 refresh(){
  
  node = node.data(nodes);
  
  var nodeEnter = node.enter().insert("g")
  	.attr("class", "node")
    .call(force.drag);
  
  nodeEnter
    .append("image")
    .attr("xlink:href", "https://github.com/favicon.ico")
    .attr("x", -8)
    .attr("y", -8)
    .attr("width", 16)
    .attr("height", 16);
  nodeEnter
    .append("text")
    .attr("dx", 12)
    .attr("dy", ".35em")
    .text(function(d) {
      return d.id;
    });
  node.exit().remove();

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

  force.start();
}


    </script>

这是一个 JSFIDDLE (我是 jsfiddle 粉丝)。

我发现您已从 Canvas 转移到 SVG。无论如何,希望这会有所帮助。

关于javascript - D3动态网络实时添加节点时速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51459097/

相关文章:

javascript - 从文本中删除 HTML

java - 为什么 images.google.com GET 请求具有如此不可读的形式?

javascript - d3 图表在 X 轴刻度中显示一些小数值,而不是显示日期和时间

javascript - 动态生成多个 d3 svg 图

javascript - 如何将 "average"线添加到 nvd3.js 堆积面积图?

javascript - jQuery 在 x 毫秒后隐藏通知

javascript - 按键值过滤 JSON

javascript - 如何在javascript中提取特定字符之间的子字符串

javascript - 用正确的数字创建一条路径

javascript - 每天使用 dc.js 进行规模化