首页 > 解决方案 > 如何更改 d3JS 强制有向图中所有突出显示的节点的颜色?

问题描述

现有功能:

当鼠标悬停在任何节点上时,所有连接的节点都将突出显示。

预期输出:

当鼠标悬停在任何节点上时,所有连接的节点都被突出显示但是突出显示的节点应该是相同的颜色,并且在鼠标移出时返回到以前的状态。

我正在尝试实现此功能,但它没有按预期工作。

请在此处参考工作代码片段: jsfiddle

function selectNode(selectedNode) {
  var neighbors = getNeighbors(selectedNode)

  nodeElements.transition().duration(500)
  .attr('r', function(node) {
        return getNodeRadius(node,neighbors);
   })

    .attr('fill', function(node) {
        return getNodeColor(node,neighbors);
   })


   textElements.transition().duration(500).style('font-size', function(node) {
    return getTextColor(node, neighbors)
  })


  linkElements.transition().duration(500).style('stroke', function(link) {
    return getLinkColor(selectedNode, link)
  })
}

function getNodeColor(node, neighbors) {
  // If is neighbor
  if (Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1) {
    return 'rgba(123, 239, 178, 1)'
       .attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })
    // return node.level === 1 ? '#9C4A9C' : 'rgba(251, 130, 30, 1)'
  }  else {
      return color(node.id);
  }
  //return node.level === 0 ? '#91007B' : '#D8ABD8'
}



 var nodeElements =  g.append("g")
  .attr("class", "nodes")
  .selectAll("circle")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("r", 60)

  .attr("stroke", "#fff")
  .attr('stroke-width', 21)
  .attr("id", function(d) { return d.id })
   //.attr("fill", function(d) {return color(d.id)}) 
     .attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })
     .on('contextmenu', function(d){ 
        d3.event.preventDefault();
        menu(d3.mouse(svg.node())[0], d3.mouse(svg.node())[1]);
    })
      .on('mouseover', selectNode)
      .on('mouseout', releaseNode)
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

标签: javascriptd3.jsd3-force-directed

解决方案


您需要在五个地方更改代码。

第一个和第二个是selectNode看评论

function selectNode(selectedNode) {
    var neighbors = getNeighbors(selectedNode)

    nodeElements.transition().duration(500)
    .attr('r', function(node) {
        return getNodeRadius(node,neighbors);
    });
    // do not use transition here, it kinda ruins the flavour  
    // or see if you like it with transitions, your call  
    nodeElements.attr('fill', function(node) {
        // send selectedNode to your getNodeColor
        return getNodeColor(node,neighbors,selectedNode);
    })
}

您可能已经猜到的第三和第四个将是getNodeColor

function getNodeColor(node, neighbors, selectedNode) {
    if (Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1) {
        return 'url(#grad' + selectedNode.index + ')'
    }  else {
        // use gradient here
        return 'url(#grad' + node.index + ')'
    }
}

最后一个将是你的releaseNode

function releaseNode() {
    nodeElements.transition().duration(500)
        .attr('r', 60);

    // don't use transitions here
    // or see if you like it with transitions, your call  
    nodeElements.attr('fill', function(d, i) { return 'url(#grad' + i + ')'; })

    linkElements.transition().duration(500).style('stroke', 'grey');
}

是一个可供您尝试的工作小提琴


推荐阅读