优化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)
关键优化细节说明
节点标签位置调整
- 通过JavaScript格式化函数判断节点的
x坐标(范围0-1),左侧节点(x<0.5)左对齐,右侧节点(x≥0.5)右对齐 - 移除之前为区分节点添加的末尾空格,保证标签显示统一
- 设置
verticalAlign = "middle"让标签垂直居中于节点
- 通过JavaScript格式化函数判断节点的
千位分隔符实现
- 放弃全局
highcharter.lang设置,改用桑基图专属的tooltip.pointFormatter自定义提示内容 - 使用Highcharts内置的
numberFormat方法对数值进行格式化,参数依次为:目标数值、保留小数位数、小数分隔符、千位分隔符 - 分别处理节点和链接的提示文本,确保信息清晰准确
- 放弃全局
内容的提问来源于stack exchange,提问作者Marie Veit
相关产品推荐
相关产品推荐

