如何在D3js强制有向图中为节点实现突出显示和过渡效果?

维维克

我正在尝试在D3 js强制有向图中的节点上实现Higlight效果。

这样做时,我面临以下问题。

突出显示效果:在选定节点的鼠标悬停时,我正在更改其相邻节点的颜色。但是其他节点的颜色不应该改变(在我的情况下,它变成红色并且不确定如何修复)。b。在选定节点的鼠标悬停时,我想通过增加其半径来为所有互连的节点添加过渡效果。其他节点也应该淡出,这可能吗?

请参考有效的js小提琴以供参考:在此处输入链接描述

var nodeElements =  g.append("g")
  .attr("class", "nodes")
  .selectAll("circle")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("r", 40)
.attr("fill", function(d) { return color(d.id); })
  .attr("stroke", "#fff")
  .attr('stroke-width', 21)
  .attr("id", function(d) { return d.id })
      .on('mouseover', selectNode)
      .on('mouseout', releaseNode)
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

function releaseNode() {
   nodeElements.attr("fill", function(d) { return color(d.id)
   })
}

function selectNode(selectedNode) {
  var neighbors = getNeighbors(selectedNode)
  nodeElements.attr('fill', function(node) {
    return getNodeColor(node, neighbors)
  })
}

function getNeighbors(node) {
  return graph.links.reduce(function(neighbors, link) {
    if (link.target.id === node.id) {
      neighbors.push(link.source.id)
    } else if (link.source.id === node.id) {
      neighbors.push(link.target.id)
    }
    return neighbors
  }, [node.id])
}

function getNodeColor(node, neighbors) {
  // If is neighbor
  if (Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1) {
    return 'rgba(251, 130, 30, 1)'
    // return node.level === 1 ? '#9C4A9C' : 'rgba(251, 130, 30, 1)'
  } else {
    return 'red';
  }
  //return node.level === 0 ? '#91007B' : '#D8ABD8'
}
  1. 若要在鼠标悬停时不更改其他节点的颜色,则必须更改以下getNodeColor功能:

    function getNodeColor(node, neighbors) {
      // If is neighbor
      if ( neighbors.indexOf(node.id) > -1) {
        return 'rgba(251, 130, 30, 1)'
      } 
      else {
            return color(node.id);
      }
    }
    
  2. 为了扩大节点上,您将不得不调用另一个函数getNodeRadiusselectNode函数被调用on('mouseover', selectNode);

    function selectNode(selectedNode) {
      var neighbors = getNeighbors(selectedNode)
      nodeElements.transition()
            .duration(500)
            .attr('fill', function(node) {
                return getNodeColor(node, neighbors)
              })
            .attr('r', function(node) {
              return getNodeRadius(node,neighbors);
            })
    }
    

请注意,方法.transition().duration(500)指示以500毫秒的持续时间对此最终状态进行动画处理。

getNodeRadius功能需要定义为:

function getNodeRadius(node, neighbors) {
  // If is neighbor
  if ( neighbors.indexOf(node.id) > -1) {
    return '60'
  } 
  else {
        return '40'
  }
}

完整的示例如下:

