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

D3 Sankey从v3迁移到v4后出现TypeError: source未定义问题求助

解决D3 v3到v4迁移Sankey图时的TypeError: source is undefined问题

这个报错我在迁移D3 Sankey图到v4版本时也碰到过,大概率是数据转换不规范或者Sankey API适配错误导致的,咱们一步步来排查解决:

核心原因分析

你报错的那段sankey.js代码,是在把links里的source/target从数字索引转换成nodes数组里的节点对象。如果出现source is undefined,通常是两种情况:

  1. links里的source值既不是数字,也不是有效的节点对象(比如是CSV直接读取的字符串),导致代码没有完成转换,后续访问source.sourceLinks时出错。
  2. links里的source索引在nodes数组中找不到对应项(比如索引是-1),nodes[link.source]返回undefined。

分步解决方法

1. 规范处理CSV数据源

CSV文件读取后,所有字段默认都是字符串,而且可能存在空值或无效行,必须先转换为Sankey需要的格式:

  • 第一步:提取所有唯一的节点名称,生成nodes数组
  • 第二步:将links中的source/target转换为对应的nodes索引(数字类型)
  • 第三步:过滤掉无效行(比如缺失source/target/value的行)

示例代码:

d3.csv("your-data.csv").then(csvData => {
  // 1. 提取所有有效节点,过滤空值
  const nodesSet = new Set();
  csvData.forEach(d => {
    if (d.source && d.target) {
      nodesSet.add(d.source);
      nodesSet.add(d.target);
    }
  });
  const nodes = Array.from(nodesSet).map(name => ({ name }));

  // 2. 转换links,确保source/target是有效索引,value是数字
  const links = csvData
    .filter(d => d.source && d.target && d.value)
    .map(d => ({
      source: nodes.findIndex(n => n.name === d.source),
      target: nodes.findIndex(n => n.name === d.target),
      value: +d.value // 务必把字符串转成数字
    }))
    // 过滤掉找不到对应节点的无效链接
    .filter(d => d.source !== -1 && d.target !== -1);

  // 后续的Sankey布局代码...
}).catch(err => console.error("读取CSV失败:", err));

2. 适配D3 v4的Sankey API

D3 v4的Sankey布局API和v3差异很大,如果你还在沿用v3的调用方式,也会导致数据处理异常:

  • 确保使用的是适配v4的sankey库(比如官方的d3-sankey,而不是v3的旧代码)
  • 正确初始化和调用Sankey布局:

示例代码:

const width = 800;
const height = 600;

// 初始化Sankey布局
const sankey = d3.sankey()
  .nodeWidth(20) // 节点宽度
  .nodePadding(10) // 节点间距
  .extent([[10, 10], [width - 10, height - 10]]); // 布局范围

// 生成处理后的布局数据
const sankeyLayout = sankey({ nodes, links });

// 后续使用sankeyLayout.nodes和sankeyLayout.links绘制图形

3. 验证sankey.js版本兼容性

如果你使用的是自定义或第三方的sankey.js,要确保它是为D3 v4编写的。v3的sankey代码依赖v3的D3 API,直接在v4环境中运行会出现变量未定义的问题,建议替换为官方的d3-sankey包。

最后检查点

  • 确认CSV中没有空的source/target字段
  • 确认links里的所有source/target都能在nodes数组中找到对应项
  • 确认value字段已经转换成数字类型(Sankey需要数值型的流量值)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:17:50