OpenMontage D3.js 配色方案完全指南:从内置色板到可访问性最佳实践
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
导读
本文是 OpenMontage 项目中 D3.js 数据可视化技能(.claude/skills/d3-viz/SKILL.md)配套的配色参考文档(colour-schemes.md)的完整展开版。它系统讲解 D3.js 内置分类 / 连续 / 发散三类色板的选型、色盲友好配色的落地方法、自定义色板的感知均匀插值技巧,以及 WCAG 对比度与冗余编码等可访问性规范。读完本文,你将掌握"面对任意数据集如何快速选对色板、如何编写可复制的 d3 配色代码、如何在深色背景与多系列图表中保持专业观感"的完整实战方案。
一、先建立体系:interpolate 函数与 scheme 数组是两套 API
D3.js 的配色能力来自d3-scale-chromatic模块,它提供了两套互补的 API,理解二者的区别是正确选型的前提:
d3.schemeXxx是离散数组:直接给出固定数量的色值(例如d3.schemeCategory10返回 10 个十六进制字符串),配合d3.scaleOrdinal()做分类编码;d3.schemeBlues[9]则是 9 步的离散渐变版本。d3.interpolateXxx是连续函数:接受[0,1]区间内的归一化数值并返回对应颜色,配合d3.scaleSequential()/d3.scaleDiverging()做连续数值编码。
两者可以互相转换:d3.quantize(d3.interpolateViridis, n)可以把连续插值器切成 n 段离散色值(详见下文"动态配色选择")。与这套体系配套的完整尺度用法(scaleOrdinal、scaleSequential、scaleDiverging、scaleSequentialQuantile以及interpolateLab/interpolateHcl/interpolateHsl等色彩空间插值)记录在同目录的 scale-reference.md 中,本文第 6 节会重点展开其中的 Lab / HCL 插值。
二、内置分类色板(Categorical Schemes)
分类色板用于"离散类别 → 颜色"的映射,最常见的载体是d3.scaleOrdinal()。D3 内置了 10 套方案,覆盖从默认到专业到柔和的各种需求。
Category10(默认)
d3.schemeCategory10 // ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', // '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']特性:
- 10 个相互区分的颜色
- 对色盲有较好的可辨别性
- 大多数分类数据的默认选择
- 饱和度与亮度均衡
适用场景:通用分类编码、图例条目、多数据系列。仓库中的 d3 模式库(d3-patterns.md)在树状图、矩形树图(treemap)、旭日图(sunburst)、弦图(chord)、堆叠柱状图、气泡图等多个模板中都直接使用d3.scaleOrdinal(d3.schemeCategory10)作为开箱即用的着色方案,例如 chord 图中d3.scaleOrdinal(d3.schemeCategory10).domain(nodes)。
Tableau10
d3.schemeTableau10特性:
- 10 个为数据可视化优化的颜色
- 外观专业
- 区分度出色
适用场景:商业仪表盘、专业报告、演示文稿。
Accent
d3.schemeAccent // 8 colours with high saturation特性:
- 明亮、鲜活的颜色
- 高对比度
- 现代审美
适用场景:突出重要类别、现代 Web 应用。
Dark2
d3.schemeDark2 // 8 darker, muted colours特性:
- 低调的调色板
- 外观专业
- 适合深色背景
适用场景:深色模式可视化、专业场景。
Paired
d3.schemePaired // 12 colours in pairs of similar hues特性:
- 明暗两两成对
- 适合嵌套类别
- 12 个可区分颜色
适用场景:分组柱状图、层次类别、前后对比。当类别数超过 10 但不超过 12 时,Paired 是官方速查表推荐的第一选择(见第 12 节)。
Pastel1 & Pastel2
d3.schemePastel1 // 9 colours d3.schemePastel2 // 8 colours特性:
- 柔和、低饱和度
- 温和的外观
- 适合大面积填充
适用场景:背景色、弱化分类、安静舒缓的可视化。
Set1、Set2、Set3
d3.schemeSet1 // 9 colours - vivid d3.schemeSet2 // 8 colours - muted d3.schemeSet3 // 12 colours - pastel特性:
- Set1:高饱和度,区分度最大
- Set2:专业、均衡
- Set3:柔和、容纳更多类别
适用场景:依据视觉层次需求灵活选择。上述全部内置分类色板的逐项列表同时收录于 scale-reference.md 的"Ordinal colour scale"一节。
三、连续色板(Sequential Schemes)
连续色板用单一色相或渐变把连续数据从低到高映射,覆盖热力图、分级统计图(choropleth)、密度图和单指标可视化四类典型场景。
单色相连续
Blues:
d3.interpolateBlues d3.schemeBlues[9] // 9-step discrete version其他单色相选项:
d3.interpolateGreens/d3.schemeGreensd3.interpolateOranges/d3.schemeOrangesd3.interpolatePurples/d3.schemePurplesd3.interpolateReds/d3.schemeRedsd3.interpolateGreys/d3.schemeGreys
适用场景:
- 简单热力图
- 分级统计图
- 密度图
- 单一指标可视化
仓库模式库中的 choropleth 模板正是采用d3.scaleSequential(d3.interpolateBlues).domain([0, d3.max(valueData, d => d.value)])为地图区域按数值着色(见 d3-patterns.md)。
多色相连续(感知均匀,推荐优先)
Viridis(推荐):
d3.interpolateViridis特性:
- 感知均匀(perceptually uniform)
- 色盲友好
- 打印安全
- 无视觉死区
- 感知亮度单调递增
其他感知均匀选项:
d3.interpolatePlasma- 紫到黄d3.interpolateInferno- 黑经红/橙到白d3.interpolateMagma- 黑经紫到白d3.interpolateCividis- 为色觉缺陷(CVD)优化
色盲可访问的多色相:
d3.interpolateTurbo // Rainbow-like but perceptually uniform d3.interpolateCool // Cyan to magenta d3.interpolateWarm // Orange to yellow适用场景:
- 科学可视化
- 医学影像
- 任何高精度数据可视化
- 需要可访问性的可视化
传统多色相
Yellow-Orange-Red:
d3.interpolateYlOrRd d3.schemeYlOrRd[9]Yellow-Green-Blue:
d3.interpolateYlGnBu d3.schemeYlGnBu[9]其他多色相:
d3.interpolateBuGn- 蓝到绿d3.interpolateBuPu- 蓝到紫d3.interpolateGnBu- 绿到蓝d3.interpolateOrRd- 橙到红d3.interpolatePuBu- 紫到蓝d3.interpolatePuBuGn- 紫到蓝绿d3.interpolatePuRd- 紫到红d3.interpolateRdPu- 红到紫d3.interpolateYlGn- 黄到绿d3.interpolateYlOrBr- 黄到橙棕
适用场景:传统数据可视化、用户熟悉的多色相联想(温度、植被、水体)。热力图模板的默认着色就来自这一家族——d3.scaleSequential(d3.interpolateYlOrRd).domain([0, d3.max(data, d => d.value)])(见 d3-patterns.md),从浅黄到深红的渐变天然适合表达强度递增。
四、发散色板(Diverging Schemes)
发散色板用两个截然不同的色相强调相对于中心值的偏离。它要求数据存在有意义的零点或基准(零、平均值、中性值),并用"中间浅、两端深"的渐变同时突出极值与中段。
Red-Blue(温度隐喻)
d3.interpolateRdBu d3.schemeRdBu[11]特性:
- 直观的温度隐喻
- 强对比
- 清晰的正负区分
适用场景:温度、盈亏、高于/低于平均、相关性。
Red-Yellow-Blue
d3.interpolateRdYlBu d3.schemeRdYlBu[11]特性:
- 三色渐变
- 经黄色柔和过渡
- 视觉阶数更多
适用场景:极值需要强调、中段也需要可读性的场景。
其他发散方案
红绿灯:
d3.interpolateRdYlGn // Red (bad) to green (good)Spectral(彩虹):
d3.interpolateSpectral // Full spectrum其他选项:
d3.interpolateBrBG- 棕到蓝绿d3.interpolatePiYG- 粉到黄绿d3.interpolatePRGn- 紫到绿d3.interpolatePuOr- 紫到橙d3.interpolateRdGy- 红到灰
适用场景:依据语义含义与可访问性需求选择。
发散色板在代码中的标准落地是d3.scaleDiverging(d3.interpolateRdBu).domain([-10, 0, 10])——domain 必须传三元素数组,中间的 0 对应渐变的中点(通常是白色或浅灰)。完整的分发 interpolator 列表见 scale-reference.md。
五、色盲友好配色(Colour-Blind Friendly Palettes)
通用指南
- 避免红绿组合(最常见的色盲类型——红绿色盲)
- 用蓝橙发散替代红绿发散
- 叠加纹理或图案作为冗余编码
- 用模拟工具测试
推荐的色盲安全方案
分类:
// Okabe-Ito palette (colour-blind safe) const okabePalette = [ '#E69F00', // Orange '#56B4E9', // Sky blue '#009E73', // Bluish green '#F0E442', // Yellow '#0072B2', // Blue '#D55E00', // Vermillion '#CC79A7', // Reddish purple '#000000' // Black ]; const colourScale = d3.scaleOrdinal() .domain(categories) .range(okabePalette);Okabe-Ito 是学术界与出版业广泛认可的色盲安全分类色板,8 个颜色覆盖橙、天蓝、蓝绿、黄、蓝、朱红、红紫、黑,即使重度色觉缺陷用户也能区分绝大多数类别。注意方案内部已经主动用"蓝 + 橙"取代了"红 + 绿"这对高风险组合。
连续:
// Use Viridis, Cividis, or Blues d3.interpolateViridis // Best overall d3.interpolateCividis // Optimised for CVD d3.interpolateBlues // Simple, safe发散:
// Use blue-orange instead of red-green d3.interpolateBrBG d3.interpolatePuOr六、自定义色板:用 Lab / HCL 插值保证感知均匀
内置色板不满足品牌或业务需求时,可以自定义色板。关键技巧是:默认的 RGB 线性插值会产生中间发灰、视觉不均匀的渐变,而d3.interpolateLab和d3.interpolateHcl基于感知均匀的色彩空间,中间过渡更自然(scale-reference.md 中对此有专门对照:RGB 插值默认、HSL 更平滑、Lab 感知均匀、HCL 感知均匀且带色相)。
创建自定义连续色板
const customSequential = d3.scaleLinear() .domain([0, 100]) .range(['#e8f4f8', '#006d9c']) // Light to dark blue .interpolate(d3.interpolateLab); // Perceptually uniform创建自定义发散色板
const customDiverging = d3.scaleLinear() .domain([0, 50, 100]) .range(['#ca0020', '#f7f7f7', '#0571b0']) // Red, grey, blue .interpolate(d3.interpolateLab);创建自定义分类色板
// Brand colours const brandPalette = [ '#FF6B6B', // Primary red '#4ECDC4', // Secondary teal '#45B7D1', // Tertiary blue '#FFA07A', // Accent coral '#98D8C8' // Accent mint ]; const colourScale = d3.scaleOrdinal() .domain(categories) .range(brandPalette);自定义分类色板在真实项目中通常表现为"预定义品牌色数组 + 按索引取模"的模式——OpenMontage 的 Remotion 图表组件就是这样落地的:BarChart、LineChart、PieChart均默认使用colors = ["#2563EB", "#F59E0B", "#10B981", "#EC4899", "#06B6D4", "#8B5CF6"]这套蓝-橙-绿-粉-青-紫六色品牌板,通过colors[i % colors.length]循环分配(见 BarChart.tsx、LineChart.tsx、PieChart.tsx)。这验证了第 2 节的建议:类别 ≤6 时 6 色足够,超出的类别应分组而非无限加色。
七、语义色关联(Semantic Colour Associations)
颜色不只是装饰,它携带语义。使用与受众预期一致的配色能显著降低理解成本。
通用颜色含义
红色:
- 危险、错误、负面
- 高温
- 负债、亏损
绿色:
- 成功、正面
- 增长、植被
- 盈利、收益
蓝色:
- 信任、冷静
- 水、寒冷
- 信息、中性
黄色/橙色:
- 警告、谨慎
- 能量、温暖
- 吸引注意
灰色:
- 中性、非活跃
- 缺失数据
- 背景
场景化色板
金融:
const financialColours = { profit: '#27ae60', loss: '#e74c3c', neutral: '#95a5a6', highlight: '#3498db' };温度:
const temperatureScale = d3.scaleSequential(d3.interpolateRdYlBu) .domain([40, -10]); // Hot to cold (reversed)注意温度场景的 domain 是反向的:40(热)对应红端,-10(冷)对应蓝端。如果写成[ -10, 40 ]就出现了"第 11 节错误清单"中的倒置温度标尺问题。
交通/状态:
const statusColours = { success: '#27ae60', warning: '#f39c12', error: '#e74c3c', info: '#3498db', neutral: '#95a5a6' };这种"绿=成功 / 红=错误 / 灰=中性"的语义编码在 OpenMontage 的 KPI 组件中同样可见:KPIGrid默认positiveColor = "#10B981"(涨)、negativeColor = "#EF4444"(跌),涨跌指示符▲/▼再配合颜色形成双重编码(见 KPIGrid.tsx),正是第 8 节"冗余编码"的工程化范例。
八、可访问性最佳实践(Accessibility)
对比度
确保颜色与背景之间有足够对比度:
// Good contrast example const highContrast = { background: '#ffffff', text: '#2c3e50', primary: '#3498db', secondary: '#e74c3c' };WCAG 对比度要求:
- 普通文本:最小 4.5:1
- 大文本:最小 3:1
- UI 组件:最小 3:1
冗余编码
永远不要只依赖颜色传达信息:
// Add patterns or shapes const symbols = ['circle', 'square', 'triangle', 'diamond']; // Add text labels // Use line styles (solid, dashed, dotted) // Use size encoding测试
为可视化做色盲模拟测试:
- Chrome DevTools(Rendering > Emulate vision deficiencies)
- Colour Oracle(免费桌面应用)
- Coblis(在线模拟器)
九、专业配色推荐(Professional Recommendations)
针对不同输出场景,业界形成了可复用的成熟色板。
数据新闻
// Guardian style const guardianPalette = [ '#005689', // Guardian blue '#c70000', // Guardian red '#7d0068', // Guardian pink '#951c75', // Guardian purple ]; // FT style const ftPalette = [ '#0f5499', // FT blue '#990f3d', // FT red '#593380', // FT purple '#262a33', // FT black ];学术/科学
// Nature journal style const naturePalette = [ '#0071b2', // Blue '#d55e00', // Vermillion '#009e73', // Green '#f0e442', // Yellow ]; // Use Viridis for continuous data const scientificScale = d3.scaleSequential(d3.interpolateViridis);注意 Nature 风格的 4 色分类板实际就是 Okabe-Ito 的子集(蓝、朱红、绿、黄),说明科学出版界与色盲安全规范高度重合。
企业/商务
// Professional, conservative const corporatePalette = [ '#003f5c', // Dark blue '#58508d', // Purple '#bc5090', // Magenta '#ff6361', // Coral '#ffa600' // Orange ];这套"深蓝-紫-品红-珊瑚-橙"是数据可视化界常用的高频专业板,色相跨度大、明度递增,在深色与浅色背景上都有良好表现。
十、动态配色选择:让代码替你决策
把选色逻辑封装成函数,根据数据特征自动选择色板类型,是工程化的最佳实践。
基于数据范围
function selectColourScheme(data) { const extent = d3.extent(data); const hasNegative = extent[0] < 0; const hasPositive = extent[1] > 0; if (hasNegative && hasPositive) { // Diverging: data crosses zero return d3.scaleSequentialSymlog(d3.interpolateRdBu) .domain([extent[0], 0, extent[1]]); } else { // Sequential: all positive or all negative return d3.scaleSequential(d3.interpolateViridis) .domain(extent); } }判定逻辑:数据同时包含正负值 → 用发散色板并把 0 作为中点;否则 → 用连续色板。这里用scaleSequentialSymlog是因为当数据跨越正负且在 0 附近密集分布时,symlog(对称对数)变换比线性更能保留细节。
基于类别数量
function selectCategoricalScheme(categories) { const n = categories.length; if (n <= 10) { return d3.scaleOrdinal(d3.schemeTableau10); } else if (n <= 12) { return d3.scaleOrdinal(d3.schemePaired); } else { // For many categories, use sequential with quantize return d3.scaleQuantize() .domain([0, n - 1]) .range(d3.quantize(d3.interpolateRainbow, n)); } }分段策略:≤10 类用 Tableau10;10~12 类用 Paired(明暗成对容纳更多类别);超过 12 类则放弃分类色板,改用d3.quantize(d3.interpolateRainbow, n)把彩虹连续插值器切成 n 段离散色值——这是把"连续 API 转离散数组"的标准用法,也呼应了第 1 节的体系说明。
十一、常见配色错误与规避
- 用彩虹渐变表达连续数据
- 问题:不感知均匀、难以读数
- 解决:用 Viridis、Blues 等均匀色板
- 发散数据用红绿
- 问题:约 8% 的男性无法区分红绿(红绿色盲是最常见类型)
- 解决:用蓝橙或紫绿
- 分类颜色过多
- 问题:难以区分和记忆
- 解决:限制在 5~8 个类别以内,超出的做分组
- 对比度不足
- 问题:可读性差
- 解决:测试对比度,浅色背景上用更深的颜色
- 忽视文化差异的颜色含义
- 问题:语义混淆(例如在某些文化中白色代表丧事而非纯洁)
- 解决:研究目标受众的颜色联想
- 温度标尺倒置
- 问题:违背直觉(红色却表示寒冷)
- 解决:红/橙 = 热,蓝 = 冷
十二、快速参考指南
需要表达……
- 分类(≤10):
d3.schemeCategory10或d3.schemeTableau10 - 分类(>10):
d3.schemePaired或对类别分组 - 连续(通用):
d3.interpolateViridis - 连续(科学):
d3.interpolateViridis或d3.interpolatePlasma - 连续(温度):
d3.interpolateRdYlBu(反向 domain) - 发散(零点):
d3.interpolateRdBu或d3.interpolateBrBG - 发散(好坏):
d3.interpolateRdYlGn(反向 domain) - 色盲安全(分类):Okabe-Ito 色板(上文已给出)
- 色盲安全(连续):
d3.interpolateCividis或d3.interpolateBlues - 色盲安全(发散):
d3.interpolatePuOr或d3.interpolateBrBG
永远记住:
- 为色盲做测试
- 保证足够对比度
- 恰当使用语义色
- 添加冗余编码(图案、标签)
- 保持简单(颜色越少,可视化越清晰)
十三、在 OpenMontage 中继续深入
配色是数据可视化的"最后一公里",但在 OpenMontage 中它服务于更完整的创作链路。你可以通过以下仓库资源继续深化:
- .claude/skills/d3-viz/SKILL.md:d3-viz 技能主文档,涵盖"何时用 d3、两种集成模式(直接 DOM 操作 vs 声明式渲染)、标准绘图结构、响应式布局、过渡动画"等完整工作流,配色方案正是其第 5 步"绑定数据并创建视觉元素"时的核心决策。
- .claude/skills/d3-viz/references/scale-reference.md:所有 d3 尺度类型的完整参考,包括
scaleOrdinal/scaleSequential/scaleDiverging/scaleSequentialQuantile与全部内置 interpolator 清单,是本文 API 部分的底层支撑。 - .claude/skills/d3-viz/references/d3-patterns.md:树状图、矩形树图、旭日图、弦图、热力图、面积图、堆叠/分组柱状图、气泡图、地图、刷选与过渡等 20+ 图表模板,每个模板都标注了推荐的色板用法(如热力图用
interpolateYlOrRd、choropleth 用interpolateBlues)。 - .claude/skills/d3-viz/assets/chart-template.jsx:可直接运行的基础柱状图模板,展示了把本文的色板接入完整 React 组件的标准写法。
- remotion-composer/src/components/charts/:OpenMontage 视频渲染管线中的真实图表组件(BarChart、LineChart、PieChart、KPIGrid 等),展示了品牌色数组、语义色(涨绿跌红)、网格与文字对比度等在 1920×1080 视频画布上的生产级落地,可作为把配色规范应用到实际成片的参考实现。
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考