OpenMontage 中 D3.js Scale 尺度系统全解:从连续、序数到色标尺度的选型与实践指南
导读
在数据可视化开发中,Scale(尺度)是连接"数据值"与"像素/颜色等视觉元素"的核心桥梁。本文以 OpenMontage 仓库中 d3-viz 技能的 scale 参考手册 为骨架,系统拆解 D3.js v7 中连续型、序数型、序贯型(颜色)尺度与尺度工具函数的全部类型、核心方法、内置色板与组合模式,并结合仓库内 SKILL.md、colour-schemes.md 与 d3-patterns.md 等配套资料深入展开。读完本文,你将掌握"什么数据该配什么尺度"的完整决策链,并能在 OpenMontage 的视频图表渲染(如 remotion-composer 中的动画图表组件)以及各类自定义 SVG 可视化中直接落地这些 API。
该参考文档同时以两份副本形式存在于仓库
.agents/skills/d3-viz/references/scale-reference.md与.claude/skills/d3-viz/references/scale-reference.md,供不同的 Agent 运行时读取。
尺度选型的总览:先看数据"长什么样"
D3.js 的尺度(d3.scale*)本质是一个函数:输入原始数据域(domain),输出视觉范围(range)。选型的第一原则取决于你的输入数据类型与分布形态:
- 连续数值、线性分布 →
scaleLinear - 跨越多个数量级、指数增长 →
scaleLog/scalePow - 时间日期 →
scaleTime - 需要把连续数据切成有限桶(分类/分级) →
scaleQuantize/scaleQuantile/scaleThreshold - 颜色随连续值渐变 →
scaleSequential(含scaleDiverging、scaleSequentialQuantile) - 离散分类输入 →
scaleBand(柱/条/格)、scalePoint(点/线/散点)、scaleOrdinal(分类着色)
这与 d3-viz/SKILL.md 中"Scales reference"一节的归类一致:scaleLinear、scaleLog、scalePow、scaleTime 为定量尺度,scaleBand、scalePoint、scaleOrdinal 为序数尺度,scaleSequential、scaleDiverging 为序贯颜色尺度。下面按该分类逐层展开。
连续型尺度(Continuous scales)
连续尺度把连续的输入域映射到连续的输出范围,是整个体系中使用频率最高的一族。参考文档(.agents/skills/d3-viz/references/scale-reference.md)逐一给出了每一类的行为细节。
Linear scale:定量数据的主力
scaleLinear 以线性插值把连续输入域映射到连续输出域,是坐标轴、柱长、位置编码的默认选择:
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, 500]);
scale(50); // Returns 250
scale(0); // Returns 0
scale(100); // Returns 500
// Invert scale (get input from output)
scale.invert(250); // Returns 50
适用场景:定量数据(温度、价格、计数、测量值)的绝大多数可视化;坐标轴刻度定位、柱状图柱长、位置坐标编码。
核心方法(如下表):
| 方法 | 作用 |
|---|---|
.domain([min, max]) |
设置输入数据域(常由 d3.min/d3.max/d3.extent 计算得到) |
.range([min, max]) |
设置输出像素/数值范围 |
.invert(value) |
反解:由范围值反推域值(配合鼠标坐标查询数据点) |
.clamp(true) |
将输出限定在范围内,超界值按边界截断 |
.nice() |
将 domain 扩展到更"整"的数值(如 0.201→0.2、0.996→1.0) |
Power scale:指数/幂次变换
scalePow 以幂指数做非线性变换,配 scaleSqrt 简写用于开方。指数缩放大量用于感知校正——人类视觉对面积/半径的感知不是线性的:
const sqrtScale = d3.scalePow()
.exponent(0.5) // Square root
.domain([0, 100])
.range([0, 500]);
const squareScale = d3.scalePow()
.exponent(2) // Square
.domain([0, 100])
.range([0, 500]);
// Shorthand for square root
const sqrtScale2 = d3.scaleSqrt()
.domain([0, 100])
.range([0, 500]);
适用场景:把人眼感知映射为线性(如圆形面积与数值成正比时用平方根尺度);强调小值/大值区间的差异。配套的 d3-patterns.md 在 Bubble chart 中正是用 d3.scaleSqrt().range([0, 50]) 把 size 字段映射为气泡半径。
Logarithmic scale:跨越数量级的数据
scaleLog 采用对数变换压缩悬殊的数值跨度。重要前提:domain 必须严格为正(>0),不能包含 0 或负数:
const logScale = d3.scaleLog()
.domain([1, 1000]) // Must be positive
.range([0, 500]);
logScale(1); // Returns 0
logScale(10); // Returns ~167
logScale(100); // Returns ~333
logScale(1000); // Returns 500
适用场景:跨越多个数量级的数据(人口、GDP、财富分布);对数坐标轴;指数增长的可视化。
Time scale:时间序列的线性特化
scaleTime 是面向时间/日期的线性尺度特化,domain 直接使用 Date 对象,天然支持 invert、ticks、nice 等能力:
const timeScale = d3.scaleTime()
.domain([new Date(2020, 0, 1), new Date(2024, 0, 1)])
.range([0, 800]);
timeScale(new Date(2022, 0, 1)); // Returns 400
// Invert to get date
timeScale.invert(400); // Returns Date object for mid-2022
适用场景:时间序列图、时间线坐标轴、按时间推进的动画、基于日期的交互。
方法要点:.nice() 把 domain 扩展到整的时间间隔;.ticks(count) 生成间隔均匀的刻度值;线性尺度的全部方法(clamp、invert 等)对它同样生效。在 d3-patterns.md 的面积渐变图中,x 轴正是 d3.scaleTime().domain(d3.extent(data, d => d.date)) 的标准组合。配合时间刻度格式化 timeScale.tickFormat(5, "%Y-%m") 可以输出"年-月"样式的刻度标签。
将连续值切桶的三兄弟:Quantize / Quantile / Threshold
当连续数据需要离散输出(桶/分级/颜色档位)时,有三种切法,差别在于切点如何确定:
Quantize(等宽切分)——按 domain 均匀切分为 N 段(range 元素个数决定 N):
const quantizeScale = d3.scaleQuantize()
.domain([0, 100])
.range(['low', 'medium', 'high']);
quantizeScale(25); // Returns 'low'
quantizeScale(50); // Returns 'medium'
quantizeScale(75); // Returns 'high'
// Get the threshold values
quantizeScale.thresholds(); // Returns [33.33, 66.67]
适用场景:连续数据装箱(binning);热力图颜色分档;低/中/高风险分类;年龄组、收入区间。
Quantile(分位数切分)——基于样本分布按分位数切,保证每个桶中样本数尽量相等,不受极端分布干扰:
const quantileScale = d3.scaleQuantile()
.domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20, 24]) // Sample data
.range(['low', 'medium', 'high']);
quantileScale(8); // Returns based on quantile position
quantileScale.quantiles(); // Returns quantile thresholds
适用场景:无论分布如何都希望各组样本量接近时;按百分位归类;处理偏态分布。
Threshold(自定义切点)——完全由你控制断点,domain 的每个值都是阈值,range 元素数恒为 domain 长度 + 1:
const thresholdScale = d3.scaleThreshold()
.domain([0, 10, 20])
.range(['freezing', 'cold', 'warm', 'hot']);
thresholdScale(-5); // Returns 'freezing'
thresholdScale(5); // Returns 'cold'
thresholdScale(15); // Returns 'warm'
thresholdScale(25); // Returns 'hot'
适用场景:自定义断点;成绩等级(A/B/C/D/F);温度分类;空气质量指数分级。
选型小结:想"均匀切数值"用 Quantize;想"均匀切样本量、抗偏态"用 Quantile;想"完全自定义阈值"用 Threshold。
序贯与发散颜色尺度(Sequential & Diverging scales)
颜色编码是可视化最常用的视觉通道。序贯类尺度把连续数据映射为连续颜色梯度,专门服务于热力图、等值区域图、密度图等"数值越大颜色越深"的表达。
连续渐变:scaleSequential
const colourScale = d3.scaleSequential(d3.interpolateBlues)
.domain([0, 100]);
colourScale(0); // Returns lightest blue
colourScale(50); // Returns mid blue
colourScale(100); // Returns darkest blue
可用的插值器(interpolator):
- 单色相:
d3.interpolateBlues、d3.interpolateGreens、d3.interpolateReds、d3.interpolateOranges、d3.interpolatePurples、d3.interpolateGreys - 多色相:
d3.interpolateViridis、d3.interpolateInferno、d3.interpolateMagma、d3.interpolatePlasma、d3.interpolateWarm、d3.interpolateCool、d3.interpolateCubehelixDefault、d3.interpolateTurbo
适用场景:热力图、等值区域(choropleth)图;连续数据的密度、温度、海拔表达。仓库内的 colour-schemes.md 明确推荐:科学可视化首选 d3.interpolateViridis(感知均匀、色盲友好、无可读死区);传统可视化常用 YlOrRd、YlGnBu 等配色。
带中点的发散:scaleDiverging
发散尺度以中间值(0、均值、中性值)为中心,两端使用两种不同色相表达"正/负""上/下":
const divergingScale = d3.scaleDiverging(d3.interpolateRdBu)
.domain([-10, 0, 10]);
divergingScale(-10); // Returns red
divergingScale(0); // Returns white/neutral
divergingScale(10); // Returns blue
可用的发散插值器(完整清单来自参考文档):
d3.interpolateRdBu:红 ↔ 蓝d3.interpolateRdYlBu:红 ↔ 黄 ↔ 蓝d3.interpolateRdYlGn:红 ↔ 黄 ↔ 绿(红=坏/绿=好,注意色盲友好性)d3.interpolatePiYG:粉 ↔ 黄 ↔ 绿d3.interpolateBrBG:棕 ↔ 蓝绿d3.interpolatePRGn:紫 ↔ 绿d3.interpolatePuOr:紫 ↔ 橙d3.interpolateRdGy:红 ↔ 灰d3.interpolateSpectral:完整光谱(rainbow)
适用场景:具有语义中点(零值、均值、中性)的数据;正负值对比;高于/低于基准的对照;相关性矩阵。
分布感知的 color + quantile 复合
scaleSequentialQuantile 把序贯颜色与分位数切分结合起来,domain 传入的是全部样本数组而非 [min, max],映射依据分位位置决定,天然抗离群点:
const sequentialQuantileScale = d3.scaleSequentialQuantile(d3.interpolateBlues)
.domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20, 24]);
// Maps based on quantile position
适用场景:感知均匀的样本量均匀分色;处理离群点与偏态分布。
序数型尺度(Ordinal scales)
序数尺度面向离散的分类输入,输出要么是像素区间/点位,要么是离散颜色,是柱状图、分类坐标轴、图例与多序列图表的基石。
Band scale:柱状图与单元格
把分类映射为一段段带宽度的"带",支持内/外 padding,并提供带宽(bandwidth)与步长(step)查询:
const bandScale = d3.scaleBand()
.domain(['A', 'B', 'C', 'D'])
.range([0, 400])
.padding(0.1);
bandScale('A'); // Returns start position (e.g., 0)
bandScale('B'); // Returns start position (e.g., 110)
bandScale.bandwidth(); // Returns width of each band (e.g., 95)
bandScale.step(); // Returns total step including padding
bandScale.paddingInner(); // Returns inner padding (between bands)
bandScale.paddingOuter(); // Returns outer padding (at edges)
padding 控制项:
.padding(value):同时设置内、外 padding(取值范围 0–1).paddingInner(value):带与带之间的间距比例(0–1).paddingOuter(value):两端边缘留白比例(0–1).align(value):带的对齐方式(0–1,默认 0.5 居中)
适用场景:柱状图(最典型);分组元素定位;分类坐标轴;热力图单元格。在 OpenMontage 的图表渲染实践中,热力图与柱状图的 x/y 定位均依赖它(见 d3-patterns.md 中 Heatmap 的 d3.scaleBand().padding(0.01) 用法);在 remotion-composer 中,即使不使用 D3 裸 API,动画柱状图同样遵循"按分类数均分可用宽度、柱间留 gap"的 band 布局思想。
Point scale:只有位置的离散点
Point scale 与 Band scale 相似,但输出没有宽度,只产生一个位置点,适合折线图/散点图的分类横轴:
const pointScale = d3.scalePoint()
.domain(['A', 'B', 'C', 'D'])
.range([0, 400])
.padding(0.5);
pointScale('A'); // Returns position (e.g., 50)
pointScale('B'); // Returns position (e.g., 150)
pointScale('C'); // Returns position (e.g., 250)
pointScale('D'); // Returns position (e.g., 350)
pointScale.step(); // Returns distance between points
适用场景:折线图的分类 x 轴;分类轴散点图;网络图节点位置;任意"分类→点位置"的场景。
Ordinal scale:分类到颜色/形状
scaleOrdinal 把离散分类稳定地映射为离散输出(颜色等),同一分类永远得到同一颜色(保持一致性):
const colourScale = d3.scaleOrdinal(d3.schemeCategory10);
colourScale('apples'); // Returns first colour
colourScale('oranges'); // Returns second colour
colourScale('apples'); // Returns same first colour (consistent)
// Custom range
const customScale = d3.scaleOrdinal()
.domain(['cat1', 'cat2', 'cat3'])
.range(['#FF6B6B', '#4ECDC4', '#45B7D1']);
内置分类色板(参考文档与 colour-schemes.md 共同列出):
| 色板 | 颜色数 | 特点 |
|---|---|---|
d3.schemeCategory10 |
10 | 默认选择,色彩平衡、色盲友好 |
d3.schemeAccent |
8 | 明亮高饱和、现代感 |
d3.schemeDark2 |
8 | 暗调低饱和、适合深色背景 |
d3.schemePaired |
12 | 浅/深成对,适合嵌套分类 |
d3.schemePastel1 / d3.schemePastel2 |
9 / 8 | 柔和低饱和、适合大面积底色 |
d3.schemeSet1 |
9 | 高饱和、区分度最大 |
d3.schemeSet2 |
8 | 专业均衡 |
d3.schemeSet3 |
12 | 柔和、分类多 |
d3.schemeTableau10 |
10 | 面向可视化优化、专业报表常用 |
适用场景:分类着色、图例条目、多序列图表、网络图节点类型区分。
一个关键补充:.unknown()
在参考文档的"Common patterns"章节末尾给出了一种被很多人忽略的健壮性配置——为未知分类设置回退色:
const colourScale = d3.scaleOrdinal()
.domain(['Low Risk', 'Medium Risk', 'High Risk'])
.range(['#2ecc71', '#f39c12', '#e74c3c'])
.unknown('#95a5a6'); // Fallback for unknown values
当传入不在 domain 中的分类时,返回灰色 #95a5a6,避免脏数据直接生成 undefined 颜色。
尺度工具函数与刻度控制(Scale utilities)
无论使用哪类尺度,以下工具函数都高频出现在坐标轴与"反向查询"场景中,参考文档将其单列为 Utility 一章。
nice():把 domain 修整到"好看"的整数
const scale = d3.scaleLinear()
.domain([0.201, 0.996])
.nice();
scale.domain(); // Returns [0.2, 1.0]
// With count (approximate tick count)
const scale2 = d3.scaleLinear()
.domain([0.201, 0.996])
.nice(5);
nice() 可传一个近似刻度数的参数(如 .nice(5)),让坐标轴刻度落在 0.2、0.4、0.6、0.8、1.0 这类"整"值上,是避免坐标轴出现 0.201 之类丑陋刻度的最简手段。
clamp():把输出钉死在范围内
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, 500])
.clamp(true);
scale(-10); // Returns 0 (clamped)
scale(150); // Returns 500 (clamped)
默认情况下,超出 domain 的输入会产生超出 range 的输出(用于拖拽缩放等场景是有意为之);当希望超界值被截断在 range 边界内(如柱高不允许为负)时开启 clamp(true)。
copy():获得完全独立的副本
const scale1 = d3.scaleLinear()
.domain([0, 100])
.range([0, 500]);
const scale2 = scale1.copy();
// scale2 is independent of scale1
copy() 返回与当前尺度配置一致、但相互独立的实例;后续修改 scale2 的 domain/range 不会污染 scale1。
ticks() / tickFormat():为坐标轴生成刻度
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, 500]);
scale.ticks(10); // Generate ~10 ticks
scale.tickFormat(10); // Get format function for ticks
scale.tickFormat(10, ".2f"); // Custom format (2 decimal places)
// Time scale ticks
const timeScale = d3.scaleTime()
.domain([new Date(2020, 0, 1), new Date(2024, 0, 1)]);
timeScale.ticks(d3.timeYear); // Yearly ticks
timeScale.ticks(d3.timeMonth, 3); // Every 3 months
timeScale.tickFormat(5, "%Y-%m"); // Format as year-month
ticks(count) 尽量生成"数目接近但间隔整齐"的刻度值;tickFormat 返回格式化函数,可直接交给 d3.axisBottom() 等坐标轴生成器使用。时间尺度上还可传间隔常量(d3.timeYear、d3.timeMonth),并用 D3 时间格式符(如 %Y-%m)控制标签外观。
颜色空间插值:让渐变更符合感知(Colour spaces and interpolation)
默认情况下,scaleLinear 的 range 里放颜色字符串时会走 RGB 插值。D3 还允许用 .interpolate() 切换到 HSL、Lab、HCL 等颜色空间以获得不同观感:
const scale = d3.scaleLinear()
.domain([0, 100])
.range(["blue", "red"]);
// Default: RGB interpolation
// HSL interpolation —— smoother colour transitions
const scale = d3.scaleLinear()
.domain([0, 100])
.range(["blue", "red"])
.interpolate(d3.interpolateHsl);
// Lab interpolation —— perceptually uniform
const scale = d3.scaleLinear()
.domain([0, 100])
.range(["blue", "red"])
.interpolate(d3.interpolateLab);
// HCL interpolation —— perceptually uniform with hue
const scale = d3.scaleLinear()
.domain([0, 100])
.range(["blue", "red"])
.interpolate(d3.interpolateHcl);
- RGB:直接、快速,但中间色容易发灰、不按感知走。
- HSL:沿色相环走,过渡观感更"顺滑"。
- Lab / HCL:基于感知均匀的颜色空间,中间色更一致、不发灰,是制作高品质渐变的推荐选择。仓库
colour-schemes.md中的"自定义渐变色板"一节也延续这一思路,用.interpolate(d3.interpolateLab)构建感知均匀的自定义顺序/发散色板。
常见组合模式(Common patterns)
参考文档最后给出 5 个可直接复用、经过实战检验的组合模式,是理解"尺度如何协同"的最佳范本。
1. 带自定义中点的发散渐变
用三段 domain 加三色 range 表达"低—中—高"语义,并用 HCL 保证中性段不发灰:
const scale = d3.scaleLinear()
.domain([min, midpoint, max])
.range(["red", "white", "blue"])
.interpolate(d3.interpolateHcl);
2. 多停靠点(multi-stop)渐变
不只是两端点,可在中间任意位置定义颜色停靠点:
const scale = d3.scaleLinear()
.domain([0, 25, 50, 75, 100])
.range(["#d53e4f", "#fc8d59", "#fee08b", "#e6f598", "#66c2a5"]);
3. 圆形半径的感知校正
圆面积给人的感知与半径平方相关,因此必须用 scaleSqrt 而不是线性尺度来映射半径:
const radiusScale = d3.scaleSqrt()
.domain([0, d3.max(data, d => d.value)])
.range([0, 50]);
// Use with circles
circle.attr("r", d => radiusScale(d.value));
4. 依据数据跨度自适应选型
数据动态变化时,可根据数值范围跨越的数量级自动切换线性/对数尺度:
function createAdaptiveScale(data) {
const extent = d3.extent(data);
const range = extent[1] - extent[0];
// Use log scale if data spans >2 orders of magnitude
if (extent[1] / extent[0] > 100) {
return d3.scaleLog()
.domain(extent)
.range([0, width]);
}
// Otherwise use linear
return d3.scaleLinear()
.domain(extent)
.range([0, width]);
}
注意:该判断隐含了"数据全为正"的前提——若含 0 或负值需要先做平移或改用 scaleSymlog。
5. 显式分类色 + 未知值回退
为语义明确的风险/等级分类显式指定颜色(绿=低、橙=中、红=高),并补上 .unknown():
const colourScale = d3.scaleOrdinal()
.domain(['Low Risk', 'Medium Risk', 'High Risk'])
.range(['#2ecc71', '#f39c12', '#e74c3c'])
.unknown('#95a5a6'); // Fallback for unknown values
在可视化管线中的落点:从尺度到完整图表
尺度不是孤立概念,它总是服务于具体图表。仓库中该参考文档的实际用法是:Agent 在制作自定义可视化时按需读取。回顾 d3-viz/SKILL.md 的标准绘图流程,尺度始终占据承上启下的位置:
- 定义尺寸与 margin,得到
innerWidth/innerHeight; - 创建尺度:位置尺度用
d3.scaleLinear().domain(d3.extent(...)).range([0, innerWidth]),注意 y 轴需倒置range([innerHeight, 0])以匹配 SVG 坐标系;柱状图用scaleBand().padding(0.1);分类着色用scaleOrdinal(schemeCategory10); - 用尺度驱动坐标轴(
d3.axisBottom(xScale)/d3.axisLeft(yScale)); - 在 data join 中用尺度函数实时计算位置、宽度、半径、颜色。
配套的 d3-patterns.md 为柱状图、折线图、散点图、堆叠/分组柱状图、气泡图、树图、旭日图、弦图、热力图、等值区域图乃至 brush 联动、路径变形动画提供了可直接套用的代码模板;colour-schemes.md 则回答了"该用哪个色板、如何避免色盲陷阱"。
就本项目 OpenMontage(agentic 视频生产系统)而言,D3 图表技能服务于 data-visualization 技能所覆盖的"数据图表镜头/场景"——即把冷冰冰的数字转化为适合 16:9 视频画面的动态图表;而 remotion-composer/src/components/charts 下提供的 BarChart、LineChart、PieChart、KPIGrid 等动画组件则承载了成片中的最终渲染。上述关于 domain/range、带宽、倒置坐标、多序列着色的原则,在手动实现动画图表时同样成立。
常见坑位速查(Best practices)
结合参考文档与配套 SKILL 文档,把最容易出错的地方收敛成一张自查清单:
- domain 必须有效:坐标轴不出现,先查数据里是否有 NaN/undefined——
d3.extent对空数组返回[undefined, undefined],会导致尺度失效。 - log 尺度 domain 必须 >0:参考文档已特别标注(
scale-reference.md)。含 0 或负数时考虑平移或scaleSymlog。 - y 轴要倒置 range:SVG 坐标原点在左上角,
scaleLinear().range([innerHeight, 0])才能让"值越大 y 越小(越靠上)"。 - 圆的面积/半径用
scaleSqrt:半径与数值成线性会让大圆的面积"虚胖"。 - 序数尺度分类数量与色板容量匹配:超过 10~12 类时应考虑聚合为"Top N + Other",并配合
.unknown()兜底。 - 不要只用颜色传信息:8% 的男性存在红绿色觉障碍,重要差异应叠加形状、文字或线型等冗余编码(详见
colour-schemes.md中 Okabe-Ito 等色盲安全色板)。 - 更新图表时用
.join()而非反复清空重建:大量元素(>1000)考虑 Canvas 渲染,响应式尺寸交给 ResizeObserver。
速查对照表
需要完成某类映射时,可直接按此表定位上文对应小节:
| 需要做的事 | 推荐尺度 | 参考小节 |
|---|---|---|
| 定量数据 → 像素位置/长度 | scaleLinear |
连续尺度 · Linear |
| 时间序列 → 位置 | scaleTime |
连续尺度 · Time |
| 指数/数量级悬殊数据 | scaleLog / scaleSymlog |
连续尺度 · Log |
| 面积/半径感知校正 | scaleSqrt / scalePow |
连续尺度 · Power |
| 连续值切为 N 个等级 | scaleQuantize |
连续尺度 · Quantize |
| 分位数均匀分级 | scaleQuantile / scaleSequentialQuantile |
连续/序贯尺度 |
| 自定义断点分级 | scaleThreshold |
连续尺度 · Threshold |
| 连续数值 → 颜色渐变 | scaleSequential(interpolator) |
序贯尺度 |
| 正负/上下对照 → 颜色 | scaleDiverging(interpolator) |
序贯尺度 |
| 柱状图/单元格定位 | scaleBand().padding(...) |
序数尺度 · Band |
| 折线/散点分类横轴 | scalePoint() |
序数尺度 · Point |
| 分类 → 稳定颜色 | scaleOrdinal(scheme) |
序数尺度 · Ordinal |
| 让 domain 变"整"、截断越界、深拷贝、生成刻度 | .nice() / .clamp(true) / .copy() / .ticks() |
尺度工具函数 |
需要更深入的模式代码与配色建议时,可继续阅读同目录下的 d3-patterns.md(可视化模式模板)与 colour-schemes.md(色板与配色指南),两者与本文共同构成 OpenMontage d3-viz 技能中相互补充的三大参考资料。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00