
本文详解如何在 D3.js v3 环境下正确配置太阳图(Sunburst)的颜色标度,解决 d3.scaleOrdinal is not a function 报错及颜色全黑问题,提供可直接运行的兼容代码与关键注意事项。
本文详解如何在 d3.js v3 环境下正确配置太阳图(sunburst)的颜色标度,解决 `d3.scaleordinal is not a function` 报错及颜色全黑问题,提供可直接运行的兼容代码与关键注意事项。
在使用 D3.js v3(如 d3.v3.min.js)时,调用 d3.scaleOrdinal() 或 d3.schemePaired 会直接报错——因为这些 API 属于 D3 v4+ 的模块化设计,v3 中完全不存在。你遇到的 Uncaught TypeError: d3.scaleOrdinal is not a function 正是版本不兼容的典型表现;而尝试降级写法 d3.scale.ordinal(d3.schemePaired) 失败,根本原因在于:d3.schemePaired 在 v3 中根本未定义,传入 undefined 后,d3.scale.ordinal() 无法初始化有效域(domain)和范围(range),最终导致所有节点颜色退化为默认黑色。
✅ 正确做法是:完全弃用 v4+ 的 scheme 和 scaleOrdinal,改用 D3 v3 原生支持的序数标度 + 手动定义或内置色板。
D3 v3 提供了多个开箱即用的分类色板,最常用的是:
-
d3.scale.category10()—— 10 种高对比度颜色(推荐用于中等规模分类) -
d3.scale.category20()—— 20 种颜色(含 10 对相似色调,适合父子层级区分) -
d3.scale.category20b()/d3.scale.category20c()—— 补充色系,增强视觉多样性
以下是适配你原始代码的完整 v3 兼容方案:
<!-- ✅ 仅保留 D3 v3,移除冲突的 v5+ CDN -->
<script src="http://d3js.org/d3.v3.min.js"></script><script src="//unpkg.com/sunburst-chart@1.12.0"></script><style>body { margin: 0 }</style><div id="chart"></div>
<script>
// ✅ D3 v3 正确写法:创建 category20 序数标度
// 注意:v3 中 scale 是函数,需显式调用 .domain() 定义输入类别
const colorScale = d3.scale.category20();
// ✅ 关键步骤:手动提取所有唯一父类名(或层级名)构建 domain
// 这里以 'flare.json' 数据结构为例(类似 {name: "root", children: [...] })
function extractNames(data, names = []) {
if (data.name) names.push(data.name);
if (data.children) data.children.forEach(child => extractNames(child, names));
return names;
}
fetch('flare.json')
.then(res => res.json())
.then(data => {
// 构建 domain:所有唯一节点名称(确保 colorScale 有足够映射)
const allNames = [...new Set(extractNames(data))];
colorScale.domain(allNames); // ⚠️ 必须设置 domain!否则返回 undefined → 黑色
Sunburst()
.data(data)
.label('name')
.size('size')
.color((d, parent) => {
// ✅ v3 兼容逻辑:取 parent.data.name(或 d.name),避免 null/undefined
const key = parent ? parent.data.name : d.name || 'root';
return colorScale(key); // 自动映射到 category20 范围内
})
.tooltipContent((d, node) => `Size: <i>${node.value}`)
(document.getElementById('chart'));
});
</script>
? 重要注意事项:
-
必须显式调用
.domain([...]):D3 v3 的序数标度不会自动推断输入值,未设 domain 时任何输入都返回null,CSS 渲染为黑色; -
避免混用版本:删除
<script src="//unpkg.com/d3"></script>(这是 v5+ 默认版),否则可能造成全局d3对象覆盖,引发不可预测行为; -
色板容量匹配:
category10最多支持 10 类,若数据分类 >10,优先选category20;如需更多颜色,可自定义数组:const customColors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', /* ... */]; const colorScale = d3.scale.ordinal().range(customColors);
-
sunburst-chart 版本兼容性:确认你使用的
sunburst-chart版本支持 D3 v3(推荐锁定@1.x,如//unpkg.com/sunburst-chart@1.12.0);v2+ 已要求 D3 v5+。
通过以上调整,你的太阳图将正确渲染彩色分层,并完全兼容现有 D3 v3 生态。升级至 D3 v5+ 虽是长期建议,但本方案让你无需重构即可稳定交付。