var graph = {
'nodes':[
{'id':'Material_Definition','group':0},
{'id':'Lot1','group':1},
{'id':'Lot2','group':1},
{'id':'Lot3','group':1},
{'id':'Lot4','group':1},
{'id':'Lot5','group':1},
{'id':'Lot6','group':1},
{'id':'Lot7','group':1},
{'id':'Lot8','group':1},
{'id':'Lot9','group':1},
{'id':'Lot10','group':1},
{'id':'Lot11','group':1},
{'id':'Lot12','group':1},
{'id':'Lot13','group':1},
{'id':'Lot14','group':1},
{'id':'Lot15','group':1},
{'id':'Lot16','group':1},
{'id':'Lot17','group':1},
{'id':'Lot18','group':1},
{'id':'Lot19','group':1},
{'id':'Lot20','group':1},
{'id':'SubLot1_Lot1','group':2},
{'id':'SubLot2_Lot1','group':2},
{'id':'SubLot3_Lot1','group':2},
{'id':'SubLot4_Lot1','group':2},
{'id':'SubLot5_Lot1','group':2},
{'id':'SubLot6_Lot1','group':2},
{'id':'SubLot1_Lot2','group':2},
{'id':'SubLot2_Lot2','group':2},
{'id':'SubLot3_Lot2','group':2},
{'id':'SubLot4_Lot2','group':2},
{'id':'SubLot5_Lot2','group':2},
{'id':'SubLot6_Lot2','group':2}],
'links':[
/* Material Definition linked to Lots */
{'source':'Material_Definition','target':'Lot1','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot2','value':8,'type':'A'},
{'source':'Material_Definition','target':'Lot3','value':10,'type':'A'},
{'source':'Material_Definition','target':'Lot3','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot4','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot5','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot6','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot7','value':2,'type':'A'},
{'source':'Material_Definition','target':'Lot8','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot9','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot10','value':8,'type':'A'},
{'source':'Material_Definition','target':'Lot11','value':10,'type':'A'},
{'source':'Material_Definition','target':'Lot12','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot13','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot14','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot15','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot16','value':2,'type':'A'},
{'source':'Material_Definition','target':'Lot17','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot18','value':1,'type':'A'},
{'source':'Material_Definition','target':'Lot19','value':2,'type':'A'},
{'source':'Material_Definition','target':'Lot20','value':1,'type':'A'},

/* Lot1 is linked to Sublots */
{'source':'Lot1','target':'SubLot1_Lot1','value':2,'type':'A'},
{'source':'Lot1','target':'SubLot2_Lot1','value':1,'type':'A'},
{'source':'Lot1','target':'SubLot3_Lot1','value':2,'type':'A'},
{'source':'Lot1','target':'SubLot4_Lot1','value':1,'type':'A'},
{'source':'Lot1','target':'SubLot5_Lot1','value':2,'type':'A'},
{'source':'Lot1','target':'SubLot6_Lot1','value':1,'type':'A'},

/* Lot2 is linked to Sublots */
{'source':'Lot2','target':'SubLot1_Lot2','value':2,'type':'A'},
{'source':'Lot2','target':'SubLot2_Lot2','value':1,'type':'A'},
{'source':'Lot2','target':'SubLot3_Lot2','value':2,'type':'A'},
{'source':'Lot2','target':'SubLot4_Lot2','value':1,'type':'A'},
{'source':'Lot2','target':'SubLot5_Lot2','value':2,'type':'A'},
{'source':'Lot2','target':'SubLot6_Lot2','value':1,'type':'A'},

/* Interconnected Lots */
{'source':'Lot10','target':'Lot18','value':2,'type':'A'},
{'source':'Lot10','target':'Lot19','value':1,'type':'A'},
{'source':'Lot10','target':'Lot20','value':2,'type':'A'},
{'source':'Lot7','target':'Lot8','value':1,'type':'A'},
{'source':'Lot7','target':'Lot9','value':2,'type':'A'},
{'source':'Lot7','target':'Lot10','value':1,'type':'A'},
{'source':'Lot12','target':'Lot4','value':2,'type':'A'},
{'source':'Lot12','target':'Lot3','value':1,'type':'A'},
{'source':'Lot12','target':'Lot2','value':2,'type':'A'},
{'source':'Lot16','target':'Lot1','value':1,'type':'A'},
{'source':'Lot16','target':'Lot9','value':2,'type':'A'},
{'source':'Lot16','target':'Lot12','value':1,'type':'A'}
]};


var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory10);
var zoom_handler = d3.zoom().on("zoom", zoom_actions);

// zoom_handler(svg);

var simulation = d3.forceSimulation()
  .force("link", d3.forceLink().distance(300).id(function(d) {
    return d.id;
  }))
  .force("charge", d3.forceManyBody().strength(-300))
  .force("center", d3.forceCenter(width / 2, height / 2));

