首页
/ d3-fetch 数据加载 API 详解:d3 7.9.0 中一行代码加载并解析 CSV、JSON 与二进制文件

d3-fetch 数据加载 API 详解:d3 7.9.0 中一行代码加载并解析 CSV、JSON 与二进制文件

2026-09-04 17:56:37作者:胡唯隽

本文以当前仓库(d3 v7.9.0)中的 docs/d3-fetch.md 文档为主体,完整讲解 d3-fetch 模块提供的全套数据文件加载 API:如何基于 Fetch 用一行 await 加载文本、JSON、CSV/TSV、SVG/HTML/XML、图片与二进制文件,以及 initrow 两个可选参数的用法细节。读完本文,你不仅能掌握全部 11 个加载函数的签名与适用场景,还能理解它们在本仓库文档站点中被实际调用的方式,并知道 row 转换函数、CSP 限制、204/205 响应等边界情况的正确处理方式。

模块定位:在 Fetch 之上的便捷解析层

d3-fetch 是 d3 主包中的一个独立子模块,其官方定义是"在浏览器/平台标准 Fetch API 之上提供便捷的文件解析"(模块说明)。它解决的痛点是:原生 fetch 只返回 Response 对象,你还要手动 await response.text()JSON.parse、解析 CSV……而 d3-fetch 把"取回 + 解析"合并成一步,例如加载文本文件:

const text = await d3.text("hello-world.txt"); // "Hello, world!"

加载并解析 CSV 文件:

const data = await d3.csv("hello-world.csv"); // [{"Hello": "world"}, …]

该模块内置对 JSON、CSV、TSV 三种格式的解析支持;其它格式(如纯文本、自定义结构)可以先用 d3.text 取回字符串再自行解析。文档中特别注明:d3-fetch 取代了旧的 d3-request 模块,因此在新代码中应优先使用本模块而非 d3.request / d3.json() 回调风格。

在当前仓库中可以确认它的装配方式:

  • package.json 中主包 d3 版本为 7.9.0,依赖声明为 "d3-fetch": "^3.0.1",说明本文档对应的 API 形态适用于 d3 v7 系列(基于 ES Module,函数返回 Promise,须配合 async/await.then 使用);
  • src/index.jsexport * from "d3-fetch"; 将全部 API 原样重导出,因此安装 d3 主包后即可直接使用 d3.csv 等函数,无需单独引入。
{
  "name": "d3",
  "version": "7.9.0",
  "dependencies": { "d3-fetch": "^3.0.1", "…": "…" }
}

安装方式(只涉及标准 npm 安装,与仓库 package.json 声明一致):

npm install d3

全部加载 API 一览:blob、buffer、csv、dsv、html、image、json、svg、text、tsv、xml

官方文档 共定义了 11 个顶层函数,下面按功能分组完整覆盖。所有函数都接受 input(URL 字符串)与可选的 init 参数;除 dsv/csv/tsv 额外接受 row 外,init 会原样传递给底层 fetch 调用,因此可以使用任何 RequestInit 允许的字段(如 headersmethodsignal 等)。

文本与 JSON

d3.text(input, init) — 获取指定 URL 的文本文件,Promise 解析为字符串。

const text = await d3.text("example.txt");

d3.json(input, init) — 获取并解析 JSON 文件。有一个重要边界行为:当服务器返回 204 No Content 或 205 Reset Content 状态码时,Promise 解析为 undefined(而不是空对象或抛错),在后续代码中应做判空处理。

const data = await d3.json("example.json");

分隔符文件:csv、tsv、dsv

d3.csv(input, init, row) — 等价于以逗号 , 为分隔符调用 d3.dsv

const data = await d3.csv("example.csv");

d3.tsv(input, init, row) — 等价于以制表符 \t 为分隔符调用 d3.dsv

const data = await d3.tsv("example.tsv");

d3.dsv(delimiter, input, init, row) — 通用入口,可指定任意单字符分隔符(管道符、分号等)。

const data = await d3.dsv(",", "example.csv");

