【问题标题】:Pushing left labels to the left of the nodes in Sankey diagram将左标签推到桑基图中节点的左侧
【发布时间】:2020-04-12 13:39:11
【问题描述】:

这是“定义”部分中提供的 Sankey 图的代码(您也可以单击图表最右侧的 CODE 按钮。

https://www.data-to-viz.com/graph/sankey.html

我们如何让非洲、欧洲、北美等左侧的国家移动到其节点的左侧,就像非洲、欧洲、拉丁美洲等右侧的国家在其节点右侧一样?谢谢。

# Libraries
library(tidyverse)
library(viridis)
library(patchwork)
library(hrbrthemes)
library(circlize)

# Load dataset from github
data <- read.table("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/13_AdjacencyDirectedWeighted.csv", header=TRUE)
# Package
library(networkD3)

# I need a long format
data_long <- data %>%
  rownames_to_column %>%
  gather(key = 'key', value = 'value', -rowname) %>%
  filter(value > 0)
colnames(data_long) <- c("source", "target", "value")
data_long$target <- paste(data_long$target, " ", sep="")

# From these flows we need to create a node data frame: it lists every entities involved in the flow
nodes <- data.frame(name=c(as.character(data_long$source), as.character(data_long$target)) %>% unique())

# With networkD3, connection must be provided using id, not using real name like in the links dataframe.. So we need to reformat it.
data_long$IDsource=match(data_long$source, nodes$name)-1 
data_long$IDtarget=match(data_long$target, nodes$name)-1

# prepare colour scale
ColourScal ='d3.scaleOrdinal() .range(["#FDE725FF","#B4DE2CFF","#6DCD59FF","#35B779FF","#1F9E89FF","#26828EFF","#31688EFF","#3E4A89FF","#482878FF","#440154FF"])'

# Make the Network
sankeyNetwork(Links = data_long, Nodes = nodes,
                     Source = "IDsource", Target = "IDtarget",
                     Value = "value", NodeID = "name", 
                     sinksRight=FALSE, colourScale=ColourScal, nodeWidth=40, fontSize=13, nodePadding=20)


【问题讨论】:

标签: javascript r d3.js htmlwidgets networkd3


【解决方案1】:

您必须有某种方法来识别左侧的那些节点与那些不在左侧的节点(即识别要应用特殊格式的节点的方法)。您可以将此信息添加到您的节点数据框中,然后记住在运行sankeyNetwork 后将其添加回htmlwdigets 对象,因为只保留必要的列。然后,您可以使用htmlwidgets::onRender 注入一些自定义 JavaScript,以仅对那些文本节点应用特殊样式。

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

url <- 'https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/13_AdjacencyDirectedWeighted.csv'
data <- read.table(url, header = TRUE)

data_long <- 
  data %>% 
  rownames_to_column('source') %>% 
  as_tibble() %>% 
  pivot_longer(-source, 'target') %>% 
  filter(value > 0) %>% 
  mutate(target = gsub('\\.', ' ', target)) %>% 
  mutate(source = paste0('src_', source)) %>% 
  mutate(target = paste0('trgt_', target))

nodes <- data.frame(name = unique(c(data_long$source, data_long$target)), stringsAsFactors = FALSE)
nodes <- tibble(name = unique(c(data_long$source, data_long$target)),
                target = grepl('trgt_', name))

data_long$IDsource <- match(data_long$source, nodes$name) - 1 
data_long$IDtarget <- match(data_long$target, nodes$name) - 1

nodes$name <- sub('^.*_', '', nodes$name)

ColourScal ='d3.scaleOrdinal() .range(["#FDE725FF","#B4DE2CFF","#6DCD59FF","#35B779FF","#1F9E89FF","#26828EFF","#31688EFF","#3E4A89FF","#482878FF","#440154FF"])'

sn <- sankeyNetwork(Links = data_long, Nodes = nodes,
                    Source = "IDsource", Target = "IDtarget",
                    Value = "value", NodeID = "name", 
                    sinksRight=FALSE, colourScale=ColourScal, nodeWidth=40, fontSize=13, nodePadding=20)

sn$x$nodes$target <- nodes$target

sn <- onRender(sn,
  '
  function(el) {
    d3.select(el)
      .selectAll(".node text")
      .filter(d => d.target)
      .attr("x", -6)
      .attr("text-anchor", "end");
  }
  '
)

sn

【讨论】:

  • 好的,谢谢!这就是我想出的——我们需要更改标签并将其用于 d3 脚本,例如 onRender 中的 filter 和 startsWith。
猜你喜欢
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 2019-10-21
  • 2021-06-20
  • 2013-07-18
  • 2021-11-29
  • 1970-01-01
相关资源
最近更新 更多