dbclick more than once functionality not working force-directed graph d3.js

588 Views Asked by At

I need my nodes to be pinned in the first dblclick and change color and stroke of the node. On the second dblclick i want to reverse these back. With the below code for the dblclick function, for the first dblclick the color of the node is changing to teal but the node is not getting pinned. The second dblclick does not do anything either. Can someone please help.

var force = d3.layout.force()
    .nodes(d3.values(nodes))
    .links(links)
    .size([width, height])
    .linkDistance(60)
   // .linkStrength(1)
   // .friction(0)
   // .gravity(0)
    .charge(-250)
    .on("tick", tick)
    .start();

// Set the range
var  v = d3.scale.linear().range([0, 100]);

// Scale the range of the data
v.domain([0, d3.max(links, function(d) { return d.value; })]);


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

// build the arrow.
svg.append("svg:defs").selectAll("marker")
    .data(["end"])      // 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");


// add the links and the arrows
var path = svg.append("svg:g").selectAll("path")
    .data(force.links())
  .enter().append("svg:path")
    .attr("class", function(d) { return "link " + d.type; })
    .style("stroke", function(d){ 
        if(d.value < 1) {return 'blue'} else {return 'red'} 
    }) ;

// define the nodes
var node = svg.selectAll(".node")
    .data(force.nodes())
  .enter().append("g")
    .attr("class", "node")
    .on("dblclick", dblclick)
    .call(force.drag);


//radius depends on weight of node
node.append("circle")
  .attr("r", function(d) {
    var minRadius = 5;
    return minRadius + (d.weight * 2);
    })
   .on("dblclick", dblclick);


node.append("text")
      .attr("dx", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.name });

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

// add the curvy lines
function tick() {
    path.attr("d", function(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;
    });

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

function dblclick1(d) {
  d3.select(this)
  .attr("stroke", "#000000")
  .attr("stroke-width", 1)
  .style("fill", "teal")
  .classed("fixed", d.fixed = true)};

function dblclick(d) {  
        console.log("dblclick")
        if (d.fixed == true) { //pinned state
          console.log("pinned")
          d3.select(this)
          .attr("stroke", "#000000")
          .attr("stroke-width", 0)
          .style("fill", "white")
          .classed("fixed", d.fixed = false);//now unpin
        } 
        else 
        { //else not pinned state
          console.log("not pinned")
          d3.select(this)
          .attr("stroke", "#000000")
          .attr("stroke-width", 1)
          .style("fill", "teal")
          .classed("fixed", d.fixed = true);//now pin
        }
}//end dbl click
1

There are 1 best solutions below

0
On

Actually i was able to figure this out. I was calling the function .on("dblclick", dblclick) twice, during the node creation and during the circle appending. This was causing the node to be pinned and then unpin again. Removing one of the function call fixed the issue.