dsvrow 转换函数(以及 init/row 的位置判定规则)是三个函数中最核心的实战细节,下一节单独展开。

结构化文档:html、svg、xml

这三个函数实现相同:先以 d3.text 取回文件内容,再用 DOMParser 解析为文档对象。区别仅在于解析时的文档类型:

d3.html(input, init) — 解析为 HTML 文档。

const document = await d3.html("example.html");

d3.svg(input, init) — 解析为 SVG 文档,配合 d3.select / 文档片段操作可把远程 SVG 挂入页面。

const document = await d3.svg("example.svg");

d3.xml(input, init) — 解析为 XML 文档。

const document = await d3.xml("example.xml");

图片与二进制

d3.image(input, init) — 加载图片(HTMLImageElement)。与其它函数不同,这里的 init 不是传给 fetch,而是在图片加载前把额外属性设置到 img 元素上。典型用途是开启匿名跨域请求(CORS image):

const image = await d3.image("https://example.com/image.png", {crossOrigin: "anonymous"});

d3.blob(input, init) — 将 URL 指向的二进制文件作为 Blob 获取。

const blob = await d3.blob("example.db");

d3.buffer(input, init) — 将二进制文件作为 ArrayBuffer 获取,适合直接交给 TypedArray 或文件解析库处理。

const buffer = await d3.buffer("example.db");

深入 dsv:init 与 row 的参数判定规则

d3.dsv(以及 d3.csvd3.tsv)的签名是 (delimiter, input, init, row),其中 initrow 都是可选的。官方文档明确规定了当只传其中一个可选参数时的判定规则

如果 initrow 只指定了一个,若它是函数则解释为 row 转换函数,否则解释为 init 对象

也就是说,以下两种写法完全等价,第二个参数位置既可以是配置对象也可以是转换函数:

// row 以函数身份占据第三个参数
const data = await d3.dsv(",", "example.csv", (d) => {
  return {
    year: new Date(+d.Year, 0, 1), // convert "Year" column to Date
    make: d.Make,
    model: d.Model,
    length: +d.Length             // convert "Length" column to number
  };
});

// init 以对象身份占据第三个参数(例如带请求头)
const data = await d3.dsv(",", "example.csv", {headers: {"X-Token": "…"}});

row 转换函数对每一行被调用,接收当前行对象 d(以表头为属性名)、行索引 i 和列名数组;若返回 nullundefined,该行被过滤掉。这一语义与底层 d3-dsv 模块的 *dsv*.parse 完全一致——d3-fetchd3.csv 本质是 fetch 拿到字符串后委托给 d3-dsv 的解析器。

row 函数与 d3.autoType 的组合

官方 d3-dsv 文档 提供了现成的行转换函数 d3.autoType:对每个字段先 trim,再按"空→null"true"/"false"→布尔、"NaN"NaN、可转数字→数字、ISO 日期串→Date、否则保持字符串"的规则推断类型。作为 row 传入时,一行 CSV 即可得到类型正确的对象:

const data = await d3.csv("example.csv", d3.autoType);

需要手动控制转换(例如把年份列转成 Date、把长度列转成数字)时,就自行编写 row 函数,如上节示例。注意官方对强制转换的建议:优先用 +Number 而非 parseInt/parseFloat(更快但更严格,"30px"+ 会得到 NaN)。

两个需要注意的实现细节

  1. 列名顺序与 columns 属性:解析结果的数组额外带有 columns 属性(按输入顺序的列名),与 Object.keys 的迭代顺序不同;若存在重名列,parse 语义下每个名称只保留最后一个值,此时应改用 parseRows 思路处理(见 docs/d3-dsv.md)。
  2. Content Security Policy*dsv*.parse 因使用动态代码生成来加速解析,要求 script-src 中含 unsafe-eval;在严格 CSP 环境下可改用 parseRows 系列或自行解析(d3-dsv 文档说明)。

本仓库中的真实调用:文档站点如何加载数据

