考虑以下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
我一直试图了解以下代码的工作原理,但没有找到明确的答案:
d3.tsv("test.tsv")
.row(function(d, i, columns){ d.total = columns.length; return d;})
.get(function(d){ console.log(d);});
我的具体问题如下:
将第三个(列)参数映射到访问者(行)函数中的列名称的底层解析函数是什么?
为什么我需要访问器函数中的row iterator(i)参数?
答案 0 :(得分:4)
将第三个(列)参数映射到访问器(行)函数中的列名称的底层解析函数是什么?
访问器函数,也称为row conversion function,是为每一行调用的函数,它需要3个参数(这将进一步回答你的第二个问题):
这第三个论点很有意思,它是在D3 v4.x中引入的。我相信它会回答你的第一个问题:
加载CSV(或TSV)时,d3.csv
(或d3.tsv
)会使用名为columns
的标题创建数组属性(取关注循环,比如 for ... in 循环,因为it will include that property)。在您的示例中,它是:
columns: ["Code", "k1", "k2"]
它引导我们回答你的第二个问题:
为什么我需要访问器函数中的行迭代器(i)参数?
你没有。问题在于这段代码使用第三个参数,即columns
属性,并且能够使用我们必须提供的第三个参数来提供它之前的两个参数,即使我们不使用它们:
.row(function(d, i, columns){ d.total = columns.length; return d;})
//3rd argument---------^
JavaScript中有一个约定,我认为不是很有名,未使用的参数应该被命名为下划线(_
)。在这种情况下,此功能将是:
.row(function(d, _, columns){ d.total = columns.length; return d;})
//not used-------^
那么,该代码所做的是获取columns.length
的值,即3,并为每个对象创建一个新属性:
d.total = columns.length; return d;
所以,对象最终会像这样:
{Code: "pf_1", k1: "0.2", k2: "0.3", total: 3}
使用新属性total
。