toolkit/javascript/d3/d3.csv.js
changeset 47 c0b4a8b5a012
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/javascript/d3/d3.csv.js	Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,92 @@
+(function(){d3.csv = function(url, callback) {
+  d3.text(url, "text/csv", function(text) {
+    callback(text && d3.csv.parse(text));
+  });
+};
+d3.csv.parse = function(text) {
+  var header;
+  return d3.csv.parseRows(text, function(row, i) {
+    if (i) {
+      var o = {}, j = -1, m = header.length;
+      while (++j < m) o[header[j]] = row[j];
+      return o;
+    } else {
+      header = row;
+      return null;
+    }
+  });
+};
+
+d3.csv.parseRows = function(text, f) {
+  var EOL = {}, // sentinel value for end-of-line
+      EOF = {}, // sentinel value for end-of-file
+      rows = [], // output rows
+      re = /\r\n|[,\r\n]/g, // field separator regex
+      n = 0, // the current line number
+      t, // the current token
+      eol; // is the current token followed by EOL?
+
+  re.lastIndex = 0; // work-around bug in FF 3.6
+
+  /** @private Returns the next token. */
+  function token() {
+    if (re.lastIndex >= text.length) return EOF; // special case: end of file
+    if (eol) { eol = false; return EOL; } // special case: end of line
+
+    // special case: quotes
+    var j = re.lastIndex;
+    if (text.charCodeAt(j) === 34) {
+      var i = j;
+      while (i++ < text.length) {
+        if (text.charCodeAt(i) === 34) {
+          if (text.charCodeAt(i + 1) !== 34) break;
+          i++;
+        }
+      }
+      re.lastIndex = i + 2;
+      var c = text.charCodeAt(i + 1);
+      if (c === 13) {
+        eol = true;
+        if (text.charCodeAt(i + 2) === 10) re.lastIndex++;
+      } else if (c === 10) {
+        eol = true;
+      }
+      return text.substring(j + 1, i).replace(/""/g, "\"");
+    }
+
+    // common case
+    var m = re.exec(text);
+    if (m) {
+      eol = m[0].charCodeAt(0) !== 44;
+      return text.substring(j, m.index);
+    }
+    re.lastIndex = text.length;
+    return text.substring(j);
+  }
+
+  while ((t = token()) !== EOF) {
+    var a = [];
+    while ((t !== EOL) && (t !== EOF)) {
+      a.push(t);
+      t = token();
+    }
+    if (f && !(a = f(a, n++))) continue;
+    rows.push(a);
+  }
+
+  return rows;
+};
+d3.csv.format = function(rows) {
+  return rows.map(d3_csv_formatRow).join("\n");
+};
+
+function d3_csv_formatRow(row) {
+  return row.map(d3_csv_formatValue).join(",");
+}
+
+function d3_csv_formatValue(text) {
+  return /[",\n]/.test(text)
+      ? "\"" + text.replace(/\"/g, "\"\"") + "\""
+      : text;
+}
+})();