UNPKG

universe

Version:

The fastest way to query and explore multivariate datasets

115 lines (100 loc) 3.43 kB
'use strict' var Promise = require('q') var _ = require('./lodash') var aggregation = require('./aggregation') module.exports = function (/* service */) { return { post: post, sortByKey: sortByKey, limit: limit, squash: squash, change: change, changeMap: changeMap, } function post(query, parent, cb) { query.data = cloneIfLocked(parent) return Promise.resolve(cb(query, parent)) } function sortByKey(query, parent, desc) { query.data = cloneIfLocked(parent) query.data = _.sortBy(query.data, function (d) { return d.key }) if (desc) { query.data.reverse() } } // Limit results to n, or from start to end function limit(query, parent, start, end) { query.data = cloneIfLocked(parent) if (_.isUndefined(end)) { end = start || 0 start = 0 } else { start = start || 0 end = end || query.data.length } query.data = query.data.splice(start, end - start) } // Squash results to n, or from start to end function squash(query, parent, start, end, aggObj, label) { query.data = cloneIfLocked(parent) start = start || 0 end = end || query.data.length var toSquash = query.data.splice(start, end - start) var squashed = { key: label || 'Other', value: {}, } _.recurseObject(aggObj, function (val, key, path) { var items = [] _.forEach(toSquash, function (record) { items.push(_.get(record.value, path)) }) _.set(squashed.value, path, aggregation.aggregators[val](items)) }) query.data.splice(start, 0, squashed) } function change(query, parent, start, end, aggObj) { query.data = cloneIfLocked(parent) start = start || 0 end = end || query.data.length var obj = { key: [query.data[start].key, query.data[end].key], value: {}, } _.recurseObject(aggObj, function (val, key, path) { var changePath = _.clone(path) changePath.pop() changePath.push(key + 'Change') _.set(obj.value, changePath, _.get(query.data[end].value, path) - _.get(query.data[start].value, path)) }) query.data = obj } function changeMap(query, parent, aggObj, defaultNull) { defaultNull = _.isUndefined(defaultNull) ? 0 : defaultNull query.data = cloneIfLocked(parent) _.recurseObject(aggObj, function (val, key, path) { var changePath = _.clone(path) var fromStartPath = _.clone(path) var fromEndPath = _.clone(path) changePath.pop() fromStartPath.pop() fromEndPath.pop() changePath.push(key + 'Change') fromStartPath.push(key + 'ChangeFromStart') fromEndPath.push(key + 'ChangeFromEnd') var start = _.get(query.data[0].value, path, defaultNull) var end = _.get(query.data[query.data.length - 1].value, path, defaultNull) _.forEach(query.data, function (record, i) { var previous = query.data[i - 1] || query.data[0] _.set(query.data[i].value, changePath, _.get(record.value, path, defaultNull) - (previous ? _.get(previous.value, path, defaultNull) : defaultNull)) _.set(query.data[i].value, fromStartPath, _.get(record.value, path, defaultNull) - start) _.set(query.data[i].value, fromEndPath, _.get(record.value, path, defaultNull) - end) }) }) } } function cloneIfLocked(parent) { return parent.locked ? _.clone(parent.data) : parent.data }