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

如何在基于Google Sheets的Sankey图中添加节点占比?

实现方法:为Sankey图节点添加占总值百分比

核心思路

  1. 计算数值列的总和作为基准值
  2. 统计每个节点(源/目标)的总流量(流经该节点的所有数值之和)
  3. 计算每个节点流量占总值的百分比,拼接至原节点名称后
  4. 将修改后的节点标签传入Sankey图绘制逻辑

代码修改示例

假设你的原有脚本已经能读取Sheet数据并生成基础Sankey图,以下是修改后的关键代码片段:

function drawSankeyWithPercentage() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const rawData = sheet.getDataRange().getValues();
  const headers = rawData.shift(); // 移除表头行(假设表头为["源", "目标", "数值"])

  // 1. 计算数值列的总总值
  const totalValue = rawData.reduce((sum, row) => sum + row[2], 0);
  if (totalValue === 0) {
    SpreadsheetApp.getUi().alert("数值列总和为0,无法计算百分比");
    return;
  }

  // 2. 统计每个节点的总流量(源/目标节点分别累加)
  const nodeTotalFlow = {};
  rawData.forEach(row => {
    const source = row[0];
    const target = row[1];
    const value = row[2];
    
    nodeTotalFlow[source] = (nodeTotalFlow[source] || 0) + value;
    nodeTotalFlow[target] = (nodeTotalFlow[target] || 0) + value;
  });

  // 3. 生成带百分比的节点标签,同时整理Sankey所需的节点、映射关系和链接数据
  const nodes = [];
  const nodeIndexMap = {};
  const links = [];

  rawData.forEach(row => {
    const source = row[0];
    const target = row[1];
    const value = row[2];

    // 处理源节点:若未加入节点列表,生成带百分比的标签并加入
    if (!nodeIndexMap[source]) {
      const percentage = ((nodeTotalFlow[source] / totalValue) * 100).toFixed(2);
      const labeledName = `${source} (${percentage}%)`;
      nodeIndexMap[source] = nodes.length;
      nodes.push({ label: labeledName });
    }

    // 处理目标节点:同上
    if (!nodeIndexMap[target]) {
      const percentage = ((nodeTotalFlow[target] / totalValue) * 100).toFixed(2);
      const labeledName = `${target} (${percentage}%)`;
      nodeIndexMap[target] = nodes.length;
      nodes.push({ label: labeledName });
    }

    // 整理链接数据(与原有逻辑一致)
    links.push({
      source: nodeIndexMap[source],
      target: nodeIndexMap[target],
      value: value
    });
  });

  // 4. 此处插入原有Sankey图绘制逻辑,传入修改后的nodes和links即可
  // 示例(基于Google Charts Sankey):
  google.charts.load('current', {'packages':['sankey']});
  google.charts.setOnLoadCallback(() => {
    const data = new google.visualization.DataTable();
    data.addColumn('string', '源');
    data.addColumn('string', '目标');
    data.addColumn('number', '数值');
    // 将rawData转换为DataTable格式(或使用nodes/links映射后的结构)
    const chartData = rawData.map(row => [row[0], row[1], row[2]]);
    data.addRows(chartData);

    const options = {
      sankey: {
        node: {
          // 确保节点标签使用我们生成的带百分比的名称
          label: {
            formatter: (label) => {
              const originalName = label.split(' (')[0];
              return nodeIndexMap[originalName] ? nodes[nodeIndexMap[originalName]].label : label;
            }
          }
        }
      }
    };

    const chart = new google.visualization.Sankey(document.getElementById('sankey_div'));
    chart.draw(data, options);
  });
}

关键细节说明

  • 节点流量统计:Sankey图中节点的总流量等于其所有流入/流出数值的总和,因此同时累加源和目标节点的数值,确保统计准确
  • 百分比格式化:使用toFixed(2)保留两位小数,可根据需求调整精度
  • 零值处理:加入总和为0的判断,避免出现除以0的错误
  • 标签匹配:若使用Google Charts的默认标签格式化,需通过原节点名称匹配带百分比的标签,确保显示正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:45:11