Reputation: 96
I need to implement the following code:
d3.csv("data.csv", function(d, i, columns) {
for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]];
d.total = t;
return d;
}, function(error, data) {
if (error) throw error;
var keys = data.columns.slice(1);
...
From: https://bl.ocks.org/mbostock/3886208
But, I have to use d3.js version 3. I found 'columns' in the d3 v4 API Reference:
The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary).
For example: data.columns; // ["Year", "Make", "Model", "Length"]
But I'm struggling with coming up with something similar in version 3 to use for the keys variable, as shown at the last line of the quoted code:
var keys = data.columns.slice(1);
How can I use data
to get the same d
and keys
without the "columns" property?
Upvotes: 2
Views: 577
Reputation: 102194
Despite the fact that now you know the v3 version of that bl.ocks, it's woth mentioning that it's quite easy to create your own columns
property, but with some drawbacks.
The source code in V4 that creates the columns
property is this:
function inferColumns(rows) {
var columnSet = Object.create(null),
columns = [];
rows.forEach(function(row) {
for (var column in row) {
if (!(column in columnSet)) {
columns.push(columnSet[column] = column);
}
}
});
return columns;
}
We can make a (very) simplified version of it.
Here is a normal d3.csv
code with D3 v3, I'm loading some CSV I found online:
d3.csv("https://www.ibm.com/support/knowledgecenter/SVU13_7.2.1/com.ibm.ismsaas.doc/reference/AssetsImportMinimumSample.csv?view=kc", function(data) {
console.log(data)
})
<script src="https://d3js.org/d3.v3.min.js"></script>
We can create our columns
getting the headers of that CSV with:
data.columns = d3.keys(data[0])
Here is the demo (look at your browser console, not the snippet's one):
d3.csv("https://www.ibm.com/support/knowledgecenter/SVU13_7.2.1/com.ibm.ismsaas.doc/reference/AssetsImportMinimumSample.csv?view=kc", function(data){
data.columns = d3.keys(data[0])
console.log(data)
})
<script src="https://d3js.org/d3.v3.min.js"></script>
But these are the drawbacks: first, this code is oversimplified: it doesn't take into account duplicated values, for instance. Second, It created the columns
property after loading/parsing the file. Therefore, you cannot use columns
in the row accessor function, because it doesn't exist at that point. Of corse you could create the columns
property inside the row function, but that's not a very wise solution, because the row function is called for every row in the CSV, which can be hundreds or even thousands.
Upvotes: 2