Fix Issue 162: Support DOS-style line endings
authorDan Vanderkam <danvk@google.com>
Fri, 17 Aug 2012 15:38:24 +0000 (11:38 -0400)
committerDan Vanderkam <danvk@google.com>
Fri, 17 Aug 2012 15:38:24 +0000 (11:38 -0400)
auto_tests/misc/local.html
auto_tests/tests/parser.js [new file with mode: 0644]
dygraph-utils.js
dygraph.js

index d1c6cd9..e35d18d 100644 (file)
@@ -45,6 +45,7 @@
   <script type="text/javascript" src="../tests/update_while_panning.js"></script>
   <script type="text/javascript" src="../tests/stacked.js"></script>
   <script type="text/javascript" src="../tests/per_series.js"></script>
+  <script type="text/javascript" src="../tests/parser.js"></script>
   <script type="text/javascript" src="../tests/update_options.js"></script>
   <script type="text/javascript" src="../tests/utils_test.js"></script>
 
diff --git a/auto_tests/tests/parser.js b/auto_tests/tests/parser.js
new file mode 100644 (file)
index 0000000..dc1d5b2
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * @fileoverview Tests the way that dygraphs parses data.
+ *
+ * @author danvk@google.com (Dan Vanderkam)
+ */
+var parserTestCase = TestCase("parser");
+
+parserTestCase.prototype.setUp = function() {
+  document.body.innerHTML = "<div id='graph'></div>";
+};
+
+parserTestCase.prototype.tearDown = function() {
+};
+
+parserTestCase.prototype.testDetectLineDelimiter = function() {
+  var data = "X,Y\r" +
+      "0,-1\r" +
+      "1,0\r" +
+      "2,1\r" +
+      "3,0\r"
+  ;
+  assertEquals("\r", Dygraph.detectLineDelimiter(data));
+
+  data = "X,Y\n" +
+      "0,-1\n" +
+      "1,0\n" +
+      "2,1\n" +
+      "3,0\n"
+  ;
+  assertEquals("\n", Dygraph.detectLineDelimiter(data));
+
+  data = "X,Y\n\r" +
+      "0,-1\n\r" +
+      "1,0\n\r" +
+      "2,1\n\r" +
+      "3,0\n\r"
+  ;
+  assertEquals("\n\r", Dygraph.detectLineDelimiter(data));
+};
+
+parserTestCase.prototype.testParseDosNewlines = function() {
+  var opts = {
+    width: 480,
+    height: 320
+  };
+  var data = "X,Y\r" +
+      "0,-1\r" +
+      "1,0\r" +
+      "2,1\r" +
+      "3,0\r"
+  ;
+
+  var graph = document.getElementById("graph");
+  var g = new Dygraph(graph, data, opts);
+
+  assertEquals(0, g.getValue(0, 0));
+  assertEquals(-1, g.getValue(0, 1));
+  assertEquals(1, g.getValue(1, 0));
+  assertEquals(0, g.getValue(1, 1));
+  assertEquals(['X', 'Y'], g.getLabels());
+};
+
index 707bbca..200617c 100644 (file)
@@ -1080,3 +1080,22 @@ Dygraph.IFrameTarp.prototype.uncover = function() {
   }
   this.tarps = [];
 };
+
+/**
+ * Determine whether |data| is delimited by CR, LF or CRLF.
+ * @param {string} data
+ * @return {string|null} the delimiter that was detected.
+ */
+Dygraph.detectLineDelimiter = function(data) {
+  for (var i = 0; i < data.length; i++) {
+    var code = data[i];
+    if (code == '\r') return code;
+    if (code == '\n') {
+      // Might actually be "\n\r".
+      if (i < data.length && data[i + 1] == '\r') return '\n\r';
+      return code;
+    }
+  }
+
+  return null;
+};
index a0e55ab..0fc48ce 100644 (file)
@@ -2936,7 +2936,8 @@ Dygraph.prototype.parseFloat_ = function(x, opt_line_no, opt_line) {
  */
 Dygraph.prototype.parseCSV_ = function(data) {
   var ret = [];
-  var lines = data.split("\n");
+  var line_delimiter = Dygraph.detectLineDelimiter(data);
+  var lines = data.split(line_delimiter || "\n");
   var vals, j;
 
   // Use the default delimiter or fall back to a tab if that makes sense.
@@ -3292,7 +3293,8 @@ Dygraph.prototype.start_ = function() {
     this.predraw_();
   } else if (typeof data == 'string') {
     // Heuristic: a newline means it's CSV data. Otherwise it's an URL.
-    if (data.indexOf('\n') >= 0) {
+    var line_delimiter = Dygraph.detectLineDelimiter(data);
+    if (line_delimiter) {
       this.loadedEvent_(data);
     } else {
       var req = new XMLHttpRequest();