当前仓库本身就是一组 d3-fetch 的活示例——文档站点(VitePress,数据文件放在 docs/public/data/ 下)在多篇文档中直接调用这些 API:

d3.csv 加载 CSV 并自动转型docs/d3-shape/stack.md):

d3.csv("../data/riaa-us-revenue.csv", d3.autoType).then((data) => (riaa.value = data));

对应的真实数据文件 docs/public/data/riaa-us-revenue.csv 结构为:

format,group,year,revenue
8 - Track,Tape,1973-01-01,2815.68
8 - Track,Tape,1974-01-01,2848.01

可见 d3.autoType 会把 year 列(ISO 日期串 1973-01-01)推断为 Daterevenue 列推断为数字,这正是上一节 autoType 规则的实际体现。注意这里用的是相对当前 HTML 页面的路径../data/…),而 d3.csv("lost.csv", d3.autoType)docs/d3-shape/pie.md)则是相对于页面所在的短路径——URL 解析遵循浏览器标准 URL 规则,写代码时要先确认文档页面位于哪个目录。

d3.json 加载 JSONdocs/components/ExampleDisjointForce.vue):

const dataPromise = d3.json("https://static.observableusercontent.com/files/e3680d5f…");

仓库自带的 docs/public/data/volcano.json{"width":87,"height":61,"values":[…]} 结构的二维数值矩阵)就是典型的 d3.json 消费对象,配合 d3.contours 或色标渲染等高线。

以上调用同时印证了 d3-fetch 与文档体系的分层关系:d3-fetch 负责"取回 + 解析",解析后的数组/对象再交给 d3-scaled3-shape 等模块做可视化,这也是 d3 主包 src/index.js 将各子模块并列重导出的设计意图。

进阶用法:init 透传与错误处理

用 init 透传 fetch 配置

d3.image 外,所有函数的 init 都原样透传给底层 fetch,因此可以携带自定义请求头、控制请求方法、传入 AbortSignal 等:

// 携带鉴权头加载私有 JSON
const data = await d3.json("/api/report.json", {headers: {"Authorization": "Bearer …"}});

// 可取消的请求
const controller = new AbortController();
const textPromise = d3.text("large.txt", {signal: controller.signal});
controller.abort(); // 中止请求

空响应的特殊约定

再次强调 d3.json 的边界行为:服务器返回 204 No Content205 Reset Content 时,Promise 解析为 undefined。健壮的数据加载代码通常写成:

const data = (await d3.json("example.json")) ?? [];

其余非 2xx 状态会走 fetch 的标准 reject 路径(网络错误、HTTP 错误由你自行 .catchtry/catch 处理)。

选型速查

目标格式 推荐函数 返回类型 备注
纯文本 d3.text string 其它格式的兜底取数方式
JSON d3.json 对象/数组 204/205 时解析为 undefined
CSV / TSV / 其它 DSV d3.csv / d3.tsv / d3.dsv columns 的行对象数组 支持 row 转换,配合 d3.autoType 转型
HTML / SVG / XML d3.html / d3.svg / d3.xml 文档对象 先 text 后 DOMParser 解析
图片 d3.image HTMLImageElement init 用于设置 img 属性(如 crossOrigin
二进制文件 d3.blob / d3.buffer Blob / ArrayBuffer 交给 TypedArray、文件解析库或 <a download>

小结

d3-fetch 以极小的 API 面(11 个函数)覆盖了 d3 数据管道的前端——"把数据取回来并解析成可用的 JavaScript 结构"。掌握本文的三个要点即可应对绝大多数场景:所有加载函数都返回 Promise、initd3.image 外均可透传给 fetchd3.csv/tsv/dsv 的第三个参数按"函数即 row、对象即 init"的自动判定规则工作。完整的逐函数说明见 docs/d3-fetch.md,DSV 解析细节(parseRowsformatautoType、BOM 处理)见 docs/d3-dsv.md,真实数据样例可参考 docs/public/data/riaa-us-revenue.csvdocs/public/data/volcano.json

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384