D3.js - 数组 API
D3.js - 数组 API (d3-array)
Section titled “D3.js - 数组 API (d3-array)”D3 的 d3-array 模块提供了一套强大的数组操作和分析函数。这些工具对于数据处理、统计计算以及准备数据进行可视化非常有帮助。本章探讨了 Array API 的主要功能。
配置数组 API
Section titled “配置数组 API”d3-array 模块是 D3.js 主捆绑包的一部分。如果你是单独使用 D3 模块,可以安装并导入 d3-array。
<!-- 选项 1:包含完整的 D3 库 --><script src="https://d3js.org/d3.v7.min.js"></script>
<!-- 选项 2:包含独立的 d3-array 模块 --><!-- <script src="https://d3js.org/d3-array.v3.min.js"></script> -->
<script> // 示例用法: // const numbers = [1, 5, 2, 8, 3]; // console.log(d3.min(numbers)); // 1 // console.log(d3.max(numbers)); // 8</script>数组统计方法
Section titled “数组统计方法”这些方法计算数组的基本汇总统计量。
- d3.min(array[, accessor]) − 使用自然顺序返回
array中的最小值。可选的accessor函数可用于从数组元素派生值。 - d3.max(array[, accessor]) − 返回最大值。
- d3.extent(array[, accessor]) − 返回一个数组
[min, max],表示最小值和最大值。 - d3.sum(array[, accessor]) − 返回所有值的总和。忽略 NaN 和 undefined 值。
- d3.mean(array[, accessor]) − 返回算术平均值(平均数)。
- d3.median(array[, accessor]) − 返回中位数(中间值)。
- d3.quantile(array, p[, accessor]) − 返回 p 分位数,其中
p是一个在 [0, 1] 范围内的数字。例如,p=0.5是中位数。 - d3.variance(array[, accessor]) − 返回样本方差。
- d3.deviation(array[, accessor]) − 返回标准差(方差的平方根)。
const data = [20, 40, 60, 80, 100];const objects = [{value: 10}, {value: 5}, {value: 15}];
console.log(`最小值: ${d3.min(data)}`); // 最小值: 20console.log(`最大值: ${d3.max(data)}`); // 最大值: 100console.log(`范围: ${d3.extent(data)}`); // 范围: 20,100console.log(`总和: ${d3.sum(data)}`); // 总和: 300console.log(`平均值: ${d3.mean(data)}`); // 平均值: 60console.log(`中位数: ${d3.median(data)}`); // 中位数: 60console.log(`分位数 (0.25): ${d3.quantile(data, 0.25)}`); // 分位数 (0.25): 40console.log(`方差: ${d3.variance(data)}`); // 方差: 1000console.log(`标准差: ${d3.deviation(data)}`); // 标准差: 31.622...
// 使用访问器console.log(`对象最小值的 value: ${d3.min(objects, d => d.value)}`); // 对象最小值的 value: 5数组搜索方法
Section titled “数组搜索方法”这些方法有助于在数组中查找元素或索引。
- d3.scan(array[, comparator]) − 执行线性扫描,根据
comparator返回具有最小值的元素的索引。默认比较器是d3.ascending。 - d3.bisectLeft(array, x[, lo[, hi]]) − 返回
x在array中的插入点,以保持排序顺序。假设array已排序。 - d3.bisectRight(array, x[, lo[, hi]]) − 类似于
bisectLeft,但返回最右侧的插入点。 - d3.bisectCenter(array, x[, lo[, hi]]) - 在已排序数组中返回最接近 x 的元素的索引。
- d3.ascending(a, b) − 一个比较器函数:如果
a < b返回 -1,如果a > b返回 1,如果a == b返回 0,否则返回 NaN。 - d3.descending(a, b) − 用于降序排列的比较器函数。
const unsortedObjects = [{id: 'c', val: 30}, {id: 'a', val: 10}, {id: 'b', val: 20}];const sortedNumbers = [10, 20, 30, 40, 50];
// 找到具有最小 'val' 值的对象的索引const minValIndex = d3.scan(unsortedObjects, (a, b) => d3.ascending(a.val, b.val));console.log(`最小 val 的索引: ${minValIndex}, 对象:`, unsortedObjects[minValIndex]); // 索引: 1, 对象: {id: 'a', val: 10}
// Bisect 示例(用于已排序数组)console.log(`25 的左侧插入点: ${d3.bisectLeft(sortedNumbers, 25)}`); // 25 的左侧插入点: 2console.log(`30 的右侧插入点: ${d3.bisectRight(sortedNumbers, 30)}`); // 30 的右侧插入点: 3console.log(`28 的中心插入点: ${d3.bisectCenter(sortedNumbers, 28)}`);// 28 的中心插入点: 2 (30 的索引)数组转换方法
Section titled “数组转换方法”这些方法从现有数组生成新数组。
- d3.cross(a, b[, reducer]) − 返回数组
a和b的笛卡尔积(Cartesian product)。可选的reducer函数可以转换每对元素。 - d3.merge(arrays) − 将数组的
arrays合并成一个单一数组。 - d3.pairs(array[, reducer]) − 从输入
array返回相邻元素对[a, b]的数组。可选的reducer可以转换元素对。 - d3.permute(array, order) − 根据指定的
order(索引数组)返回array的排列。也可以排列对象的属性。 - d3.shuffle(array[, start[, stop]]) - 在原地随机打乱数组元素的顺序(Fisher-Yates shuffle)。返回打乱后的数组。
- d3.ticks(start, stop, count) − 在
start和stop之间生成大约count个均匀分布、易于阅读的值。对于轴刻度值(axis ticks)很有用。 - d3.tickStep(start, stop, count) - 返回
d3.ticks的步长。 - d3.tickIncrement(start, stop, count) - 类似于
d3.tickStep,但用于日期。 - d3.range([start, ]stop[, step]) − 生成一个数字数组,类似于 Python 的
range。start默认为 0,step默认为 1。 - d3.zip(arrays…) − 转置(transposes)数组的数组。例如,
d3.zip([1,2], [3,4])产生[[1,3], [2,4]]。
console.log('交叉乘积:', JSON.stringify(d3.cross([1, 2], ['a', 'b'])));// 交叉乘积: [[1,"a"],[1,"b"],[2,"a"],[2,"b"]]
console.log('合并:', d3.merge([[1, 2], [3, 4]]));// 合并: [1, 2, 3, 4]
console.log('成对:', JSON.stringify(d3.pairs([1, 2, 3, 4])));// 成对: [[1,2],[2,3],[3,4]]
const obj = {name: 'D3', type: 'library'};const order = ['type', 'name'];console.log('置换对象属性:', d3.permute(obj, order));// 置换对象属性: ["library", "D3"]
console.log('拉链操作:', JSON.stringify(d3.zip([1, 2], ['a', 'b'], [true, false])));// 拉链操作: [[1,"a",true],[2,"b",false]]
console.log('范围 (0, 5):', d3.range(5));// 范围 (0, 5): [0, 1, 2, 3, 4]console.log('范围 (1, 5, 0.5):', d3.range(1, 5, 0.5));// 范围 (1, 5, 0.5): [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]
console.log('刻度值 (0, 10, 5):', d3.ticks(0, 10, 5));// 刻度值 (0, 10, 5): [0, 2, 4, 6, 8, 10] (示例输出,实际数量可能略有差异)d3-array 工具集对于以下场景非常有用:
- 数据清洗与准备: 计算刻度尺(scales)的范围(extents),计算饼图(pie charts)的总和,计算数据的平均值。
- 统计分析: 计算方差、标准差、分位数等,以理解数据分布。
- 算法实现: 使用二分查找(bisection)在排序数据中进行高效搜索(例如,为时间序列图上的工具提示定位)。
- 生成数据结构: 创建用于迭代的范围(ranges),用于热力图(heatmaps)的笛卡尔积,或用于轴线(axes)的刻度值。
请在 d3-array 文档 中探索此模块的全部功能。