spy*_*dis 2 javascript csv d3.js
考虑以下 tsv 文件:
Code k1 k2
pf_1 0.2 0.3
pf_2 0.3 0.7
pf_3 0.2 0.4
pf_4 0.1 0.6
pf_5 0.8 0.9
Run Code Online (Sandbox Code Playgroud)
我一直试图理解以下代码是如何工作的,但尚未找到明确的答案:
d3.tsv("test.tsv")
.row(function(d, i, columns){ d.total = columns.length; return d;})
.get(function(d){ console.log(d);});
Run Code Online (Sandbox Code Playgroud)
我的具体问题如下:
将第三个(列)参数映射到访问器(行)函数中的列名称的底层解析函数是什么?
为什么访问器函数中需要行迭代器 (i) 参数?
将第三个(列)参数映射到访问器(行)函数中的列名称的底层解析函数是什么?
访问器函数,也称为行转换函数,是为每行调用的函数,它需要 3 个参数(这将进一步回答你的第二个问题):
第三个参数很有趣,它是在 D3 v4.x 中引入的。我相信它回答了你的第一个问题:
当您加载 CSV(或 TSV)时,d3.csv
(或d3.tsv
) 创建一个带有标题的数组属性columns
,名为(请注意for...in循环等循环,因为它将包含该属性)。就您的示例而言,它是:
columns: ["Code", "k1", "k2"]
Run Code Online (Sandbox Code Playgroud)
这引出了你的第二个问题:
为什么访问器函数中需要行迭代器 (i) 参数?
你不知道。问题是,这段代码使用了第三个参数,即columns
属性,为了能够使用第三个参数,我们必须提供它前面的两个参数,即使我们不使用它们:
.row(function(d, i, columns){ d.total = columns.length; return d;})
//3rd argument---------^
Run Code Online (Sandbox Code Playgroud)
JavaScript 中有一个约定,我认为不是很有名,即未使用的参数应命名为下划线 ( _
)。在这种情况下,这个函数将是:
.row(function(d, _, columns){ d.total = columns.length; return d;})
//not used-------^
Run Code Online (Sandbox Code Playgroud)
因此,该代码的作用是获取 的值columns.length
(即 3),并为每个对象创建一个新属性:
d.total = columns.length; return d;
Run Code Online (Sandbox Code Playgroud)
所以,对象最终会变成这样:
{Code: "pf_1", k1: "0.2", k2: "0.3", total: 3}
Run Code Online (Sandbox Code Playgroud)
有了新的财产total
。