var g = svg.append("g")
  .attr("class", "everything");

svg.call(zoom_handler)
  .call(zoom_handler.transform, d3.zoomIdentity.translate(200, 150).scale(0.2));


var linkElements = g.append("g")
  .attr("class", "links")
  .selectAll("line")
  .data(graph.links)
  .enter().append("line")
  .style("stroke-width",5.5)
  .style("stroke",'black');

var nodeElements =  g.append("g")
  .attr("class", "nodes")
  .selectAll("circle")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("r", 40)
  .attr('class', 'nodecircles')
.attr("fill", function(d) { return color(d.id); })
  .attr("stroke", "#fff")
  .attr('stroke-width', 21)
  .attr("id", function(d) { return d.id })
      .on('mouseover', selectNode)
      .on('mouseout', releaseNode)
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));
    
function releaseNode(d) {
   nodeElements.transition().duration(500)
   .attr("fill", function(d) { return color(d.id)
   })
   .attr('r', 40);
}
  
var textElements = g.append("g")    // use g.append instead of svg.append to enable zoom
  .attr("class", "texts")
  .selectAll("text")
  .data(graph.nodes)
  .enter().append("text")
  .text(function(node) {
    return node.id
  })
  .attr("font-size", 55)
  .attr("font-family", "sans-serif")
  .attr("text-anchor", "middle")
  .attr("fill", "black")
  .attr("style", "font-weight:bold; text-stroke: 1px #fff;")
  .attr("dx", 0)
  .attr("dy", 20)

function ticked() {
  linkElements
    .attr("x1", function(d) { return d.source.x; })
    .attr("y1", function(d) { return d.source.y; })
    .attr("x2", function(d) { return d.target.x; })
    .attr("y2", function(d) { return d.target.y; });
  nodeElements
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .each(d => { d3.select('#t_' + d.id).attr('x', d.x + 10).attr('y', d.y + 3); });
    textElements
    .attr('x', function(d) {
      return d.x
    })
    .attr('y', function(d) {
      return d.y
    });
    
}

simulation
  .nodes(graph.nodes)
  .on("tick", ticked);

simulation.force("link")
  .links(graph.links);


function zoom_actions() {
  g.attr("transform", d3.event.transform)
}

function dragstarted(d) {
  if (!d3.event.active) simulation.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) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}

function selectNode(selectedNode) {
  var neighbors = getNeighbors(selectedNode)
  nodeElements.transition()
    .duration(500)
    .attr('fill', function(node) {
    return getNodeColor(node, neighbors)
  })
    .attr('r', function(node) {
    return getNodeRadius(node,neighbors);
  })
}

function getNeighbors(node) {
  return graph.links.reduce(function(neighbors, link) {
    if (link.target.id === node.id) {
      neighbors.push(link.source.id)
    } else if (link.source.id === node.id) {
      neighbors.push(link.target.id)
    }
    return neighbors
  }, [node.id])
}

function getNodeColor(node, neighbors) {
  // If is neighbor
  if ( neighbors.indexOf(node.id) > -1) {
    return 'rgba(251, 130, 30, 1)'
  } 
  else {
		return color(node.id);
  }
}

function getNodeRadius(node, neighbors) {
  // If is neighbor
  if ( neighbors.indexOf(node.id) > -1) {
    return '60'
  } 
  else {
		return '40'
  }
}
   .links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #000;
  stroke-width: 1.5px;
}

text {
  font-size: 10px;
}
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="shortcut icon" href="//#" />

<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">


</html>

<svg width="798" height="400"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何更改d3JS强制有向图中所有突出显示的节点的颜色?

来自分类Dev

参数化的D3js强制有向图节点定位

来自分类Dev

如何在d3.js强制有向图中检测元素拖动

来自分类Dev

D3js强制布局更新节点和链接

来自分类Dev

