Change color of nodes on double click in D3

I want the node color to change with double click. those. on the first double-click it will turn black, but on the second double-click it will revert to its original color. I can make it black on the first double click, but I can't get it to go back to its original color. Thanks in advance and here is my code.

var gnodes = svg.selectAll('g.gnode')
                .data(graph.nodes)
                .enter()
                .append('g')
                .classed('gnode', true);

var node = gnodes.append("circle")
                 .attr("class", "node")
                 .attr("r", 5)
                 .style("fill", function(d) {return d.colr; })
                 .on('dblclick', function (d)
                 {
                         if (d3.select(this).style("fill") != "black")
                            {
                                d3.select(this).style("fill", "black");
                            }
                        else
                            {
                                d3.select(this).style("fill", function(d){return d.colr;});
                            }
                })
                .call(force.drag);

      

+3


source to share


2 answers


The problem you are facing is actually really complex.

You are checking if the style matches the fill

string "black"

. The problem is that many browsers (including Chrome and FF) reformat color names to RGB strings. This way, when you set padding to "black"

, it is converted to an RGB string "rgb(0, 0, 0)"

. So the call d3.select(this).style("fill")

will return that rgb string, not the color name, ensuring that else

your code branch never runs.



You can avoid having to check the current padding state as a style string by using selection.each

to store each circle state as a boolean value, and then register a double click handler for it that switches booleans and then branches based on its value. Try the following:

var node = gnodes.append("circle")
  .attr("class", "node")
  .attr("r", 5)
  .style("fill", function(d) {return d.colr; })
  .each(function() {
    var sel = d3.select(this);
    var state = false;
    sel.on('dblclick', function() {
      state = !state;
      if (state) {
        sel.style('fill', 'black');
      } else {
        sel.style('fill', function(d) { return d.colr; });
      }
    });
  });

      

+3


source


One way to deal with this is through CSS:

.doubled { fill: black !important; }

      

Then switch this CSS class into your dblclick function:



d3.selectAll(".node")
  .on("dblclick", function() {
    var c = d3.select(this).classed("doubled");
    d3.select(this).classed("doubled", !c);
  })

      

Working example here: http://jsfiddle.net/qAHC2/829/

+1


source







All Articles