Created
September 27, 2016 06:05
-
-
Save wesalvaro/16402a3f3d734de5a6728376bec36439 to your computer and use it in GitHub Desktop.
Adds iteration and simpler filtering to DataTable and DataView objects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const extendGoogleVisualization = () => { | |
const dataView = google.visualization.DataView.prototype; | |
const dataTable = google.visualization.DataTable.prototype; | |
dataView.getNiceRow = dataTable.getNiceRow = function(r) { | |
const row = []; | |
for (let c = 0; c < this.getNumberOfColumns(); ++c) { | |
const colId = this.getColumnId(c); | |
row.push(this.getValue(r, c)); | |
if (colId) { | |
row[colId] = row[c]; | |
} | |
} | |
return row; | |
}; | |
dataView[Symbol.iterator] = dataTable[Symbol.iterator] = function() { | |
const self = this; | |
return { | |
_row: -1, | |
next() { | |
const done = ++this._row >= self.getNumberOfRows(); | |
return { | |
done: done, | |
value: done ? null : self.getNiceRow(this._row), | |
}; | |
}, | |
}; | |
}; | |
dataView.filter = dataTable.filter = function(filter) { | |
const rows = [...this].reduce((rows, row, i) => { | |
return rows.concat(filter(row) ? [i] : []); | |
}, []); | |
const dataView = new google.visualization.DataView(this); | |
dataView.setRows(rows); | |
return dataView; | |
}; | |
dataView.filterByColumn = dataTable.filterByColumn = function(...filters) { | |
const convertToFilterObject = (filter, colIndex) => { | |
const filterType = typeof filter; | |
switch (filterType) { | |
case 'string': | |
case 'number': | |
case 'function': | |
return { | |
column: colIndex, | |
value: filter, | |
}; | |
case 'object': | |
if (filter instanceof RegExp) { | |
return { | |
column: colIndex, | |
test: v => filter.test(v), | |
}; | |
} else if (filter instanceof Array) { | |
if ('number' == typeof filter[1]) { | |
// [min, max] NOTE: Does not work for specifying column and number value filter. | |
return { | |
column: colIndex, | |
minValue: filter[0], | |
maxValue: filter[1], | |
}; | |
} else { | |
// [column, filter] | |
return Object.assign(convertToFilterObject(filter[1]), { | |
column: filter[0], | |
}); | |
} | |
} else { | |
return filter; | |
} | |
default: throw 'Unsupported filter'; | |
} | |
}; | |
const filterObjects = filters.map(convertToFilterObject).filter(f => !!f); | |
const dataView = new google.visualization.DataView(this); | |
dataView.setRows(this.getFilteredRows(filterObjects)); | |
return dataView; | |
}; | |
}; | |
const onLoadCallback = () => { | |
console.log('loaded'); | |
const data = google.visualization.arrayToDataTable([ | |
[{id: 'n', label: 'name'}, 'foo', {id: 'bar'}], | |
['tom', 1, 2], | |
['pam', 1, 2], | |
['jan', 2, 3], | |
]); | |
extendGoogleVisualization(); | |
console.log( | |
data.getNiceRow(0), | |
[...data.filterByColumn(null, null, /3/).filterByColumn({column: 0, value: 'jan'})], | |
[...data.filter(row => row.bar == 2).filter(row => /tom/.test(row[0]))]); | |
}; | |
google.charts.load('current', {packages: ['corechart']}); | |
google.charts.setOnLoadCallback(onLoadCallback); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment