使用R:networkD3:sankeyNetwork突出显示所有方向的整个路径

时间:2019-01-16 15:33:42

标签: javascript r htmlwidgets networkd3

嗨,我正在尝试使用NetworkD3在R中创建Sankey Daigram,并在我将鼠标悬停在特定节点上时使用htmlwidgets使用一些javascript突出显示路径(该节点可以位于开头,中间或结尾)。换句话说,如果节点位于中间,那么我想用两种方式(右和左)突出显示相应的路径。如果节点在末端,则我要突出显示从末端到起点的相应路径。对于Sankey图开头的节点也是如此。请查看下面的链接以获得更好的主意。

源:https://setsna2.shinyapps.io/sankey-shinyforallcities/

我使用了CJ Yetman在堆栈溢出时发现的R代码。该代码仅在图的开头突出显示了节点的路径

library(dplyr)
library(tidyr)
library(networkD3)
library(htmlwidgets)

df <- read.csv(header = T, as.is = T, text = '
               name,origin,layover,destination
               Bob,Baltimore,Chicago,Los Angeles
               Bob,Baltimore,Chicago,Seattle
               Bob,New York,St Louis,Austin
               Bob,New York,Chicago,Seattle
               Tom,Baltimore,Chicago,Los Angeles
               Tom,New York,St Louis,San Diego
               Tom,New York,Chicago,Seattle
               Tom,New York,New Orleans,Austin
               ')

links <-
  df %>%
  mutate(row = row_number()) %>%
  mutate(traveler = .[[1]]) %>%
  gather("column", "source", -row, -traveler) %>%
  mutate(column = match(column, names(df))) %>%
  arrange(row, column) %>%
  group_by(row) %>%
  mutate(target = lead(source)) %>%
  ungroup() %>%
  filter(!is.na(target)) %>%
  select(source, target, traveler) %>%
  group_by(source, target, traveler) %>%
  summarise(count = n()) %>%
  ungroup()

nodes <- data.frame(name = unique(c(links$source, links$target)))
links$source <- match(links$source, nodes$name) - 1
links$target <- match(links$target, nodes$name) - 1

sn <- sankeyNetwork(Links = links, Nodes = nodes, Source = 'source',
                    Target = 'target', Value = 'count', NodeID = 'name',
                    )

# add origin back into the links data because sankeyNetwork strips it out
sn$x$links$traveler <- links$traveler

# add onRender JavaScript to set the click behavior
htmlwidgets::onRender(
  sn,
  '
  function(el, x) {
  var nodes = d3.selectAll(".node");
  var links = d3.selectAll(".link");
  nodes.select("rect").style("cursor", "pointer");
  nodes.on("mousedown.drag", null); // remove the drag because it conflicts
  //nodes.on("mouseout", null);
  nodes.on("click", clicked);
  function clicked(d, i) {
  links
  .style("stroke-opacity", function(d1) {
  return d1.traveler == d.name ? 0.5 : 0.2;
  });
  }
  }
  '
)

非常感谢您的帮助:)

我所做的更改是用

替换javascript部分
htmlwidgets::onRender(
  sn,
  '
  function highlight_node_links(node,i){

  var remainingNodes=[],
  nextNodes=[];

  var stroke_opacity = 0;
  if( d3.select(this).attr("data-clicked") == "1" ){
  d3.select(this).attr("data-clicked","0");
  stroke_opacity = 0.2;
  }else{
  d3.select(this).attr("data-clicked","1");
  stroke_opacity = 0.5;
  }

  var traverse = [{
  linkType : "sourceLinks",
  nodeType : "target"
  },{
  linkType : "targetLinks",
  nodeType : "source"
  }];

  traverse.forEach(function(step){
  node[step.linkType].forEach(function(link) {
  remainingNodes.push(link[step.nodeType]);
  highlight_link(link.id, stroke_opacity);
  });

  while (remainingNodes.length) {
  nextNodes = [];
  remainingNodes.forEach(function(node) {
  node[step.linkType].forEach(function(link) {
  nextNodes.push(link[step.nodeType]);
  highlight_link(link.id, stroke_opacity);
  });
  });
  remainingNodes = nextNodes;
  }
  });
  }

  function highlight_link(id,opacity){
  d3.select("#link-"+id).style("stroke-opacity", opacity);
  }
  '
)

0 个答案:

没有答案