title: d3js force button to allow/disable drag actions
body: <p>My goal is to allow or disable the drag action on the nodes of my graph. I have this input : <code>&lt;input id="drag" name="drag" type="button" value="switch drag" /&gt;</code>. I found some hints <a href="http://www.d3noob.org/2014/04/using-html-inputs-with-d3js.html" rel="nofollow noreferrer">here</a> and on <a href="https://stackoverflow.com/questions/13136355/d3-js-remove-force-drag-from-a-selection">this question</a>. </p>
  
  <p>As I said in a comment below,  it doesn't work if I create nodes and links from an external json file. Is my function d3.json("graph.json", function(error, graph) {...}); not correct ?</p>
  
  <p>Here's my json file:</p>
  
  <pre><code>{
    "nodes": [
      {"x": 260, "y": 210, "fixed": true},
      {"x": 300, "y": 210, "fixed": true},
      {"x": 260, "y": 260, "fixed": true},
      {"x": 300, "y": 260, "fixed": true}
    ],
    "links": [
      {"source":  0, "target":  1},
      {"source":  0, "target":  2},
      {"source":  2, "target":  3},
      {"source":  3, "target":  1}
     ]
  }
  </code></pre>
  
  <p>And here's my code :</p>
  
  <pre><code>   var width = 960, height = 500;
  
     var svg = d3.select("body")
                 .append("svg")
                 .attr("width", width)
                 .attr("height", height);
  
  
     var myLinks = svg.selectAll(".link");
     var myNodes = svg.selectAll(".node");
  
     var force = d3.layout.force()
         .size([width, height])
         .charge(-400)
         .linkDistance(40)
         .on("tick", tick);
  
     // Allows the drag actions 
     var drag = force.drag();
  
     // Read the json file and creates the links and the nodes
     d3.json("graph.json", function(error, graph) {
        if (error) alert(error);    
  
        force
           .nodes(graph.nodes)
           .links(graph.links)
           .start();
  
        myLinks = myLinks.data(graph.links)
           .enter()
           .append("line")
           .attr("class", "link");
  
        myNodes = myNodes.data(graph.nodes)
           .enter()
           .append("circle")
           .attr("class", "node")
           .attr("r", 6)
           .call(drag);
     });
  
     // Add properties to myLinks and myNodes
     function tick() {
        myLinks.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; });
  
        myNodes.attr("cx", function(d) { return d.x; })
           .attr("cy", function(d) { return d.y; });
     }
  
     var dragOnOff = d3.select("#drag");
  
     dragOnOff.on("click", function() { 
        myNodes.on('mousedown.drag', null);
     });
  
     var dragOnOff = d3.select("#drag");
  
     var dragCallback = myNodes.property('__onmousedown.drag')['_'];
  
     var draggable = true;
  
     dragOnOff.on("click", function () {
         myNodes.on('mousedown.drag', draggable ? null : dragCallback);
         this.value = 'switch drag to ' + draggable;
         draggable = !draggable;
     }); 
  </code></pre>
  
  <p>I wish someone could answer me and my post can help someone else !
  Thanks in advance!</p>