Как я могу выделить выбранный узел в графе, направленном силой, в D3

#d3.js

Вопрос:

Я определил размер и цвет кругов, прикрепленных к узлам, на основе расчетного значения, но хотел бы изменить цвет выбранного узла при нажатии. В настоящее время он закрепит узел, но я не могу понять, как изменить цвет. Я также хотел бы щелкнуть закрепленный узел, чтобы отцепить его, но, похоже, не могу понять, куда звонить .on(«нажмите», нажмите). Вот текущий сценарий:

 <!DOCTYPE html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>

path.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}

circle {
  fill: #ccc;
  stroke: #fff;
  stroke: black;
  stroke-width: 1.5px;
}

text {
  fill: #000;
  font: 10px sans-serif;
  pointer-events: none;
}

node.fixed {
  fill: rgb(0, 255, 0);
}

</style>



<head>
<title></title></head>
<body>

<script>

d3.dsv(",", "board_games.csv", function(d) {
  return {
    source: d.source,
    target: d.target,
    value:  d.value
  }
}).then(function(data) {

  var links = data;

  var nodes = {};

  // compute the distinct nodes from the links.
  links.forEach(function(link) {
      link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
      link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
  });

  var width = 1200,
      height = 700;

  var force = d3.forceSimulation()
      .nodes(d3.values(nodes))
      .force("link", d3.forceLink(links).distance(100))
      .force('center', d3.forceCenter(width / 2, height / 2))
      .force("x", d3.forceX())
      .force("y", d3.forceY())
      .force("charge", d3.forceManyBody().strength(-250))
      .alphaTarget(1)
      .on("tick", tick);

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

//Add GT user name
svg.append("text").attr("id", "credit")
    .attr("text-anchor", "end")
    .attr("x", width/2   200)
    .attr("y", height/2 - 300)
    .style("font-size", "10px")
    .text("flarson3");

  // add the links
  var path = svg.append("g")
      .selectAll("path")
      .data(links)
      .enter()
      .append("path")
      .attr("class", function(d) { return "link "   d.type; })
      .style("stroke", function(d) {
      if(d.value == 1) {return "green";
      } 
      else {return "grey";}})
      .style("stroke-dasharray", function(d) {
      if(d.value == 1) {return ("5, 5");
      } 
      else {return;}});

      

  // define the nodes
  var node = svg.selectAll(".node")
      .data(force.nodes())
      .enter().append("g")
      .attr("class", "node")
      .on("dblclick", click)
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

  // add the nodes
// Add degree 
d3.selectAll('g.node')
  .each(function(d) {
    d.degree = 0;
  });

// Calculate degree
links.forEach(function(d){
    d.source.degree  = 1;
    d.target.degree  = 1;
  });

// Accessor functions to get min amp; max
var minDegree = d3.min(
  d3.values(nodes), function(d) {
    return d.degree; })

var maxDegree = d3.max(
  d3.values(nodes), function(d) { 
    return d.degree; })

// Create node scale based on degree
var colorscale = d3.scaleLinear()
  .domain([minDegree, maxDegree])
  .range([50, 255]);



var nodescale = d3.scaleSqrt()
  .domain( [minDegree, maxDegree] )
  .range( [5, 35] ); // Change this to your desired range



  node.append("circle")
      .attr("id", function(d){
         return (d.name.replace(/s /g,'').toLowerCase())})
      .attr("r", function(d) {
      return nodescale(d.degree);
      })
      .style("fill", function(d) {
      if(d.fixed == true) {return "rgb(0, 255, 0)";}
      else {return "rgb("   colorscale(d.degree)   ", 0, 0)";}})
      
  node.append("text")
      .attr("dx", 6)
      .attr("dy", 1)
      .style("font-weight", 700)
      .text(function(d) {
        return (d.name.replace(/s /g,''));
        });

  // 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 click(event, d) {
    delete d.fx;
    delete d.fy;
    d3.select(this).classed("fixed", false);
    force.alpha(1).restart();
  }



  function dragstarted(d) {
      d3.select(this).classed("fixed", d.fixed = true);
      d3.select(this).select(".circle") 
      .style("fill", "green");  
      if (!d3.event.active) force.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
  };

  function dragged(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
  };

  function dragended(d) {
      if (!d3.event.active) force.alphaTarget(0);
      if (d.fixed == true) {
          d.fx = d.x;
          d.fy = d.y;
      }
      else {
          d.fx = null;
          d.fy = null;
      }
  };
  
}).catch(function(error) {
  console.log(error);
});



</script>
</body>
</html>