Выделите все подключенные пути от начала до конца диаграммы Санки с помощью networkD3 - PullRequest
0 голосов
/ 19 декабря 2018

Я хотел бы создать диаграмму Санки, используя пакет networkD3 в R, который имеет функциональность, описанную в этом вопросе, и функцию "highlight_node_links" в ответе:

d3 Sankey -Выделите все подключенные пути от начала до конца

Я новичок как с R, так и с Javascript, и моя проблема в том, что я не могу заставить вышеупомянутую функцию javascript работать с моим кодом R.Я проверил Подсветите все связанные пути от начала до конца на графике Санки, используя вопрос R , но, к сожалению, я не смог решить его, основываясь на ответе там.Я понимаю, что мне нужно использовать htmlwidgets::onRender, но не могу понять, как.

Небольшой пример данных и сеть, сгенерированная из него:

links = data.frame(source = c("me",  "you", "she", "p1",  "p1",  "p2",  "p2"), target = c("p1",  "p2",  "p1",  "p2",  "b1",  "b1",  "b2"), weight = c(20, 10, 30, 40, 60, 50, 50)) 
nodes <- data.frame(name = c(links$source, links$target) %>% unique()) 
links$IDsource = match(links$source, nodes$name)-1 
links$IDtarget = match(links$target, nodes$name)-1

sn <- sankeyNetwork(Links = links, 
                      Nodes = nodes,
                      Source = "IDsource", 
                      Target = "IDtarget",
                      Value = "weight",  
                      NodeID = "name",  
                      sinksRight = TRUE)

И способ, которым я пытался включитьфункция highlight_node_links (которую я определил ранее без изменений по ссылке выше):

    htmlwidgets::onRender(
  sn,
  '
        function(el, x) {
          var link = d3.selectAll(".link");
         var node = d3.selectAll(".node");
        node.on("mousedown.drag", null);
        node.on("click",highlight_node_links);

  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)
         }}'
)

1 Ответ

0 голосов
/ 19 декабря 2018

Когда я запускаю ваш код, я получаю предупреждающее сообщение ...

Warning message:
It looks like Source/Target is not zero-indexed. This is required in JavaScript
 and so your plot may not render.

, которое сообщает вам, в чем причина проблемы ... ваши фреймы данных links и nodesнеправильно создан.

Вы можете легко решить эту проблему, добавив stringsAsFactors = FALSE в качестве параметра к команде data.frame, которую вы используете для создания фрейма данных links.

Рабочий пример...

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

links = data.frame(
  source = c("me",  "you", "she", "p1",  "p1",  "p2",  "p2"),
  target = c("p1",  "p2",  "p1",  "p2",  "b1",  "b1",  "b2"),
  weight = c(20, 10, 30, 40, 60, 50, 50),
  stringsAsFactors = FALSE
)
nodes <-
  data.frame(name = c(links$source, links$target) %>% unique())
links$IDsource = match(links$source, nodes$name) - 1
links$IDtarget = match(links$target, nodes$name) - 1

sn <- sankeyNetwork(
  Links = links,
  Nodes = nodes,
  Source = "IDsource",
  Target = "IDtarget",
  Value = "weight",
  NodeID = "name",
  sinksRight = TRUE
)

htmlwidgets::onRender(
  sn,
  '
        function(el, x) {
          var link = d3.selectAll(".link");
         var node = d3.selectAll(".node");
        node.on("mousedown.drag", null);
        node.on("click",highlight_node_links)}'
)

enter image description here

...