d3.js: using CSV for numbers

D3 has two main ways to load data; JSON files or CSV files. JSON is generally better but bloated for long repeated rows of data, for which CSV is better because it only prints the key names once. But CSV has a drawback which is that it’s untyped. So D3 just lamely loads everything as strings. Most of the time Javascript’s automatic string to float conversion lets you ignore that but it fails in some places, like sorting with d3.ascending.

Fortunately D3’s CSV library lets you create an accessor function which manipulates the data as you load it. Here’s a function which will load every row and try to convert things to numbers. I wrote it in very verbose Javascript to make it clear what’s going on. I don’t care about the number of lines, but I do wonder if this is less efficient than possible.

// convert strings to numbers in CSV
function convertNumbers(row) {
  var r = {};
  for (var k in row) {
    r[k] = +row[k];
    if (isNaN(r[k])) {
      r[k] = row[k];
    }
  }
  return r;
}

d3.csv("data.csv", convertNumbers, function(error, inputData) {
  // do work on the data here
}

Note that the accessor function has to create a new object; you can’t just return the one the accessor passes you.