在D3中双击更改节点的颜色

时间:2014-09-25 23:46:48

标签: javascript d3.js attributes double-click

我希望双击时更改节点的颜色。即在第一次双击时,它会变黑,但重新点击它时,它会变回原来的颜色。我可以在第一次双击时使其变黑,但我无法使其恢复原来的颜色。在此先感谢,这是我的代码。

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

2 个答案:

答案 0 :(得分:3)

你在这里遇到的问题实际上非常棘手。

您正在检查fill样式是否等于字符串"black"。问题是,许多浏览器(包括Chrome和FF)将颜色名称重新格式化为RGB字符串。因此,当您将填充设置为"black"时,它将转换为RGB字符串"rgb(0, 0, 0)"。实际上,调用d3.select(this).style("fill")将返回此rgb字符串而不是颜色名称,从而确保代码的else分支永远不会运行。

通过使用selection.each将每个圆的状态存储为布尔值,然后注册其双击处理程序,切换布尔值,然后注册,可以避免必须将填充的当前状态检查为样式字符串基于其价值的分支。试试这个:

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

答案 1 :(得分:1)

处理此问题的一种方法是通过CSS:

.doubled { fill: black !important; }

然后在dblclick函数中切换此CSS类:

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

这里的工作示例:http://jsfiddle.net/qAHC2/829/