D3 oncontext菜单,更改选择的节点颜色

时间:2016-04-22 16:15:27

标签: javascript jquery d3.js

我有一个带有右键菜单的节点(即矩形),我试图根据onclick菜单的结果更改节点上的颜色,但节点不会改变颜色。我在代码中有不同的方式/尝试,看看我可能做错了什么。有很多关于onclick双击的论坛,但没有关于oncontextmenu的论坛。任何帮助都会很棒,谢谢

var node = svg.selectAll("g.node")
.data(json.nodes)
.enter().append("g")
.attr("r", 12)
.attr("class", "node")
.attr("class", "gLink")
.call(node_drag)
.on('contextmenu', function(d,i) {
       d3.selectAll('.context-menu').data([1])
        .enter()
        .append('div')
        .attr('class', 'context-menu');
      // close menu
      d3.select('body').on('click.context-menu', function() {
        d3.select('.context-menu').style('display', 'none');
      });
      // this gets executed when a contextmenu event occurs
      d3.selectAll('.context-menu')
        .html('')
        .append('ul')
        .selectAll('li')
          .data(actions).enter()
          .append('li')

      .on('click' , function(d) { 

            if (d=="Force Succeed"){ 
                 alert(d);
                 d3.select(".node").style("fill", "#000");
             }
           else  if (d=="Start Node"){ 
         alert(d);
                 d3.select(this).style("fill", "#000000");
             }
    else  if (d=="Start Tree"){ 
                 alert(d);
                 d3.select(this).style("fill", "#000");
             }
    else   { 
                 alert(d);
                 d3.select(this).style("fill", "#000");
             }
           })
          .text(function(d) { return d; });
      d3.select('.context-menu').style('display', 'none');
      // show the context menu
      d3.select('.context-menu')
        .style('left', (d3.event.pageX - 2) + 'px')
        .style('top', (d3.event.pageY - 2) + 'px')
        .style('display', 'block');
      d3.event.preventDefault();
  });



node.append("svg:rect")
   .attr("x", function(d) { return -1 * (d.name.length * 10) / 2 })
   .attr("y", -15)
   .attr("rx", 5)
   .attr("ry", 5)
   .attr("width", function(d) { return d.name.length * 10; })
   .attr("height", 20)
   .style("fill", "#FFF")
   .style("stroke", "#6666FF");

1 个答案:

答案 0 :(得分:0)

只需保留对右键单击上下文菜单的对象的引用:

.on('contextmenu', function(d, i) {

  var self = d3.select(this); //<-- keep this reference

  d3.selectAll('.context-menu').data([1])
   .enter()

  ...

    .on('click', function(d) {
      if (d == "Force Succeed") {
        self.style("fill", "green"); //<-- use it later

  ...

这是一个功能示例,从您的代码段中推断出来:

&#13;
&#13;
<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>

<body>
  <script>
    var svg = d3.select('body')
      .append('svg')
      .attr('width', 500)
      .attr('height', 500);

    var json = {};
    json.nodes = [
      0, 1, 2, 3
    ];
    
    var actions = ["Force Succeed", "Start Node", "Start Tree"];

    var node = svg.selectAll("g.node")
      .data(json.nodes)
      .enter().append("circle")
      .attr("r", 12)
      .attr("cx", function(d){
        return d * 30 + 15;
      })
      .attr("cy", 15)
      .on('contextmenu', function(d, i) {
        
        var self = d3.select(this);
        
        d3.selectAll('.context-menu').data([1])
          .enter()
          .append('div')
          .attr('class', 'context-menu');
        // close menu
        d3.select('body').on('click.context-menu', function() {
          d3.select('.context-menu').style('display', 'none');
        });
        // this gets executed when a contextmenu event occurs
        d3.selectAll('.context-menu')
          .html('')
          .append('ul')
          .selectAll('li')
          .data(actions).enter()
          .append('li')

        .on('click', function(d) {
            if (d == "Force Succeed") {
              self.style("fill", "green");
            } else if (d == "Start Node") {
              self.style("fill", "red");
            } else if (d == "Start Tree") {
              self.style("fill", "blue");
            } else {
              self.style("fill", "#000");
            }
          })
          .text(function(d) {
            return d;
          });
        d3.select('.context-menu').style('display', 'none');
        // show the context menu
        d3.select('.context-menu')
          .style('left', (d3.event.pageX - 2) + 'px')
          .style('top', (d3.event.pageY - 2) + 'px')
          .style('display', 'block')
          .style('position', 'absolute');
        d3.event.preventDefault();
      });

    node.append("svg:rect")
      .attr("x", function(d) {
        return -1 * (3 * 10) / 2
      })
      .attr("y", -15)
      .attr("rx", 5)
      .attr("ry", 5)
      .attr("width", function(d) {
        return 3 * 10;
      })
      .attr("height", 20)
      .style("fill", "#FFF")
      .style("stroke", "#6666FF");
  </script>
</body>

</html>
&#13;
&#13;
&#13;