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

优化Highcharter桑基图:调整节点标签位置与千位分隔符

Highcharter桑基图外观优化方案

需求说明

需要对Highcharter桑基图做两处外观优化:

  • 将节点标签移至图表左右两侧,而非默认的节点上方(示例中国家名称需放在两侧)
  • 为悬停节点和链接时显示的数值添加千位分隔符“,”

优化实现方案

以下是整合了两项优化的完整代码,关键修改点已在代码中注释说明:

library(tidyverse)
library(highcharter)

df <- tibble(from = c("Brazil", "Brazil", "Poland", "Spain", "Poland"),
             toto = c("Portugal", "Spain", "Portugal", "Brazil", "Poland"),
             assets = c(5324523.4523, 232452345.234, 2345234.52345, 3234523.45234, 63452345.2345))

# 转换数据为桑基图所需格式
transform_to_list <- function(data, from, to, weight, add_spaces = FALSE) {
  df_list <- list()
  for (i in 1:nrow(data)) {
    df_list[[i]] <- list(from = data[[from]][i],
                         to = ifelse(test = add_spaces == TRUE, 
                                     yes = paste0(data[[to]][i], " "), 
                                     no = data[[to]][i]  
                         ),
                         weight = data[[weight]][i]
    )
  }
  return(df_list)
}

df_list_spaces <- transform_to_list(data = df, from = "from", to = "toto", weight = "assets", add_spaces = TRUE)

# 生成节点列表(含颜色)
transform_to_nodes_list <- function(data, from, to, colors) {
  from_col <- unique(data[[from]])
  to_col <- unique(paste0(data[[to]], " "))
  id_col <- c(from_col, to_col)
  helper_col <- gsub("\\s+$", "", id_col) 
  color_col <- colors[as.numeric(factor(helper_col))]
  
  d0 <- tibble(id_col, color_col)
  nodes_list <- list()
  for (i in 1:nrow(d0)) {
    nodes_list[[i]] <- list(id = d0[["id_col"]][i],
                            color = d0[["color_col"]][i])
  }
  return(nodes_list)
}

pal <- c("brown", "blue", "yellow", "green", "orange", "red")
nodes_list <- transform_to_nodes_list(data = df, from = "from", to = "toto", colors = pal)

# 优化后的桑基图绘制代码
highchart() %>%
  hc_add_series(
    type = "sankey",
    data = df_list_spaces,
    nodes = nodes_list,
    links = df_list_spaces,
    name = "assets",
    # 调整节点标签位置:左右两侧对齐
    dataLabels = list(
      enabled = TRUE,
      formatter = JS("function() {
        // 移除标签末尾的冗余空格
        var cleanLabel = this.point.id.replace(/\\s+$/, '');
        // 根据节点横向位置判断对齐方向
        if (this.point.x < 0.5) {
          this.align = 'left';
          this.x += 10; // 增加标签与节点的间距,避免重叠
        } else {
          this.align = 'right';
          this.x -= 10;
        }
        return cleanLabel;
      }"),
      verticalAlign = "middle" # 标签垂直居中
    ),
    # 自定义悬停提示框,添加千位分隔符
    tooltip = list(
      pointFormatter = JS("function() {
        // 格式化数值:保留2位小数,千位分隔符为','
        var formattedNum = Highcharts.numberFormat(this.weight, 2, '.', ',');
        // 区分节点和链接的提示内容
        if (this.from && this.to) {
          return '<b>' + this.from.replace(/\\s+$/, '') + ' → ' + this.to.replace(/\\s+$/, '') + '</b><br/>资产: ' + formattedNum;
        } else {
          return '<b>' + this.id.replace(/\\s+$/, '') + '</b><br/>总流量: ' + formattedNum;
        }
      }")
    )
  ) %>%
  # 调整图表边距,防止两侧标签被截断
  hc_chart(marginLeft = 100, marginRight = 100)

关键优化细节说明

  1. 节点标签位置调整

    • 通过JavaScript格式化函数判断节点的x坐标(范围0-1),左侧节点(x<0.5)左对齐,右侧节点(x≥0.5)右对齐
    • 移除之前为区分节点添加的末尾空格,保证标签显示统一
    • 设置verticalAlign = "middle"让标签垂直居中于节点
  2. 千位分隔符实现

    • 放弃全局highcharter.lang设置,改用桑基图专属的tooltip.pointFormatter自定义提示内容
    • 使用Highcharts内置的numberFormat方法对数值进行格式化,参数依次为:目标数值、保留小数位数、小数分隔符、千位分隔符
    • 分别处理节点和链接的提示文本,确保信息清晰准确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:55:19