Skip to content

D3.js - 请求 API

可视化是数据驱动的。D3.js 提供了方便的方法来加载外部数据,例如 CSV、TSV、JSON 和纯文本文件。现代 D3 使用 d3-fetch 模块,它构建在浏览器标准的 Fetch API 之上,并利用 Promises 进行异步操作。这取代了旧的 d3-request 模块。

d3-fetch 模块包含在 D3 主包中。如果你单独使用 D3 模块,可以安装 d3-fetch。

<!-- 引入完整的 D3 库 (包含 d3-fetch) -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
// 示例:加载 JSON 文件
// d3.json("/path/to/data.json")
// .then(data => {
// console.log(data);
// })
// .catch(error => {
// console.error("加载数据出错:", error);
// });
</script>

d3-fetch 方法返回 Promises,这使得处理异步数据加载更加清晰和健壮。你可以使用 .then() 处理成功响应,.catch() 处理错误,或者使用 async/await 语法。

以下是 d3-fetch 提供的主要方法:

  • d3.blob(url[, init]) − 将指定 url 的文件作为 Blob 获取。init 是一个可选对象,包含 fetch 选项(例如,headers, method)。
  • d3.buffer(url[, init]) − 将指定 url 的文件作为 ArrayBuffer 获取。
  • d3.csv(url[, initOrRowConverter[, rowConverter]]) − 获取指定 url 的 CSV 文件,解析它,并返回一个解析为对象数组的 Promise。可以提供一个可选的 rowConverter 函数来转换每一行。如果提供了两个函数,第二个是行转换函数,第一个是 init 对象。d3.autoType 常被用作行转换函数,用于自动类型推断。
  • d3.dsv(delimiter, url[, initOrRowConverter[, rowConverter]]) − 获取指定 url 的分隔符分隔的值文件(例如,使用 ’;’ 或 ’|’)。
  • d3.html(url[, init]) − 获取指定 url 的 HTML 文件,并返回一个解析为文档片段的 Promise。
  • d3.image(url[, init]) − 获取指定 url 的图像,并返回一个解析为 HTMLImageElement 的 Promise。init 可以包含 crossOrigin 属性。
  • d3.json(url[, init]) − 获取指定 url 的 JSON 文件,并返回一个解析为解析后 JSON 对象的 Promise。
  • d3.svg(url[, init]) − 获取指定 url 的 SVG 文件,并返回一个解析为包含 SVG 的文档片段的 Promise。
  • d3.text(url[, init]) − 获取指定 url 的纯文本文件。
  • d3.tsv(url[, initOrRowConverter[, rowConverter]]) − 获取指定 url 的 TSV(制表符分隔的值)文件。与 d3.csv 类似。

在你的项目文件夹中创建一个 sample.csv 文件:

product,category,price
Apple,Fruit,1.2
Banana,Fruit,0.8
Carrot,Vegetable,0.5

现在,创建一个 HTML 文件来加载和显示这些数据:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3.js Fetch CSV Example</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<h3>Loaded CSV Data:</h3>
<div id="output"></div>
<script>
async function loadData() {
try {
// 使用 d3.autoType 自动将字符串转换为数字、日期等
const data = await d3.csv("sample.csv", d3.autoType);
console.log(data);
// data 将是:
// [
// {product: "Apple", category: "Fruit", price: 1.2},
// {product: "Banana", category: "Fruit", price: 0.8},
// {product: "Carrot", category: "Vegetable", price: 0.5}
// ]
const outputDiv = d3.select("#output");
outputDiv.selectAll("p")
.data(data)
.join("p")
.text(d => `Product: ${d.product}, Category: ${d.category}, Price: $${d.price.toFixed(2)}`);
} catch (error) {
console.error("加载或解析 CSV 出错:", error);
d3.select("#output").text("加载数据失败。");
}
}
loadData();
</script>
</body>
</html>

此示例使用 async/await 使异步代码更清晰。d3.autoType 是一个方便的行转换函数,它可以推断列的数据类型(例如,将 ‘1.2’ 转换为数字 1.2)。

对于更复杂的数据,你可能需要一个自定义的行转换函数:

d3.csv("timeseries.csv", (d) => {
return {
date: new Date(d.timestamp), // 假设列名为 'timestamp'
value: +d.measurement // 将 'measurement' 转换为数字
};
}).then(data => {
console.log("自定义解析数据:", data);
}).catch(error => {
console.error("错误:", error);
});

数据加载是大多数 D3.js 项目的第一步:

  • 获取图表和图形所需的数据集。
  • 加载 GeoJSON 数据用于地图绘制。
  • 检索配置文件或文本内容。
  • 动态加载图像或 SVG 资源。

在获取数据时,务必使用 .catch() 或 async/await 中的 try...catch 处理潜在错误。欲了解更多详情,请参阅 d3-fetch 文档。