d3js强制定向-在悬停到节点上时,高亮显示/着色链接的节点和链接?

来自分类Dev

d3js强制定向-在悬停到节点上时,高亮显示/着色链接的节点和链接?

来自分类Dev

如何在D3.js强制布局图中创建到主节点的附属节点

来自分类Dev

d3js强制大量节点

来自分类Dev

如何在D3强制有向图中选择要使用的JSON文件

来自分类Dev

最初如何在d3 Force有向图中限制节点数

来自分类Dev

d3.js 强制有向图:如何使节点大小取决于链接的值?

来自分类Dev

如何在 D3js 中为不同的图表显示不同的标题?

来自分类Dev

如何在d3中实现这种过渡效果?

来自分类Dev

如何使用d3.js和Angular在力向图中显示边缘?

来自分类Dev

d3js(v4)画布强制布局,节点上带有文本

来自分类Dev

D3js在enter()上强制重复节点

来自分类Dev

d3js使用固定节点创建强制布局

来自分类Dev

D3js在enter()上强制重复节点

来自分类Dev

D3JS缩放和过渡性能

来自分类Dev

在D3.js中的动态强制布局图中显示节点标签

来自分类Dev

如何在 D3js v4 和 Angular 4 中实现 FontAwesome v5 图标

来自分类Dev

D3v4强制有向图-localStorage断开链接和节点的连接

来自分类Dev

如何使用 D3js 在多线图中不显示缺失值

来自分类Dev

如何在D3强制布局中突出显示/选择邻居?

来自分类Dev

将节点动态添加到d3.js强制有向图

来自分类Dev

将节点动态添加到d3.js强制有向图

来自分类Dev

如何使用d3.js在饼图过渡图中显示标签?

来自分类Dev

如何在D3 Sankey图中突出显示整个路径?

来自分类Dev

d3js文本未显示在节点图上

Related 相关文章

  1. 1

    如何更改d3JS强制有向图中所有突出显示的节点的颜色?

  2. 2

    参数化的D3js强制有向图节点定位

  3. 3

    如何在d3.js强制有向图中检测元素拖动

  4. 4

    D3js强制布局更新节点和链接

  5. 5

    d3js强制定向-在悬停到节点上时,高亮显示/着色链接的节点和链接?

  6. 6

    d3js强制定向-在悬停到节点上时,高亮显示/着色链接的节点和链接?

  7. 7

    如何在D3.js强制布局图中创建到主节点的附属节点

  8. 8

    d3js强制大量节点

  9. 9

    如何在D3强制有向图中选择要使用的JSON文件

  10. 10

    最初如何在d3 Force有向图中限制节点数

  11. 11

    d3.js 强制有向图:如何使节点大小取决于链接的值?

  12. 12

    如何在 D3js 中为不同的图表显示不同的标题?

  13. 13

    如何在d3中实现这种过渡效果?

  14. 14

    如何使用d3.js和Angular在力向图中显示边缘?

  15. 15

    d3js(v4)画布强制布局,节点上带有文本

  16. 16

    D3js在enter()上强制重复节点

  17. 17

    d3js使用固定节点创建强制布局

  18. 18

    D3js在enter()上强制重复节点

  19. 19

    D3JS缩放和过渡性能

  20. 20

    在D3.js中的动态强制布局图中显示节点标签

  21. 21

    如何在 D3js v4 和 Angular 4 中实现 FontAwesome v5 图标

  22. 22

    D3v4强制有向图-localStorage断开链接和节点的连接

  23. 23

    如何使用 D3js 在多线图中不显示缺失值

  24. 24

    如何在D3强制布局中突出显示/选择邻居?

  25. 25

    将节点动态添加到d3.js强制有向图

  26. 26

    将节点动态添加到d3.js强制有向图

  27. 27

    如何使用d3.js在饼图过渡图中显示标签?

  28. 28

    如何在D3 Sankey图中突出显示整个路径?

  29. 29

    d3js文本未显示在节点图上

热门标签

归档