2016-05-08 8 views
1

現在、グラフ(頂点+エッジ)を作成しアルゴリズムを適用するプログラムを開発中です。私はこのプログラムを作るために3d.jsを選びました。 私は頂点を追加するときにrepaint関数に関する問題に直面しています。3d.js - 強制有向グラフでのノードの更新

...私は最初の頂点を追加すると

、それが仕事だが、次のために、私の頂点が(頂点&ラベル)急速に増殖スクリーンショット:


enter image description here
enter image description here

ソースコード:


<!DOCTYPE html> 
<html> 
<head> 
    <title>Graph</title> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
    <style> 
     html{ 
      background-color: #042029; 
     } 
    </style> 
</head> 
<body> 
<button onclick="addNodes()">Restart Animation</button> 
<script> 

    var graph = (function() { 
    return { 
     modules: {}, 
     nodes: [], 
     links: [] 
    } 
})(); 

graph.modules.engin = (function() { 
    var w, h, circleWidth, svgApp, force, link, node, nodes; 
    var palette = { 
     "white": "#FFFFFF", 
     "gray": "#708284", 
     "orange": "#BD3613", 
     "red": "#D11C24", 
     "blue": "#2176C7" 
    }; 
    return { 
     init: function() { 
      var w = 960, 
       h = 450; 

      circleWidth = 7; 

      svgApp = d3.select("body") 
       .append("svg:svg") 
       .attr("width", w) 
       .attr("height", h) 
       .attr("id", "svg") 
       .attr("pointer-events", "all") 
       .attr("viewBox", "0 0 " + w + " " + h) 
       .attr("perserveAspectRatio", "xMinYMid") 
       .append('svg:g'); 

      force = d3.layout.force() 
       .nodes(graph.nodes) 
       .links([]) 
       .gravity(0.1) 
       .charge(-1000) 
       .size([w, h]); 


      //console.log(nodes); 
      //nodes.push({}) 
      graph.modules.engin.repaint(); 

      graph.modules.engin.insertNode('V1'); 
      graph.modules.engin.insertNode('V2'); 
      graph.modules.engin.insertNode('V3'); 
     }, 
     repaint: function(){ 
      console.log('update'); 

      nodes = force.nodes(); 
      var links = force.links(); 

      link = svgApp.selectAll(".link") 
       .data(links); 
      link.enter().append("line") 
       .attr("class", "link") 
       .attr("stroke", palette.gray) 
       .attr("fill", "none"); 
      link.exit().remove(); 


      node = svgApp.selectAll("circle.node") 
       .data(nodes); 
      node.enter().append("g") 
       .attr("class", "node") 
       .on("mouseover", function (d, i) { //MOUSEOVER 
        if (!d.root) { 
         d3.select(this).selectAll("circle") 
          .transition() 
          .duration(250) 
          .style("cursor", "none") 
          .attr("r", circleWidth + 3) 
          .attr("fill", palette.orange); 

         d3.select(this).select("text") 
          .transition() 
          .style("cursor", "none") 
          .duration(250) 
          .style("cursor", "none") 
          .attr("font-size", "1.5em") 
          .attr("x", 15) 
          .attr("y", 5) 
        } else { 
         d3.select(this).selectAll("circle") 
          .style("cursor", "none"); 

         d3.select(this).select("text") 
          .style("cursor", "none"); 
        } 
       }) 
       .on("mouseout", function (d, i) { //MOUSEOUT 
        if (!d.root) { 
         //CIRCLE 
         d3.select(this).selectAll("circle") 
          .transition() 
          .duration(250) 
          .attr("r", circleWidth) 
          .attr("fill", palette.blue); 

         //TEXT 
         d3.select(this).select("text") 
          .transition() 
          .duration(250) 
          .attr("font-size", "1em") 
          .attr("x", 8) 
          .attr("y", 4) 
        } 
       }) 
       .call(force.drag); 

      node.append("svg:circle") 
       .attr("cx", function (d) { 
        return d.x; 
       }) 
       .attr("cy", function (d) { 
        return d.y; 
       }) 
       .attr("r", circleWidth) 
       .attr("fill", function (d, i) { 
        if (!d.root) { 
         return palette.blue; 
        } else { 
         return palette.red 
        } 
       }); 

      node.append("text") 
       .text(function (d, i) { 
        return d.name; 
       }) 
       .attr("x", function (d, i) { 
        return circleWidth + 5; 
       }) 
       .attr("y", function (d, i) { 
        if (!d.root) { 
         return circleWidth 
        } else { 
         return circleWidth + 5 
        } 
       }) 
       .attr("font-family", "Bree Serif") 
       .attr("fill", function (d, i) { 
        return palette.white; 
       }) 
       .attr("font-size", function (d, i) { 
        return "1em"; 
       }) 
       .attr("text-anchor", function (d, i) { 
        if (!d.root) { 
         return "beginning"; 
        } else { 
         return "end" 
        } 
       }); 
      node.exit().remove(); 

      force.on("tick", function (e) { 
       node.attr("transform", function (d, i) { 
        return "translate(" + d.x + "," + d.y + ")"; 
       }); 

       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; 
        }) 
      }); 

      force.start(); 
     }, 
     insertNode: function(name) { 
      nodes.push({name: name}) 
      graph.modules.engin.repaint(); 
     } 
    } 
})(); 
$(document).ready(function(){ 
    graph.modules.engin.init(); 
}); 
</script> 
</body> 
</html> 

