以正确的顺序将 x-node 个标题添加到 networkD3 Sankey 图
Add x-node titles to networkD3 Sankey plot in correct order
我正在尝试标记使用 networkD3 创建的 Sankey 图的 x-nodes。
我看到这里发布了一个解决方案:
但是,当我尝试手动设置标签时,它们的显示顺序错误。我将此作为评论发布在该问题中,但被要求创建一个新问题。
这是一个可重现的例子:
library('tidyverse')
library('networkD3')
#create the dataframe
df <- data.frame('location' = c('A', 'B', 'C', 'A', 'A', 'B'),
'office' = c('D', 'E', 'E', 'E', 'F', 'G'),
'strategy' = c('1', '2', '1', '1', '2', '5'),
'tactic' = c('6', '6', '6', '7', '7', '7'),
'target' = c('H', 'H', 'I', 'H', 'H', 'I'),
'outcome' = c('K', 'L', 'L', 'L', 'L', 'L'),
'output' = c('O', 'O', 'P', 'Q', 'Q', 'Q'))
#prepare the data for Sankey using dplyr
#Create the links
links <- df %>%
mutate(row = row_number()) %>%
pivot_longer(-row, names_to = "col", values_to = "source") %>%
mutate(col = match(col, names(df))) %>%
mutate(source = paste0(source, '_', col)) %>%
group_by(row) %>%
mutate(target = lead(source, order_by = col)) %>%
ungroup() %>%
filter(!is.na(target)) %>%
group_by(source, target) %>%
summarise(value = n(), .groups = "drop")
#Create the nodes
nodes <- data.frame(id = unique(c(links$source, links$target)),
stringsAsFactors = F) %>%
mutate(name = sub('_[0-9]*$', '', id))
#Create the source and target ID
links$source_id = match(links$source, nodes$id) - 1
links$target_id = match(links$target, nodes$id) - 1
#Create the plot
plot <- sankeyNetwork(Links = links, Nodes = nodes,
Source = 'source_id', Target = 'target_id', Value = 'value', NodeID = 'name',
fontSize = 14)
#Apply the manual var labels - solution from the linked Whosebug answer
htmlwidgets::onRender(plot, '
function(el) {
var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i);
var labels = ["Location", "Office", "Strategy", "Tactic", "Target", "Outcome", "Output"];
cols_x.forEach((d, i) => {
d3.select(el).select("svg")
.append("text")
.attr("x", d)
.attr("y", 12)
.text(labels[i]);
})
}
')
给出:
在这里你可以看到:
节点 1 ('Strategy') 应该是 'Location'
节点 2 ('Tactic') 应该是 'Office'
节点 3 ('Location') 应该是 'Strategy'
节点 4 ('Office') 应该是 'Tactic'
节点 5 ('Target') 是 'Target'
节点 6 ('Outcome') 是 'Outcome'
节点 7 ('Output') 是 'Output'
不清楚这些是如何排序的。
如何按正确的顺序获取它们?
在JavaScript第一行末尾添加.sort(function(a, b){return a - b})
,如...
var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i).sort(function(a, b){return a - b});
否则列的返回 x 值可能乱序
我正在尝试标记使用 networkD3 创建的 Sankey 图的 x-nodes。
我看到这里发布了一个解决方案:
但是,当我尝试手动设置标签时,它们的显示顺序错误。我将此作为评论发布在该问题中,但被要求创建一个新问题。
这是一个可重现的例子:
library('tidyverse')
library('networkD3')
#create the dataframe
df <- data.frame('location' = c('A', 'B', 'C', 'A', 'A', 'B'),
'office' = c('D', 'E', 'E', 'E', 'F', 'G'),
'strategy' = c('1', '2', '1', '1', '2', '5'),
'tactic' = c('6', '6', '6', '7', '7', '7'),
'target' = c('H', 'H', 'I', 'H', 'H', 'I'),
'outcome' = c('K', 'L', 'L', 'L', 'L', 'L'),
'output' = c('O', 'O', 'P', 'Q', 'Q', 'Q'))
#prepare the data for Sankey using dplyr
#Create the links
links <- df %>%
mutate(row = row_number()) %>%
pivot_longer(-row, names_to = "col", values_to = "source") %>%
mutate(col = match(col, names(df))) %>%
mutate(source = paste0(source, '_', col)) %>%
group_by(row) %>%
mutate(target = lead(source, order_by = col)) %>%
ungroup() %>%
filter(!is.na(target)) %>%
group_by(source, target) %>%
summarise(value = n(), .groups = "drop")
#Create the nodes
nodes <- data.frame(id = unique(c(links$source, links$target)),
stringsAsFactors = F) %>%
mutate(name = sub('_[0-9]*$', '', id))
#Create the source and target ID
links$source_id = match(links$source, nodes$id) - 1
links$target_id = match(links$target, nodes$id) - 1
#Create the plot
plot <- sankeyNetwork(Links = links, Nodes = nodes,
Source = 'source_id', Target = 'target_id', Value = 'value', NodeID = 'name',
fontSize = 14)
#Apply the manual var labels - solution from the linked Whosebug answer
htmlwidgets::onRender(plot, '
function(el) {
var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i);
var labels = ["Location", "Office", "Strategy", "Tactic", "Target", "Outcome", "Output"];
cols_x.forEach((d, i) => {
d3.select(el).select("svg")
.append("text")
.attr("x", d)
.attr("y", 12)
.text(labels[i]);
})
}
')
给出:
在这里你可以看到:
节点 1 ('Strategy') 应该是 'Location'
节点 2 ('Tactic') 应该是 'Office'
节点 3 ('Location') 应该是 'Strategy'
节点 4 ('Office') 应该是 'Tactic'
节点 5 ('Target') 是 'Target'
节点 6 ('Outcome') 是 'Outcome'
节点 7 ('Output') 是 'Output'
不清楚这些是如何排序的。
如何按正确的顺序获取它们?
在JavaScript第一行末尾添加.sort(function(a, b){return a - b})
,如...
var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i).sort(function(a, b){return a - b});
否则列的返回 x 值可能乱序