嗨,我正在尝试使用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);
}
'
)