私は私の問題を解決し、 YM

答えて

0

ありがとう:変数の参照ミスとセレクタ要素を:

ソースコード:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Graph</title> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
    <style> 
     html{ 
      background-color: #042029; 
     } 
     body { 
      height: 600px; 
      width: 100%; 
     } 
    </style> 
</head> 
<body> 
<button onclick="addNodes()">Restart Animation</button> 
<script> 

    var graph = (function() { 
    return { 
     modules: {}, 
     nodes: [], 
     links: [] 
    } 
})(); 

graph.modules.engin = (function() { 
    var w, h, circleWidth, svgApp, force; 
    var palette = { 
     "white": "#FFFFFF", 
     "gray": "#708284", 
     "orange": "#BD3613", 
     "red": "#D11C24", 
     "blue": "#2176C7" 
    }; 
    return { 
     init: function() { 
      h = $('body').height(); 
      w = $('body').width(); 

      circleWidth = 7; 

      svgApp = d3.select("body") 
       .append("svg:svg") 
       .attr("pointer-events", "all") 
       .attr("width", w) 
       .attr("height", h) 
       .attr("viewBox", "0 0 " + w + " " + h) 
       .attr("perserveAspectRatio", "xMinYMid"); 

      force = d3.layout.force(); 

      graph.nodes = force.nodes(); 
      graph.links = force.links(); 

      graph.modules.engin.repaint(); 

      graph.modules.engin.insertNode('V1'); 
      graph.modules.engin.insertNode('V2'); 
      graph.modules.engin.insertNode('V3'); 
     }, 
     repaint: function(){ 
      console.log('update'); 

      var nodes = force.nodes(); 
      var links = force.links(); 

      console.log('BEFORE REPAINT'); 
      console.log(nodes); 
      console.log(links); 
      console.log(graph.nodes); 
      console.log(graph.links); 

      var link = svgApp.selectAll("line.link") 
       .data(links); 
      var linkEnter = link.enter().append("line") 
       .attr("class", "link") 
       .attr("stroke", palette.gray) 
       .attr("fill", "none"); 
      link.exit().remove(); 


      var node = svgApp.selectAll("g.node") 
       .data(nodes, function (d) { 
        return d.name; 
       }); 

      var nodeEnter = node.enter().append("g") 
       .attr("class", "node") 
       .on("mouseover", function (d, i) { 
        if (!d.root) { 
         d3.select(this).select("circle") 
          .transition() 
          .duration(250) 
          .style("cursor", "none") 
          .attr("r", circleWidth + 3) 
          .attr("fill", palette.yellow); 

         d3.select(this)//.select("text") 
          .transition() 
          .style("cursor", "none") 
          .duration(250) 
          .style("cursor", "none") 
          .attr("font-size", "1.5em") 
          .attr("x", 15) 
          .attr("y", 5) 
        } else { 
         d3.select(this).select("circle") 
          .style("cursor", "none"); 

         d3.select(this).select("text") 
          .style("cursor", "none"); 

        } 
       }) 
       .on("mouseout", function (d, i) { 
        if (!d.root) { 
         d3.select(this).select("circle") 
          .transition() 
          .duration(250) 
          .attr("r", circleWidth) 
          .attr("fill", palette.blue); 

         d3.select(this)//.select("text") 
          .transition() 
          .duration(250) 
          .attr("font-size", "1em") 
          .attr("x", 8) 
          .attr("y", 4) 
        } 
       }) 
       .call(force.drag); 

      nodeEnter.append("svg:circle") 
       .attr("cx", function (d) { 
        return d.x; 
       }) 
       .attr("cy", function (d) { 
        return d.y; 
       }) 
       .attr("r", circleWidth) 
       .attr("fill", function (d, i) { 
        if (!d.root) { 
         return palette.blue; 
        } else { 
         return palette.red 
        } 
       }).attr("id", function (d) { 
       return "Node-" + d.name; 
      }); 

      nodeEnter.append("svg:text") 
       .text(function (d, i) { 
        return d.name; 
       }) 
       .attr("x", function (d, i) { 
        return circleWidth + 5; 
       }) 
       .attr("y", function (d, i) { 
        if (!d.root) { 
         return circleWidth - 2 
        } else { 
         return circleWidth + 5 
        } 
       }) 
       .attr("font-family", "Bree Serif") 
       .attr("fill", function (d, i) { 
        return palette.white; 
       }) 
       .attr("font-size", function (d, i) { 
        return "1em"; 
       }) 
       .attr("text-anchor", function (d, i) { 
        if (!d.root) { 
         return "beginning"; 
        } else { 
         return "end" 
        } 
       }); 

      node.exit().remove(); 

      force.on("tick", function (e) { 
       node.attr("transform", function (d, i) { 
        return "translate(" + d.x + "," + d.y + ")"; 
       }); 

       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; 
        }) 
      }); 

      force.gravity(0.1) 
       .charge(-1000) 
       .size([w, h]) 
       .start(); 
     }, 
     insertNode: function(name) { 
      graph.nodes.push({name: name}) 
      graph.modules.engin.repaint(); 
     } 
    } 
})(); 
$(document).ready(function(){ 
    graph.modules.engin.init(); 
}); 
</script> 
</body> 
</html> 
関連する問題