| 1 | /** |
| 2 | * Unit tests for GViz data table support. |
| 3 | */ |
| 4 | |
| 5 | import Dygraph from '../../src/dygraph'; |
| 6 | |
| 7 | import Util from './Util'; |
| 8 | |
| 9 | describe('gviz', function() { |
| 10 | |
| 11 | cleanupAfterEach(); |
| 12 | |
| 13 | // This is a fake version of the gviz DataTable API, which can only be |
| 14 | // sourced using the google js loader. |
| 15 | // |
| 16 | // Their example of the "data" structure is: |
| 17 | // cols: [{id: 'task', label: 'Task', type: 'string'}, |
| 18 | // {id: 'hours', label: 'Hours per Day', type: 'number'}], |
| 19 | // rows: [{c:[{v: 'Work'}, {v: 11}]}, |
| 20 | // {c:[{v: 'Eat'}, {v: 2}]}, |
| 21 | // {c:[{v: 'Commute'}, {v: 2}]}, |
| 22 | // {c:[{v: 'Watch TV'}, {v:2}]}, |
| 23 | // {c:[{v: 'Sleep'}, {v:7, f:'7.000'}]} |
| 24 | // ] |
| 25 | // |
| 26 | // https://developers.google.com/chart/interactive/docs/reference#DataTable |
| 27 | var FakeDataTable = function(data) { |
| 28 | this.data = data; |
| 29 | }; |
| 30 | FakeDataTable.prototype.getNumberOfColumns = function() { |
| 31 | return this.data.cols.length; |
| 32 | }; |
| 33 | FakeDataTable.prototype.getNumberOfRows = function() { |
| 34 | return this.data.rows.length; |
| 35 | }; |
| 36 | FakeDataTable.prototype.getColumnType = function(idx) { |
| 37 | return this.data.cols[idx].type; |
| 38 | }; |
| 39 | FakeDataTable.prototype.getColumnLabel = function(idx) { |
| 40 | return this.data.cols[idx].label; |
| 41 | }; |
| 42 | FakeDataTable.prototype.getValue = function(row, col) { |
| 43 | return this.data.rows[row].c[col].v; |
| 44 | }; |
| 45 | FakeDataTable.prototype.getColumnRange = function(col) { |
| 46 | throw 'Not Implemented'; |
| 47 | }; |
| 48 | |
| 49 | // This mirrors http://dygraphs.com/tests/gviz.html |
| 50 | var numericData = new FakeDataTable({ |
| 51 | cols: [{id:"",label:"X",type:"number"}, |
| 52 | {id:"",label:"A",type:"number"}, |
| 53 | {id:"",label:"B",type:"number"}], |
| 54 | rows: [{c:[{v:0},{v:1},{v:7}]}, |
| 55 | {c:[{v:1},{v:2},{v:4}]}, |
| 56 | {c:[{v:2},{v:3},{v:3}]}, |
| 57 | {c:[{v:3},{v:4},{v:0}]}] |
| 58 | }); |
| 59 | |
| 60 | it('should parse simple data tables', function() { |
| 61 | var g = new Dygraph('graph', numericData); |
| 62 | assert.equal(4, g.numRows()); |
| 63 | assert.equal(3, g.numColumns()); |
| 64 | assert.equal(0, g.getValue(0, 0)); |
| 65 | assert.equal(1, g.getValue(0, 1)); |
| 66 | assert.equal(7, g.getValue(0, 2)); |
| 67 | assert.equal(3, g.getValue(3, 0)); |
| 68 | assert.equal(4, g.getValue(3, 1)); |
| 69 | assert.equal(0, g.getValue(3, 2)); |
| 70 | assert.deepEqual(['X', 'A', 'B'], g.getLabels()); |
| 71 | }); |
| 72 | |
| 73 | it('should parse tables with annotations', function() { |
| 74 | // Data from https://developers.google.com/chart/interactive/docs/gallery/annotatedtimeline |
| 75 | var data = new FakeDataTable({ |
| 76 | cols: [ |
| 77 | {label: "Date", type: "date" }, |
| 78 | {label: "Sold Pencils", type: "number" }, |
| 79 | {label: "title1", type: "string" }, |
| 80 | {label: "text1", type: "string" }, |
| 81 | {label: "Sold Pens", type: "number" }, |
| 82 | {label: "title2", type: "string" }, |
| 83 | {label: "text2", type: "string" } |
| 84 | ], |
| 85 | rows: [ |
| 86 | {c: [{v: new Date(2008, 1, 1)}, {v: 30000}, {v: null}, {v: null}, |
| 87 | {v: 40645}, {v: null}, {v: null}]}, |
| 88 | {c: [{v: new Date(2008, 1, 2)}, {v: 14045}, {v: null}, {v: null}, |
| 89 | {v: 20374}, {v: null}, {v: null}]}, |
| 90 | {c: [{v: new Date(2008, 1, 3)}, {v: 55022}, {v: null}, {v: null}, |
| 91 | {v: 50766}, {v: null}, {v: null}]}, |
| 92 | {c: [{v: new Date(2008, 1, 4)}, {v: 75284}, {v: null}, {v: null}, |
| 93 | {v: 14334}, {v: "Out of Stock"}, {v: "Ran out of stock"}]}, |
| 94 | {c: [{v: new Date(2008, 1, 5)}, {v: 41476}, {v: "Bought Pens"}, |
| 95 | {v: "Bought 200k pens" }, {v: 66467}, {v: null}, {v: null}]}, |
| 96 | {c: [{v: new Date(2008, 1, 6)}, {v: 33322}, {v: null}, {v: null}, |
| 97 | {v: 39463}, {v: null}, {v: null}]} |
| 98 | ] |
| 99 | }); |
| 100 | |
| 101 | var g = new Dygraph('graph', data, {displayAnnotations: true}); |
| 102 | |
| 103 | var annEls = document.getElementsByClassName('dygraphDefaultAnnotation'); |
| 104 | assert.equal(2, annEls.length); |
| 105 | |
| 106 | var annotations = g.annotations(); |
| 107 | assert.equal(2, annotations.length); |
| 108 | var a0 = annotations[0]; |
| 109 | assert.deepEqual({ |
| 110 | text: 'Out of Stock\nRan out of stock', |
| 111 | series: 'Sold Pens', |
| 112 | xval: new Date(2008, 1, 4).getTime(), |
| 113 | shortText: 'A' |
| 114 | }, annotations[0]); |
| 115 | }); |
| 116 | |
| 117 | it('should parse tables with dates', function() { |
| 118 | // This mirrors http://dygraphs.com/tests/gviz.html |
| 119 | var data = new FakeDataTable({ |
| 120 | cols: [{id:"",label:"Date",type:"datetime"}, |
| 121 | {id:"",label:"Column A",type:"number"}, |
| 122 | {id:"",label:"Column B",type:"number"}], |
| 123 | rows: [{c:[{v:new Date(2009, 6, 1)},{v:1},{v:7}]}, |
| 124 | {c:[{v:new Date(2009, 6, 8)},{v:2},{v:4}]}, |
| 125 | {c:[{v:new Date(2009, 6, 15)},{v:3},{v:3}]}, |
| 126 | {c:[{v:new Date(2009, 6, 22)},{v:4},{v:0}]}] |
| 127 | }); |
| 128 | |
| 129 | var g = new Dygraph('graph', data); |
| 130 | assert.equal(4, g.numRows()); |
| 131 | assert.equal(3, g.numColumns()); |
| 132 | assert.equal(new Date(2009, 6, 1).getTime(), g.getValue(0, 0)); |
| 133 | assert.equal(1, g.getValue(0, 1)); |
| 134 | assert.equal(7, g.getValue(0, 2)); |
| 135 | assert.deepEqual(['Date', 'Column A', 'Column B'], g.getLabels()); |
| 136 | }); |
| 137 | |
| 138 | // it('should parse tables with error bars', function() { |
| 139 | // }); |
| 140 | |
| 141 | it('should implement the gviz API', function() { |
| 142 | var g = new Dygraph.GVizChart(document.getElementById('graph')); |
| 143 | g.draw(numericData); |
| 144 | |
| 145 | g.setSelection([{row: 0}]); |
| 146 | assert.equal('0: A: 1 B: 7', Util.getLegend()); |
| 147 | assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 2}], g.getSelection()); |
| 148 | g.setSelection([]); |
| 149 | assert.deepEqual([], g.getSelection()); |
| 150 | }); |
| 151 | }); |