ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

d3-format 数字格式化完全指南:格式说明符微型语言、Locale 与 SI 前缀在 d3 中的实战应用

d3-format 数字格式化完全指南:格式说明符微型语言、Locale 与 SI 前缀在 d3 中的实战应用 d3-format 数字格式化完全指南格式说明符微型语言、Locale 与 SI 前缀在 d3 中的实战应用【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3本文基于 d3 官方文档 d3-format 展开。d3-format 解决的是“把数字变成适合人类阅读的字符串”这一问题消除二进制浮点误差带来的0.30000000000000004、统一表格列宽、千分位分组、货币精度、科学计数与 SI 前缀、以及按地区locale适配分隔符。读完后你将掌握完整的格式说明符specifier语法、d3.formatLocale/d3.formatDefaultLocale的地区定义方式、formatPrefix的 SI 前缀机制以及precisionFixed/precisionRound/precisionPrefix三个精度推断工具并能理解它们在 d3 坐标轴刻度格式化等模块中的真实用途。一、问题背景为什么不能直接打印 JavaScript 数字d3-format 文档开篇用一个经典例子说明了问题所在for (let i 0; i 10; i) { console.log(0.1 * i); }输出是0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6000000000000001 0.7000000000000001 0.8 0.9这是 IEEE 754 双精度浮点表示的必然结果。d3 仓库中 d3-array/ticks.md 同样明确指出这一行为源自 IEEE 754 双精度浮点0.2 * 3 0.6000000000000001并建议“使用 d3-format 对数字做适合人类阅读的格式化Use d3-format to format numbers for human consumption with appropriate rounding”。除了舍入误差数字格式化还有更多动机表格中的数字应统一格式以便比较例如0.0优于0大数应做千分位分组42,000或使用科学计数 / SI 记法4.2e4、42k货币应固定精度$3.50统计结果应按有效数字舍入4021变为4000格式应适配读者地区42.000,00或42,000.00。d3-format 的设计借鉴了 Python 3 的 format specification mini-languagePEP 3101。重新审视上面的例子const f d3.format(.1f); for (let i 0; i 10; i) { console.log(f(0.1 * i)); }输出变为干净的0.0到0.9。二、d3-format 在 d3 仓库中的位置当前仓库d3 7.9.0是一个 monorepo 风格的总包d3-format作为独立依赖^3.1.0声明在 package.json 中并在 src/index.js 中通过export * from d3-format;全量再导出因此安装 d3 后即可直接使用d3.format等全部 API无需单独引入 d3-format。docs/api.md 中对 d3-format 的条目索引也列出了d3.format、d3.formatPrefix、d3.formatSpecifier、d3.precisionFixed、d3.precisionPrefix、d3.precisionRound、d3.formatLocale、d3.formatDefaultLocale这些方法。需要说明的是d3-format 的源码如src/locale.js、src/formatSpecifier.js位于独立的 d3-format 依赖中当前仓库不包含其实现文件本文所有 API 语义均以 docs/d3-format.md 的官方描述为准。三、d3.format基础格式化器d3.format(specifier)是默认地区上locale.format的别名。返回一个格式化函数接受一个数字返回格式化后的字符串const f d3.format(.2f);文档给出的示例集覆盖了常见场景以下注释即文档标注的期望输出d3.format(.0%)(0.123) // 舍入的百分比12% d3.format(($.2f)(-3.5) // 本地化定点货币(£3.50) d3.format(20)(42) // 空格填充且带符号 42 d3.format(.^20)(42) // 点填充且居中.........42......... d3.format(.2s)(42e6) // 两位有效数字的 SI 前缀42M d3.format(#x)(48879) // 带前缀的小写十六进制0xbeef d3.format(,.2r)(4223) // 千分位分组加两位有效数字4,200文档同时提醒可以用d3.formatSpecifier对上述任意说明符做解码查看每个字段被解析成什么见第六节。四、格式说明符的完整语法locale.format(specifier)及d3.format别名接受一个字符串说明符其通用形式为[[fill]align][sign][symbol][0][width][,][.precision][~][type]4.1 fill 与 alignfill可以是任意字符其存在由紧随其后的align字符来标识。align必须是以下之一— 右对齐默认行为— 左对齐^— 居中— 与类似但符号和货币符号位于填充之前。4.2 sign-— 零或正数无符号负数用减号默认行为— 零或正数用加号负数用减号(— 零或正数无符号负数用圆括号空格— 零或正数用空格负数用减号。一个值得注意的仓库事实CHANGES.md 记载在 d3 v7 中d3.format对负值的默认负号从连字符hyphen-minus改为了真正的减号minus sign这是 v7 的行为变更之一。4.3 symbol$— 按地区定义应用货币符号#— 用于二进制、八进制、十六进制分别加0b、0o、0x前缀。4.4 zero、width 与逗号0选项启用零填充它会隐式地把fill设为0、align设为。width定义最小字段宽度不指定时由内容决定宽度。,选项启用分组分隔符如千位逗号。4.5 precision 的语义重要precision的含义取决于type对类型f和%precision 表示小数点后的位数对类型 none、e、g、r、s、pprecision 表示有效数字的位数。未指定 precision 时除 none 类型默认为 12 外其他类型均默认为 6。整数格式b、o、d、x、X和字符类型c会忽略 precision。4.6~修剪选项~选项在所有格式类型中修剪无意义的末尾零最常与r、e、s、%配合使用d3.format(s)(1500) // 1.50000k d3.format(~s)(1500) // 1.5k4.7 type 类型总表type含义e指数记法f定点记法g小数或指数记法按有效数字舍入r十进制记法按有效数字舍入s带 SI 前缀的十进制记法按有效数字舍入%乘以 100十进制记法加百分号p乘以 100按有效数字舍入十进制记法加百分号b二进制记法舍入到整数o八进制记法舍入到整数d十进制记法舍入到整数x十六进制小写字母舍入到整数X十六进制大写字母舍入到整数c字符数据用于文本字符串此外类型 none是~g的简写默认 precision 为 12而非 6类型n是,g的简写对g、n和 none 类型若结果字符串的位数不超过 precision 则用小数记法否则用指数记法d3.format(.2)(42) // 42 d3.format(.2)(4.2) // 4.2 d3.format(.1)(42) // 4e1 d3.format(.1)(4.2) // 4五、formatPrefix一致的 SI 前缀格式化d3.formatPrefix(specifier, value)是默认地区上locale.formatPrefix的别名const f d3.formatPrefix(,.0, 1e-6);它返回一个格式化器在按定点记法格式化之前先将数值换算到与参考数值value相匹配的 SI 前缀单位。支持的完整前缀列表为前缀名称量级yyocto10⁻²⁴zzepto10⁻²¹aatto10⁻¹⁸ffemto10⁻¹⁵ppico10⁻¹²nnano10⁻⁹µmicro10⁻⁶mmilli10⁻³none—10⁰kkilo10³Mmega10⁶Ggiga10⁹Ttera10¹²Ppeta10¹⁵Eexa10¹⁸Zzetta10²¹Yyotta10²⁴与s类型的关键区别在于formatPrefix返回的是一致的 SI 前缀——所有数值共用同一前缀而不是像s类型那样为每个数字动态计算前缀specifier 中的 precision 含义变为小数点后的位数类似f而非有效数字位数。const f d3.formatPrefix(,.0, 1e-6); f(0.00042); // 420µ f(0.0042); // 4,200µ这使得同一单位下的多个数字可以直接比较。CHANGES.md 中还记录了这一 API 的历史演进d3 v4 起d3.formatPrefix由“返回一个 SI 前缀字符串”改为“返回给定 specifier 和参考 value 的 SI 前缀格式化函数”例如d3.formatPrefix(,.0, 1e3)用来格式化千级数字——强调与s指令不同它始终采用同一个 SI 前缀产生一致的结果。仓库中的真实用例文档站示例 ExampleChord.vue 展示了formatPrefix的典型用法先由d3.tickStep(0, sum, 100)计算刻度步长再用它同时作为 SI 前缀的参考值和刻度间距const tickStepMinor d3.tickStep(0, sum, 100); const formatValue d3.formatPrefix(,.0, tickStepMinor);格式化后的formatValue(d.value)直接渲染到弦图的刻度文本上ExampleChord.vue。这是一个“刻度步长决定单位单位决定格式化器”的完整闭环。六、formatLocale 与 formatDefaultLocale地区定义6.1 formatLocale(definition)const enUs d3.formatLocale({ thousands: ,, grouping: [3], currency: [$, ] });返回一个locale对象带有locale.format和locale.formatPrefix两个方法。definition必须包含decimal— 小数点如.thousands— 分组分隔符如,grouping— 分组长度数组如[3]按需循环使用currency— 货币前缀和后缀如[$, ]numerals— 可选十个字符串用于替换数字 0–9percent— 可选百分号默认%minus— 可选减号默认−nan— 可选非数值默认NaN。注意文档的提醒thousands属性其实是个“误称”因为 grouping 定义允许非千位分组的分组方式。6.2 formatDefaultLocale(definition)const enUs d3.formatDefaultLocale({ thousands: ,, grouping: [3], currency: [$, ] });与d3.formatLocale等价额外会把d3.format和d3.formatPrefix重新指向新地区的locale.format/locale.formatPrefix。若从未设置默认地区则默认使用美式英语U.S. English定义。七、formatSpecifier 与 new FormatSpecifier解码与派生说明符7.1 formatSpecifier(specifier)d3.formatSpecifier(.1f)解析说明符字符串返回一个字段对应格式微型语言各组成部分、并带toString()方法可重建说明符的对象。例如formatSpecifier(s)返回FormatSpecifier { fill: , align: , sign: -, symbol: , zero: false, width: undefined, comma: false, precision: undefined, trim: false, type: s }这个方法的两大用途理解说明符是如何被解析的以及派生新的说明符。例如用precisionFixed计算出合适精度后动态构建新格式const s d3.formatSpecifier(f); s.precision d3.precisionFixed(0.01); const f d3.format(s); f(42); // 42.00;注意最后一步直接把 specifier 对象传给了d3.format——toString()重建说明符字符串的机制在此生效。7.2 new d3.FormatSpecifier(specifier)new d3.FormatSpecifier({type: f, precision: 1})接受一个说明符对象而非字符串返回同样带toString()的 FormatSpecifier。new FormatSpecifier({type: s})的返回结构与上面formatSpecifier(s)相同。这是从对象字段直接构造说明符的入口。八、精度推断三件套precisionFixed / precisionPrefix / precisionRound这三个方法都用于“根据你的数据自动选择合适的 precision”前提是待格式化的值本身是 step 的整数倍。8.1 precisionFixed(step)给定定点记法的步长step即待格式化值之间的最小绝对差返回建议的小数 precisiond3.precisionFixed(0.01) // 2对数字 1、1.5、2step 应为 0.5建议 precision 为 1const p d3.precisionFixed(0.5); const f d3.format(. p f); f(1); // 1.0 f(1.5); // 1.5 f(2); // 2.0而对 1、2、3step 为 1建议 precision 为 0const p d3.precisionFixed(1); const f d3.format(. p f); f(1); // 1 f(2); // 2 f(3); // 3注意对%类型需要减 2const p Math.max(0, d3.precisionFixed(0.05) - 2); const f d3.format(. p %); f(0.45); // 45% f(0.50); // 50% f(0.55); // 55%8.2 precisionPrefix(step, value)d3.precisionPrefix(1e5, 1.3e6) // 1给定step和参考value决定使用哪个 SI 前缀返回配合formatPrefix的建议小数 precision。对数字 1.1e6、1.2e6、1.3e6step 取 1e5value 可取 1.3e6建议 precision 为 1const p d3.precisionPrefix(1e5, 1.3e6); const f d3.formatPrefix(. p, 1.3e6); f(1.1e6); // 1.1M f(1.2e6); // 1.2M f(1.3e6); // 1.3M8.3 precisionRound(step, max)d3.precisionRound(0.01, 1.01) // 3给定step和max待格式化值的最大绝对值返回按有效数字舍入类型如r的建议 precision。对 0.99、1.0、1.01step 为 0.01、max 为 1.01建议 precision 为 3const p d3.precisionRound(0.01, 1.01); const f d3.format(. p r); f(0.99); // 0.990 f(1.0); // 1.00 f(1.01); // 1.01而对 0.9、1.0、1.1step 为 0.1、max 为 1.1建议 precision 为 2const p d3.precisionRound(0.1, 1.1); const f d3.format(. p r); f(0.9); // 0.90 f(1.0); // 1.0 f(1.1); // 1.1注意对e类型需要减 1const p Math.max(0, d3.precisionRound(0.01, 1.01) - 1); const f d3.format(. p e); f(0.01); // 1.00e-2 f(1.01); // 1.01e0九、d3-format 在 d3 生态中的实际协作方式d3-format 并不是孤立使用的仓库文档中有两处体现它与坐标轴 / 比例尺模块的协作坐标轴的刻度格式化docs/d3-axis.mdaxis.tickFormat(format)可直接传入 d3-format 的格式化器axis.tickFormat(d3.format(,.0f));文档进一步指出更常见的做法是把格式说明符传给axis.ticks(count, format)这样精度会基于刻度间距自动设置axis.ticks(10, ,f);若不设置显式 tickFormat轴会回落到比例尺的默认tickFormat。比例尺的刻度格式docs/d3-scale/linear.md*linear*.tickFormat(count, specifier)内部正是结合precisionFixed类方法与d3.formatSpecifier派生说明符——precisionFixed/precisionRound的文档也明确说明这些方法“被 d3-scale 用于刻度格式化”。刻度值的舍入docs/d3-array/ticks.mdd3-array 的 tick 生成因 IEEE 754 可能产生浮点噪声文档明确指向 d3-format 作为“对人类友好”的展示层解决方案。由此可以推断出一条清晰的分层d3-array 负责生成“数学上正确”的刻度值d3-scale 负责生成“默认合理”的刻度格式器d3-format 则提供底层的全部格式化原语d3-axis 在渲染时消费这些格式器。十、快速参考与适用前提API作用关键参数d3.format(specifier)默认地区格式化器说明符字符串d3.formatPrefix(specifier, value)一致 SI 前缀格式化器说明符 参考值precision 为小数位数d3.formatLocale(definition)创建地区对象format formatPrefixdecimal/thousands/grouping/currency 等d3.formatDefaultLocale(definition)创建地区并重定义d3.format别名同上d3.formatSpecifier(specifier)解析说明符为对象字符串new d3.FormatSpecifier(obj)由对象构造说明符{type, precision, ...}d3.precisionFixed(step)定点记法建议精度值的最小绝对差d3.precisionPrefix(step, value)formatPrefix 建议精度步长 参考值d3.precisionRound(step, max)有效数字记法建议精度步长 最大绝对值适用前提与限制当前仓库为 d3 7.9.0d3-format 版本为^3.1.0见 package.jsond3.format对负值默认使用减号minus sign而非连字符这是 v7 的行为精度推断三件套均假设“待格式化的值本身是 step 的整数倍”否则建议值可能不适用formatPrefix与s类型的 precision 语义不同小数位数 vs 有效数字位数混用 specifier 时容易出错可用d3.formatSpecifier解码核对自定义数字字形如全角数字通过 definition 的numerals数组替换 0–9 实现。深入阅读建议从 docs/d3-format.md 原文、docs/api.md 的总索引以及 docs/d3-axis.md 和 docs/components/ExampleChord.vue 中的两处真实格式化用法入手。【免费下载链接】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),仅供参考
返回列表