简体   繁体   中英

d3.tsv/d3.csv columns in accessor (row) function

Consider the following tsv file:

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

I 've been trying to understand how the following code works but haven't found a clear answer:

d3.tsv("test.tsv") 
    .row(function(d, i, columns){ d.total = columns.length; return d;})
    .get(function(d){ console.log(d);});

The specific questions I have are the following:

  • What is the underlying parse function that maps the third (columns) argument to the column names in the accessor (row) function?

  • Why do I need the row iterator (i) argument in the accessor function?

What is the underlying parse function that maps the third (columns) argument to the column names in the accessor (row) function?

The accessor function, also known as the row conversion function , is a function invoked for each row, and it takes 3 arguments (which will answer your second question further down):

  • The first argument is the row
  • The second argument is the index , starting at zero
  • The third argument is the column names array

This third argument is interesting, and it was introduced in D3 v4.x. I believe that it answers your first question:

When you load a CSV (or a TSV), d3.csv (or d3.tsv ) creates an array property with the headers, named columns (take care with loops like a for...in loop, because it will include that property ) . In the case of your example, it is:

columns: ["Code", "k1", "k2"]

And it lead us to your second question:

Why do I need the row iterator (i) argument in the accessor function?

You don't. The thing is that this piece of code uses the third argument, which is the columns property, and for being able to use the third argument we have to supply the two arguments that come before it, even if we don't use them:

.row(function(d, i, columns){ d.total = columns.length; return d;}) 
//3rd argument---------^

There is a convention in JavaScript, not very famous I reckon, that an unused parameter should be named as an underscore ( _ ). In that case, this function would be:

.row(function(d, _, columns){ d.total = columns.length; return d;}) 
//not used-------^

So, what that code does is getting the value of columns.length , which is 3, and creating a new property to each object:

d.total = columns.length; return d;

So, the objects will end up like this:

{Code: "pf_1", k1: "0.2", k2: "0.3", total: 3}

With the new property total .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM