Skip to content

Instantly share code, notes, and snippets.

@wesalvaro
Created September 27, 2016 06:05
Show Gist options
  • Save wesalvaro/16402a3f3d734de5a6728376bec36439 to your computer and use it in GitHub Desktop.
Save wesalvaro/16402a3f3d734de5a6728376bec36439 to your computer and use it in GitHub Desktop.
Adds iteration and simpler filtering to DataTable and DataView objects.
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