You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保Highcharter桑基图Post节点按1-7顺序排列?

解决highcharter桑基图Post节点顺序混乱问题

问题

使用highcharter绘制Pre→Post的桑基图时,右侧Post节点的数字顺序偶尔会被打乱,期望Post节点严格按1到7的顺序排列,当前实现代码如下:

library(highcharter)
library(dplyr)
 
# prepare data
dat <- prae_post_aktuell %>%
    select(q39_lq, post_q39_lq) %>%
     filter(!is.na(q39_lq), !is.na(post_q39_lq)) %>%
    mutate(
         q39_lq = factor(as.character(q39_lq), levels = as.character(1:7), ordered = TRUE),
         post_q39_lq = factor(as.character(post_q39_lq), levels = as.character(1:7), ordered = TRUE),
         from = paste0("Pre: ", q39_lq),
        to   = paste0("Post: ", post_q39_lq)
     ) %>%
     count(from, to, name = "weight")
 
 # define color map
 color_map <- c(
    "1" = "#d73027",
     "2" = "#f46d43",
     "3" = "#fdae61",
     "4" = "#888800",
     "5" = "#a6d96a",
     "6" = "#66bd63",
     "7" = "#1a9850"
 )
 
 # define all possible pre- / post-nodes in the right order 
 pre_nodes  <- paste0("Pre: ", 1:7)
 post_nodes <- paste0("Post: ", 1:7)
 node_order <- c(pre_nodes, post_nodes)  # Reihenfolge explizit!

# Order Sankey-data based on from / to
dat <- dat %>%
     mutate(
         from = factor(from, levels = pre_nodes, ordered = TRUE),
         to   = factor(to,   levels = post_nodes, ordered = TRUE)
    ) %>%
     arrange(from, to)

 # create nodes in defined order
nodes <- node_order |>
     lapply(function(x) {
         num <- gsub("[^0-9]", "", x)
        list(
             id = unname(x),
             color = unname(color_map[num]),
             name = unname(x)
         )
     })

 # create sankey diagram
 highchart() %>%
    hc_add_series(
        data = dat,
        type = "sankey",
        hcaes(from = from, to = to, weight = weight),
         nodes = nodes,
         name = "Sorge vor Anfällen (Pre → Post)"
     ) %>%
    hc_plotOptions(
         sankey = list(
             nodeWidth = 20,
             nodePadding = 15,
             curveFactor = 0.4,
             linkOpacity = 0.4
         ),
         series = list(dataLabels = list(style = list(fontSize = "12px")))
    ) %>%
     hc_title(text = "Veränderung der Lebensqualitäts Skala (Pre → Post)") %>%
     hc_tooltip(pointFormat = "Von <b>{point.from}</b> nach <b>{point.to}</b>: {point.weight}") %>%
     hc_chart(height = 600)

解决方法

Highcharts默认会根据节点间的流量自动调整节点顺序,要强制固定Post节点的顺序,只需在sankey的绘图选项中添加nodePositionBy: 'category',让图表严格遵循我们定义的nodes列表顺序排列。

修改后的完整代码:

library(highcharter)
library(dplyr)
 
# prepare data
dat <- prae_post_aktuell %>%
    select(q39_lq, post_q39_lq) %>%
     filter(!is.na(q39_lq), !is.na(post_q39_lq)) %>%
    mutate(
         q39_lq = factor(as.character(q39_lq), levels = as.character(1:7), ordered = TRUE),
         post_q39_lq = factor(as.character(post_q39_lq), levels = as.character(1:7), ordered = TRUE),
         from = paste0("Pre: ", q39_lq),
        to   = paste0("Post: ", post_q39_lq)
     ) %>%
     count(from, to, name = "weight")
 
 # define color map
 color_map <- c(
    "1" = "#d73027",
     "2" = "#f46d43",
     "3" = "#fdae61",
     "4" = "#888800",
     "5" = "#a6d96a",
     "6" = "#66bd63",
     "7" = "#1a9850"
 )
 
 # define all possible pre- / post-nodes in the right order 
 pre_nodes  <- paste0("Pre: ", 1:7)
 post_nodes <- paste0("Post: ", 1:7)
 node_order <- c(pre_nodes, post_nodes)  # 明确节点顺序

# Order Sankey-data based on from / to
dat <- dat %>%
     mutate(
         from = factor(from, levels = pre_nodes, ordered = TRUE),
         to   = factor(to,   levels = post_nodes, ordered = TRUE)
    ) %>%
     arrange(from, to)

 # create nodes in defined order
nodes <- node_order |>
     lapply(function(x) {
         num <- gsub("[^0-9]", "", x)
        list(
             id = unname(x),
             color = unname(color_map[num]),
             name = unname(x)
         )
     })

 # create sankey diagram
 highchart() %>%
    hc_add_series(
        data = dat,
        type = "sankey",
        hcaes(from = from, to = to, weight = weight),
         nodes = nodes,
         name = "Sorge vor Anfällen (Pre → Post)"
     ) %>%
    hc_plotOptions(
         sankey = list(
             nodeWidth = 20,
             nodePadding = 15,
             curveFactor = 0.4,
             linkOpacity = 0.4,
             nodePositionBy = "category"  # 关键:强制按定义的节点顺序排列
         ),
         series = list(dataLabels = list(style = list(fontSize = "12px")))
    ) %>%
     hc_title(text = "Veränderung der Lebensqualitäts Skala (Pre → Post)") %>%
     hc_tooltip(pointFormat = "Von <b>{point.from}</b> nach <b>{point.to}</b>: {point.weight}") %>%
     hc_chart(height = 600)

说明

  • nodePositionBy: "category" 会让桑基图的节点严格按照nodes列表的顺序排列,而非根据流量自动调整。
  • 你的代码已经正确定义了node_order(先Pre1-7,再Post1-7),添加该配置后就能保证Post节点按1到7的顺序显示。

内容的提问来源于stack exchange,提问作者NinjaNuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 01:40:58