Basic tests for GViz support
authorDan Vanderkam <danvdk@gmail.com>
Sun, 29 Mar 2015 02:41:58 +0000 (22:41 -0400)
committerDan Vanderkam <danvdk@gmail.com>
Sun, 29 Mar 2015 02:44:34 +0000 (22:44 -0400)
auto_tests/tests/gviz.js [new file with mode: 0644]
src/dygraph.js

diff --git a/auto_tests/tests/gviz.js b/auto_tests/tests/gviz.js
new file mode 100644 (file)
index 0000000..c663029
--- /dev/null
@@ -0,0 +1,152 @@
+/**
+ * Unit tests for GViz data table support.
+ */
+
+describe('gviz', function() {
+
+  beforeEach(function() {
+    document.body.innerHTML = "<div id='graph'></div>";
+  });
+
+  afterEach(function() {
+  });
+
+  // This is a fake version of the gviz DataTable API, which can only be
+  // sourced using the google js loader.
+  //
+  // Their example of the "data" structure is:
+  //   cols: [{id: 'task', label: 'Task', type: 'string'},
+  //          {id: 'hours', label: 'Hours per Day', type: 'number'}],
+  //   rows: [{c:[{v: 'Work'}, {v: 11}]},
+  //          {c:[{v: 'Eat'}, {v: 2}]},
+  //          {c:[{v: 'Commute'}, {v: 2}]},
+  //          {c:[{v: 'Watch TV'}, {v:2}]},
+  //          {c:[{v: 'Sleep'}, {v:7, f:'7.000'}]}
+  //         ]
+  //
+  // https://developers.google.com/chart/interactive/docs/reference#DataTable
+  var FakeDataTable = function(data) {
+    this.data = data;
+  };
+  FakeDataTable.prototype.getNumberOfColumns = function() {
+    return this.data.cols.length;
+  };
+  FakeDataTable.prototype.getNumberOfRows = function() {
+    return this.data.rows.length;
+  };
+  FakeDataTable.prototype.getColumnType = function(idx) {
+    return this.data.cols[idx].type;
+  };
+  FakeDataTable.prototype.getColumnLabel = function(idx) {
+    return this.data.cols[idx].label;
+  };
+  FakeDataTable.prototype.getValue = function(row, col) {
+    return this.data.rows[row].c[col].v;
+  };
+  FakeDataTable.prototype.getColumnRange = function(col) {
+    throw 'Not Implemented';
+  };
+
+  // This mirrors http://dygraphs.com/tests/gviz.html
+  var numericData = new FakeDataTable({
+    cols: [{id:"",label:"X",type:"number"},
+           {id:"",label:"A",type:"number"},
+           {id:"",label:"B",type:"number"}],
+    rows: [{c:[{v:0},{v:1},{v:7}]},
+           {c:[{v:1},{v:2},{v:4}]},
+           {c:[{v:2},{v:3},{v:3}]},
+           {c:[{v:3},{v:4},{v:0}]}]
+  });
+
+  it('should parse simple data tables', function() {
+    var g = new Dygraph('graph', numericData);
+    assert.equal(4, g.numRows());
+    assert.equal(3, g.numColumns());
+    assert.equal(0, g.getValue(0, 0));
+    assert.equal(1, g.getValue(0, 1));
+    assert.equal(7, g.getValue(0, 2));
+    assert.equal(3, g.getValue(3, 0));
+    assert.equal(4, g.getValue(3, 1));
+    assert.equal(0, g.getValue(3, 2));
+    assert.deepEqual(['X', 'A', 'B'], g.getLabels());
+  });
+
+  it('should parse tables with annotations', function() {
+    // Data from https://developers.google.com/chart/interactive/docs/gallery/annotatedtimeline
+    var data = new FakeDataTable({
+      cols: [
+        {label: "Date", type: "date" },
+        {label: "Sold Pencils", type: "number" },
+        {label: "title1", type: "string" },
+        {label: "text1", type: "string" },
+        {label: "Sold Pens", type: "number" },
+        {label: "title2", type: "string" },
+        {label: "text2", type: "string" }
+      ],
+      rows: [
+        {c: [{v: new Date(2008, 1, 1)}, {v: 30000}, {v: null}, {v: null},
+             {v: 40645}, {v: null}, {v: null}]},
+        {c: [{v: new Date(2008, 1, 2)}, {v: 14045}, {v: null}, {v: null},
+             {v: 20374}, {v: null}, {v: null}]},
+        {c: [{v: new Date(2008, 1, 3)}, {v: 55022}, {v: null}, {v: null},
+             {v: 50766}, {v: null}, {v: null}]},
+        {c: [{v: new Date(2008, 1, 4)}, {v: 75284}, {v: null}, {v: null},
+             {v: 14334}, {v: "Out of Stock"}, {v: "Ran out of stock"}]},
+        {c: [{v: new Date(2008, 1, 5)}, {v: 41476}, {v: "Bought Pens"},
+             {v: "Bought 200k pens" }, {v: 66467}, {v: null}, {v: null}]},
+        {c: [{v: new Date(2008, 1, 6)}, {v: 33322}, {v: null}, {v: null},
+             {v: 39463}, {v: null}, {v: null}]}
+      ]
+    });
+    
+    var g = new Dygraph('graph', data, {displayAnnotations: true});
+
+    var annEls = document.getElementsByClassName('dygraphDefaultAnnotation');
+    assert.equal(2, annEls.length);
+
+    var annotations = g.annotations();
+    assert.equal(2, annotations.length);
+    var a0 = annotations[0];
+    assert.deepEqual({
+      text: 'Out of Stock\nRan out of stock',
+      series: 'Sold Pens',
+      xval: new Date(2008, 1, 4).getTime(),
+      shortText: 'A'
+    }, annotations[0]);
+  });
+
+  it('should parse tables with dates', function() {
+    // This mirrors http://dygraphs.com/tests/gviz.html
+    var data = new FakeDataTable({
+      cols: [{id:"",label:"Date",type:"datetime"},
+             {id:"",label:"Column A",type:"number"},
+             {id:"",label:"Column B",type:"number"}],
+      rows: [{c:[{v:new Date(2009, 6, 1)},{v:1},{v:7}]},
+             {c:[{v:new Date(2009, 6, 8)},{v:2},{v:4}]},
+             {c:[{v:new Date(2009, 6, 15)},{v:3},{v:3}]},
+             {c:[{v:new Date(2009, 6, 22)},{v:4},{v:0}]}]
+    });
+
+    var g = new Dygraph('graph', data);
+    assert.equal(4, g.numRows());
+    assert.equal(3, g.numColumns());
+    assert.equal(new Date(2009, 6, 1).getTime(), g.getValue(0, 0));
+    assert.equal(1, g.getValue(0, 1));
+    assert.equal(7, g.getValue(0, 2));
+    assert.deepEqual(['Date', 'Column A', 'Column B'], g.getLabels());
+  });
+
+  // it('should parse tables with error bars', function() {
+  // });
+
+  it('should implement the gviz API', function() {
+    var g = new Dygraph.GVizChart(document.getElementById('graph'));
+    g.draw(numericData);
+
+    g.setSelection([{row: 0}]);
+    assert.equal('0: A: 1 B: 7', Util.getLegend());
+    assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 2}], g.getSelection());
+    g.setSelection([]);
+    assert.deepEqual([], g.getSelection());
+  });
+});
index 735ddca..df6baf9 100644 (file)
@@ -3247,9 +3247,9 @@ Dygraph.prototype.parseDataTable_ = function(data) {
     this.attrs_.axes.x.ticker = Dygraph.numericTicks;
     this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;
   } else {
-    console.error("only 'date', 'datetime' and 'number' types are supported " +
-                  "for column 1 of DataTable input (Got '" + indepType + "')");
-    return null;
+    throw new Error(
+          "only 'date', 'datetime' and 'number' types are supported " +
+          "for column 1 of DataTable input (Got '" + indepType + "')");
   }
 
   // Array of the column indices which contain data (and not annotations).
@@ -3271,8 +3271,9 @@ Dygraph.prototype.parseDataTable_ = function(data) {
       }
       hasAnnotations = true;
     } else {
-      console.error("Only 'number' is supported as a dependent type with Gviz." +
-                    " 'string' is only supported if displayAnnotations is true");
+      throw new Error(
+          "Only 'number' is supported as a dependent type with Gviz." +
+          " 'string' is only supported if displayAnnotations is true");
     }
   }