2016-01-23 80 views
1

我使用强制布局算法绘制图形。但我希望用户能够禁用强制布局算法并能够移动节点。我遵循示例here(P是用于固定)作为基础来构建我的代码。在d3中禁用强制布局算法中的力

但是,我希望用户欣赏基于力的算法的美妙之处,因此只有在用户按下“Make draggable”按钮后才能启用拖动和固定功能。

这里是我使用的代码...

<!DOCTYPE html> 
<html lang="en"> 
<style> 

    .node { 
     stroke: #fff; 
     stroke-width: 1.5px; 
    } 

    .link { 
     stroke: #999; 
     stroke-opacity: .6; 
    } 


</style> 
<head> 
    <meta charset="UTF-8"> 
    <title>Spatial Social Network</title> 

    <script src="//d3js.org/d3.v3.min.js"></script> 
</head> 
<body> 
    <h1>The network</h1> 

    <script> 
     var width = 500, 
      height = 500; 

     var color = d3.scale.category20(); 


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

     var force = d3.layout.force() 
       .charge(-120) 
       .linkDistance(30) 
       .size([width, height]); 

     /*Drag and pin*/ 
     var node_drag = d3.behavior.drag() 
      .on("dragstart", dragstart) 
      .on("drag", dragmove) 
      .on("dragend", dragend); 
     function dragstart(d, i) { 
      alert("I am here"); 
      force.stop() // stops the force auto positioning before you start dragging 
     } 
     function dragmove(d, i) { 
      d.px += d3.event.dx; 
      d.py += d3.event.dy; 
      d.x += d3.event.dx; 
      d.y += d3.event.dy; 
     } 
     function dragend(d, i) { 
      d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff 
      force.resume(); 
     } 
     function releasenode(d) { 
      d.fixed = false; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff 
      //force.resume(); 
     } 
     /*Drag and pin*/ 

     svg.append('text') 
      .attr("x", 2) 
      .attr("y", 20) 
      .text("Force Layout") 
      .attr("font-family", "sans-serif") 
      .attr("font-size", "20px") 
      .attr("fill", "red"); 


     d3.json("jsonGraph.json", function(error, graph) { 
      if (error) throw error; 


      //console.log(graph.nodes); 

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

      var link = svg.selectAll(".link") 
       .data(graph.links) 
       .enter().append("line") 
       .attr("class", "link"); 


      var node = svg.selectAll(".node") 
       .data(graph.nodes) 
       .enter().append("circle") 
       .attr("class", "node") 
       .attr("r", 5) 
       .style("fill", function(d) { return color(d.class); }) 
       .call(force.drag);     

      node.append("title") 
       .text(function(d) { return d.id; }); 

      force.on("tick", function() { 
       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("cx", function(d) { return d.x; }) 
       .attr("cy", function(d) { return d.y; }); 
      }); 



     }); 

     function MakeDraggable() 
     { 
      alert("here"); 
      d3.json("jsonGraph.json", function(error, graph) { 
       if (error) throw error; 


       force 
        .nodes(null) 
        .links(null) 
        .start(); 

       var link = svg.selectAll(".link") 
        .data(graph.links) 
        .enter().append("line") 
        .attr("class", "link"); 

       var node = svg.selectAll(".node") 
        .data(graph.nodes) 
        .enter().append("circle") 
        .attr("class", "node") 
        .attr("r", 5) 
        .style("fill", function(d) { return color(d.class); }) 
        //.call(force.drag); 
        .call(node_drag) 
        .on('dblclick', releasenode); 

       //force.stop(); 

      }); 
     } 



    </script> 

    <input type="button" name="MakeDraggable" value="Make Draggable!" onClick="MakeDraggable()"></input> 

</body> 
</html> 

遗憾的是,似乎没有要在行为上的任何变化,即使按下按钮后,“让可拖动的!”。

这里是我用来阅读图表JSON文件:

{ 
"directed": false, 
"graph": { 
    "name": "Fun Graph" 
}, 
"nodes": [ 
    { 
     "class": "A", 
     "id": "A" 
    }, 
    { 
     "class": "B", 
     "id": "C" 
    }, 
    { 
     "class": "B", 
     "id": "B" 
    }, 
    { 
     "class": "B", 
     "id": "E" 
    }, 
    { 
     "class": "B", 
     "id": "D" 
    }, 
    { 
     "class": "A", 
     "id": "G" 
    }, 
    { 
     "class": "B", 
     "id": "F" 
    }, 
    { 
     "class": "A", 
     "id": "I" 
    }, 
    { 
     "class": "B", 
     "id": "H" 
    }, 
    { 
     "class": "A", 
     "id": "K" 
    }, 
    { 
     "class": "B", 
     "id": "J" 
    }, 
    { 
     "class": "B", 
     "id": "M" 
    }, 
    { 
     "class": "A", 
     "id": "L" 
    }, 
    { 
     "class": "A", 
     "id": "O" 
    }, 
    { 
     "class": "A", 
     "id": "N" 
    } 
], 
"links": [ 
    { 
     "source": 0, 
     "target": 8 
    }, 
    { 
     "source": 0, 
     "target": 9 
    }, 
    { 
     "source": 0, 
     "target": 2 
    }, 
    { 
     "source": 0, 
     "target": 11 
    }, 
    { 
     "source": 0, 
     "target": 4 
    }, 
    { 
     "source": 1, 
     "target": 7 
    }, 
    { 
     "source": 1, 
     "target": 11 
    }, 
    { 
     "source": 2, 
     "target": 11 
    }, 
    { 
     "source": 2, 
     "target": 12 
    }, 
    { 
     "source": 3, 
     "target": 4 
    }, 
    { 
     "source": 3, 
     "target": 5 
    }, 
    { 
     "source": 3, 
     "target": 6 
    }, 
    { 
     "source": 4, 
     "target": 7 
    }, 
    { 
     "source": 4, 
     "target": 11 
    }, 
    { 
     "source": 4, 
     "target": 12 
    }, 
    { 
     "source": 5, 
     "target": 7 
    }, 
    { 
     "source": 5, 
     "target": 8 
    }, 
    { 
     "source": 6, 
     "target": 11 
    }, 
    { 
     "source": 6, 
     "target": 12 
    }, 
    { 
     "source": 7, 
     "target": 13 
    }, 
    { 
     "source": 7, 
     "target": 8 
    }, 
    { 
     "source": 9, 
     "target": 14 
    }, 
    { 
     "source": 10, 
     "target": 11 
    }, 
    { 
     "source": 10, 
     "target": 14 
    }, 
    { 
     "source": 12, 
     "target": 13 
    } 
], 
"multigraph": false 
} 

我是新来D3和不知道在哪里,我错了。

[1]: http://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/ 

回答

2

在点击链接,你不需要重新创建/重载全部力量布局:

function MakeDraggable() 
     { 
      alert("here"); 
      d3.json("jsonGraph.json", function(error, graph) { 
       if (error) throw error; 


       force 
        .nodes(null) 
        .links(null) 
        .start(); 

这可以通过简单地做:

function MakeDraggable() { 
    svg.selectAll(".node").call(node_drag);//attach the drag behavior 
} 

工作演示here

希望这会有所帮助!