实战指南:scalePow / scaleSqrt 与 y = mx^k + b 映射模型)
d3 幂标度Power Scale实战指南scalePow / scaleSqrt 与 y mx^k b 映射模型【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3本文基于 d3 官方文档 docs/d3-scale/pow.md 展开讲解 d3 中 Powerpow标度的数学模型、scalePow/scaleSqrt两个构造函数的默认值与用法、exponent指数的 getter/setter 语义并结合当前 d3 仓库的模块组织与 API 清单说明幂标度在宽范围定量数据场景下的选型依据与可复现代码。读完本文你将能够正确配置幂标度完成位置、颜色等视觉编码并理解它与 linear、log、symlog 标度的边界差异。一、什么是 Power 标度y mx^k b 映射模型Powerpow标度与 linear 标度 的思路一致——将连续定量输入域映射到连续输出值域——区别在于在计算输出之前先对输入域值施加一个指数power变换。每个范围值y都可以表示为域值x的函数y m · x^k b其中k是 exponent 指数值。m、b 是由 domain/range 决定的线性系数k 则是可调的形变参数。当k 1时指数变换退化为恒等变换pow 标度在数学上就等效于一个 linear 标度——这是文档中明确给出的性质见下文 exponent 一节。k 1如 0.5 开平方会压缩大值、放大小值k 1如 2 平方则反过来拉伸大值。这正是它适用于宽范围定量数据的原因原始数据跨度大、小值差异被大值淹没时用 k 1 的变换可以把低值区域的细节撑开。d3 官方 d3-scale 总览文档 对各类标度的定位也印证了这一点Pow scales —— for quantitative data (that has a wide range)Log scales / Symlog scales —— 同样面向宽范围定量数据但变换模型不同见 log、symlog 文档负域值的支持规则pow 标度支持负的 domain 值此时文档明确说明输入值与得到的输出值会同时乘以 -1即对绝对值做变换后再恢复符号。这一点与 log 标度形成对比——log 标度的 domain 必须严格全正或全负、不能跨越零因为 log(0) -∞而 pow 标度天然能处理零附近乃至全负的数据这是两者选型时的一个关键区别。二、scalePow(domain, range)通用幂标度构造函数文档锚点#scalePow见 docs/d3-scale/pow.md。构造一个新的 pow 标度指定 domain 与 range并给出如下初始状态exponent 默认为 1即初始时等效线性interpolator 默认为 d3.interpolated3-interpolate 的通用值插值器工厂clamp截断默认关闭。const x d3.scalePow([0, 100], [red, blue]).exponent(2);如果domain或range未指定二者各自默认为 [0, 1]。参数与默认值速查标度domain 默认range 默认exponent 默认clamp 默认interpolator 默认d3.scalePow[0, 1][0, 1]1关闭d3.interpolated3.scaleSqrt[0, 1][0, 1]0.5关闭d3.interpolate实战示例位置编码与颜色编码位置编码sqrt 压缩宽范围数值import * as d3 from d3; // 把 0–10000 的数值域按开平方映射到 0–960 像素 const x d3.scaleSqrt([0, 10000], [0, 960]); x(100); // 96 sqrt(100)10占满域的 10%即 96px x(400); // 192 x(10000); // 960对照 linear 标度d3.scaleLinear([0, 10000], [0, 960])线性下 100 只占 9.6px、400 只占 38.4px——sqrt 变换让小值在坐标轴上获得了明显更大的可视空间宽范围数据的低值区间细节因此更易读。颜色编码指数拉伸色带// 二次幂颜色标度靠近 0 的区域颜色变化平缓靠近 100 的区域急剧变蓝 const color d3.scalePow([0, 100], [red, blue]).exponent(2); color(10); // 红色附近变化很小 color(90); // 已快速趋近蓝色颜色类的 range 依赖标度内部的 interpolator 在相邻 range 值之间插值机制与 linear 标度的linear.interpolate 完全一致因此同样可以换成 HCL / Cubehelix 等色彩空间插值器如d3.interpolateHcl参考 d3-interpolate 颜色插值const color d3.scalePow([0, 100], [red, blue]) .exponent(2) .interpolate(d3.interpolateHcl);负域值示例绝对值变换 符号恢复// domain 全为负值时输入与输出均乘以 -1 参与变换 const x d3.scaleSqrt([-10000, -100], [960, 0]);从文档描述看其内部行为是对绝对值应用幂变换、再按规则恢复符号实际调试时以仓库对应 d3-scale 版本的运行时行为为准。三、scaleSqrt(domain, range)开平方快捷构造函数文档锚点#scaleSqrt。构造一个 pow 标度语义与scalePow完全相同唯一区别是exponent 固定初始化为 0.5const x d3.scaleSqrt([0, 100], [red, blue]);domain / range 未指定时同样各自默认 [0, 1]它是d3.scalePow(…).exponent(0.5)的便捷等价方法文档原文如此表述。开平方标度最典型的用途是面积类视觉通道人眼感知的是圆的面积而非半径若想让感知面积 ∝ 数据值就必须让半径 ∝ sqrt(值)此时应使用scaleSqrt。例如气泡图中const r d3.scaleSqrt(d3.extent(data, d d.area), [0, 40]); // circle r{r(d.area)}面积与 d.area 成正比注意区分radial 标度d3.scaleRadial是线性标度且 range 内部先平方同样用于面积-半径对应但它作用于位置半径且不支持自定义 interpolator而scaleSqrt是 pow 标度家族成员指数、颜色 range、截断等行为都与scalePow一致。四、pow.exponent(exponent)指数的 getter / setter文档锚点#pow_exponent。指定参数时把标度当前指数设为该数值并返回 this可链式调用。const x d3.scalePow([0, 100], [red, blue]).exponent(2);不指定参数时返回当前指数默认值为 1。x.exponent(); // 2k 1 的退化性质文档明确说明——当exponent为 1 时pow 标度在效果上就是一个 linear 标度。因此在实践中想微调曲率可以只改exponent如 0.8 ~ 1.2 区间无需切换标度类型需要严格线性基线做 A/B 对比时把 exponent 设回 1 即可。五、共享连续标度接口domain / range / invert / clamp 等pow 标度建立在 d3-scale 的 continuous scale 机制之上原始文档中对其 domain、range、interpolator、clamp 的引用全部指向 linear 标度文档的对应条目因此这些通用方法的语义可直接复用 linear 文档的定义方法语义以 linear 文档为准文档位置domain(d)/domain()设置/读取输入域数组≥2 个元素非数字会被强制转换linear#domainrange(r)/range()设置/读取输出值域数组元素类型由 interpolator 决定linear#rangerangeRound(r)range interpolateRound数值 range 专用linear#rangeRoundinterpolate(f)设置相邻 range 值之间的插值器工厂默认d3.interpolatelinear#interpolateclamp(c)是否把结果截断在 range 内默认关闭linear#clampunknown(v)指定 undefined / NaN 输入时的输出linear#unknowninvert(y)数值 range 下反解域值用于交互如鼠标位置→数据值linear#invertticks(count)/tickFormat(count, s)约 count 个均匀刻度 自动精度格式化linear#ticks、linear#tickFormatnice(count)将域扩展为整齐值linear#nicecopy()返回完全独立的副本linear#copy两点使用提醒继承自 linear 文档的 CAUTION默认插值器可能复用返回值若 range 是对象插值器会原地修改并返回同一对象。用于直接设置属性/样式没问题若需保存返回值请自行指定插值器或拷贝invert 要求数值 range颜色等非数值 range 调invert会得到 NaN。六、在当前 d3 仓库中的定位从源码结构看本仓库是 d3 主包package.json 中version为 7.9.0它不内联标度实现而是通过 src/index.js 对子模块做聚合再导出export * from d3-scale; // src/index.js 第 22 行package.json 声明d3-scale: ^4.0.2即d3.scalePow、d3.scaleSqrt的实现位于 d3-scale 4.x对应上游src/pow.js文档中给出的 Source 链接指向该文件。仓库内可用于检索与验证的相关材料docs/api.md 的全量 API 清单列出了本主题三个入口d3.scalePowcreate a quantitative power scale、d3.scaleSqrtexponent 0.5 的定量 power scale、*pow*.exponentset the power exponent同一家族的颜色端幂标度sequential 中的scaleSequentialSqrtexponent 0.5 的 power sequential scale与 diverging 中的scaleDivergingSqrt——它们是顺序/发散颜色标度上的开平方变体与本文讲的可映射任意值域的scaleSqrt分属不同接口不要混用文档站本地构建可用 package.json 中的docs:dev/docs:build脚本VitePressdocs/ 目录。七、选型速查pow vs log vs symlog三者都面向宽范围定量数据见 d3-scale 总览差异在于变换模型与定义域约束标度变换定义域约束适用场景powy m·x^k b支持负值符号翻转规则可跨零需要可调曲率 k数据含 0 或全负时优先logy m·log(x) b必须全正或全负不能跨零log(0) -∞数据严格正值且跨多个数量级symlog分段对称对数可跨零数据有正有负且跨度大一个可操作的决策路径数据跨度 ≤ 2~3 个数量级、分布大致均匀 → 直接用 scaleLinear必要时.nice()数据全正、跨多个数量级 →scaleLog数据跨零、需要压缩大值 →scalePow配合exponent(0.5)即scaleSqrt视觉通道是面积气泡/地图圆圈→ 优先scaleSqrt保证感知面积 ∝ 数值需要精确反解交互invert→ 确认 range 为数值pow 标度同样支持。八、可复现的最小示例以下代码在当前 d3 版本d3-scale 4.x下可直接运行覆盖了文档中的全部核心 APIimport * as d3 from d3; // 1) 构造函数 默认值 const a d3.scalePow(); // domain [0,1], range [0,1], exponent 1 a.exponent(); // 1 // 2) 链式设置指数文档原例 const x d3.scalePow([0, 100], [red, blue]).exponent(2); x.exponent(); // 2 x(50); // 颜色插值结果t0.5 处 // 3) sqrt 快捷方式文档原例 const s d3.scaleSqrt([0, 100], [red, blue]); // 等价于 d3.scalePow([0,100], [red,blue]).exponent(0.5) // 4) 数值 range invert继承自连续标度语义 const px d3.scaleSqrt([0, 10000], [0, 960]); px(100); // 96 px.invert(96); // 100总结Power 标度 linear 标度 可调指数变换。记住三件事即可用好它① 数学形式y mx^k bk 由exponent()控制且默认 1k1 即线性②scaleSqrt只是 exponent 为 0.5 的快捷构造默认 domain/range 均为 [0,1]、clamp 默认关闭③ 它支持负域值输入输出同乘 -1 的变换规则这使它成为跨零宽范围数据上最常用的宽范围标度。【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考