Initial commit
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
var _ = require('underscore');
|
||||
var WidgetModel = require('./widgets/widget-model');
|
||||
var CategoryWidgetModel = require('./widgets/category/category-widget-model');
|
||||
var HistogramWidgetModel = require('./widgets/histogram/histogram-widget-model');
|
||||
var TimeSeriesWidgetModel = require('./widgets/time-series/time-series-widget-model');
|
||||
|
||||
var WIDGETSTYLEPARAMS = {
|
||||
auto_style_allowed: 'autoStyleEnabled'
|
||||
};
|
||||
|
||||
// We create an object with options off the attributes
|
||||
var makeWidgetStyleOptions = function (attrs) {
|
||||
return _.reduce(WIDGETSTYLEPARAMS, function (memo, value, key) {
|
||||
if (attrs[key] !== undefined) {
|
||||
memo[value] = attrs[key];
|
||||
return memo;
|
||||
}
|
||||
}, {});
|
||||
};
|
||||
|
||||
var _checkProperties = function (obj, propertiesArray) {
|
||||
_.each(propertiesArray, function (prop) {
|
||||
if (obj[prop] === undefined) {
|
||||
throw new Error(prop + ' is required');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var extendAttrs = function (attrs, state, hasInitialState) {
|
||||
return _.extend(attrs, state, { hasInitialState: hasInitialState }); // Will overwrite preset attributes with the ones passed on the state
|
||||
};
|
||||
|
||||
var checkAnalysisModel = function (attrs) {
|
||||
if (!(attrs.source instanceof Object) || !attrs.source.cid) {
|
||||
throw new Error('Source must be defined and be an instance of AnalysisModel.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Public API to interact with dashboard widgets.
|
||||
*/
|
||||
var WidgetsService = function (widgetsCollection, dataviews) {
|
||||
this._widgetsCollection = widgetsCollection;
|
||||
this._dataviews = dataviews;
|
||||
};
|
||||
|
||||
WidgetsService.prototype.getCollection = function () {
|
||||
return this._widgetsCollection;
|
||||
};
|
||||
|
||||
WidgetsService.prototype.get = function (id) {
|
||||
return this._widgetsCollection.get(id);
|
||||
};
|
||||
|
||||
WidgetsService.prototype.getList = function () {
|
||||
return this._widgetsCollection.models;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} attrs
|
||||
* @param {String} attrs.title Title rendered on the widget view
|
||||
* @param {String} attrs.column Name of column to use to aggregate
|
||||
* @param {String} attrs.aggregation Name of aggregation operation to apply to get categories
|
||||
* can be any of ['sum', 'count']. Default is 'count'
|
||||
* @param {String} attrs.aggregation_column column to be used for the aggregation operation
|
||||
* it only applies for sum operations.
|
||||
* @param {Object} attrs.source Object with the id of the source analysis node that the widget points to
|
||||
* @param {Object} layer Instance of a layer model (cartodb.js)
|
||||
* @return {CategoryWidgetModel}
|
||||
*/
|
||||
WidgetsService.prototype.createCategoryModel = function (attrs, layer, state) {
|
||||
_checkProperties(attrs, ['title']);
|
||||
var extendedAttrs = extendAttrs(attrs, state, this._widgetsCollection.hasInitialState());
|
||||
checkAnalysisModel(extendedAttrs);
|
||||
|
||||
var dataviewModel = this._dataviews.createCategoryModel(extendedAttrs);
|
||||
|
||||
var ATTRS_NAMES = ['id', 'title', 'order', 'collapsed', 'prefix', 'suffix', 'show_stats', 'show_source', 'style', 'hasInitialState'];
|
||||
var widgetAttrs = _.pick(extendedAttrs, ATTRS_NAMES);
|
||||
var options = makeWidgetStyleOptions(extendedAttrs);
|
||||
|
||||
widgetAttrs.attrsNames = ATTRS_NAMES;
|
||||
|
||||
var widgetModel = new CategoryWidgetModel(widgetAttrs, {
|
||||
dataviewModel: dataviewModel,
|
||||
layerModel: layer
|
||||
}, options);
|
||||
widgetModel.setInitialState(state);
|
||||
this._widgetsCollection.add(widgetModel);
|
||||
|
||||
return widgetModel;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} attrs
|
||||
* @param {String} attrs.title Title rendered on the widget view
|
||||
* @param {String} attrs.column Name of column
|
||||
* @param {Number} attrs.bins Count of bins
|
||||
* @param {Object} layer Instance of a layer model (cartodb.js)
|
||||
* @return {WidgetModel}
|
||||
*/
|
||||
WidgetsService.prototype.createHistogramModel = function (attrs, layer, state, opts) {
|
||||
_checkProperties(attrs, ['title']);
|
||||
var extendedAttrs = extendAttrs(attrs, state, this._widgetsCollection.hasInitialState());
|
||||
checkAnalysisModel(extendedAttrs);
|
||||
var dataviewModel = this._dataviews.createHistogramModel(extendedAttrs);
|
||||
|
||||
// Default bins attribute was removed from dataViewModel because of time-series aggregation.
|
||||
// Just in case it's needed for histogram models we added it here.
|
||||
if (!dataviewModel.has('bins')) {
|
||||
dataviewModel.set('bins', 10, { silent: true });
|
||||
}
|
||||
|
||||
var attrsNames = ['id', 'title', 'order', 'collapsed', 'bins', 'show_stats', 'show_source', 'normalized', 'style', 'hasInitialState', 'table_name'];
|
||||
var widgetAttrs = _.pick(extendedAttrs, attrsNames);
|
||||
var options = makeWidgetStyleOptions(extendedAttrs);
|
||||
|
||||
widgetAttrs.type = 'histogram';
|
||||
widgetAttrs.attrsNames = attrsNames;
|
||||
|
||||
var widgetModel = new HistogramWidgetModel(widgetAttrs, {
|
||||
dataviewModel: dataviewModel,
|
||||
layerModel: layer
|
||||
}, options);
|
||||
widgetModel.setInitialState(state);
|
||||
this._widgetsCollection.add(widgetModel);
|
||||
|
||||
return widgetModel;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} attrs
|
||||
* @param {String} attrs.title Title rendered on the widget view
|
||||
* @param {String} attrs.column Name of column
|
||||
* @param {String} attrs.operation Name of operation to use, can be any of ['min', 'max', 'avg', 'sum']
|
||||
* @param {Object} layer Instance of a layer model (cartodb.js)
|
||||
* @return {CategoryWidgetModel}
|
||||
*/
|
||||
WidgetsService.prototype.createFormulaModel = function (attrs, layer, state) {
|
||||
_checkProperties(attrs, ['title']);
|
||||
var extendedAttrs = extendAttrs(attrs, state, this._widgetsCollection.hasInitialState());
|
||||
checkAnalysisModel(extendedAttrs);
|
||||
var dataviewModel = this._dataviews.createFormulaModel(extendedAttrs);
|
||||
|
||||
var ATTRS_NAMES = ['id', 'title', 'order', 'collapsed', 'prefix', 'suffix', 'show_stats', 'show_source', 'description', 'hasInitialState'];
|
||||
var widgetAttrs = _.pick(extendedAttrs, ATTRS_NAMES);
|
||||
widgetAttrs.type = 'formula';
|
||||
widgetAttrs.attrsNames = ATTRS_NAMES;
|
||||
|
||||
var widgetModel = new WidgetModel(widgetAttrs, {
|
||||
dataviewModel: dataviewModel,
|
||||
layerModel: layer
|
||||
});
|
||||
widgetModel.setInitialState(state);
|
||||
this._widgetsCollection.add(widgetModel);
|
||||
|
||||
return widgetModel;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} attrs
|
||||
* @param {String} attrs.column Name of column that contains
|
||||
* @param {Object} layer Instance of a layer model (cartodb.js)
|
||||
* @param {Number} bins
|
||||
* @return {WidgetModel}
|
||||
*/
|
||||
WidgetsService.prototype.createTimeSeriesModel = function (attrs, layer, state, opts) {
|
||||
// TODO will other kind really work for a time-series?
|
||||
attrs.column_type = attrs.column_type || 'date';
|
||||
checkAnalysisModel(attrs);
|
||||
var dataviewModel = this._dataviews.createHistogramModel(attrs);
|
||||
|
||||
var ATTRS_NAMES = ['id', 'style', 'title', 'normalized', 'animated', 'timezone'];
|
||||
var widgetAttrs = _.pick(attrs, ATTRS_NAMES);
|
||||
widgetAttrs.type = 'time-series';
|
||||
widgetAttrs.attrsNames = ATTRS_NAMES;
|
||||
|
||||
var widgetModel = new TimeSeriesWidgetModel(widgetAttrs, {
|
||||
dataviewModel: dataviewModel,
|
||||
layerModel: layer
|
||||
}, opts);
|
||||
widgetModel.setInitialState(state);
|
||||
this._widgetsCollection.add(widgetModel);
|
||||
|
||||
return widgetModel;
|
||||
};
|
||||
|
||||
WidgetsService.prototype.setWidgetsState = function (state) {
|
||||
this._widgetsCollection.setStates(state);
|
||||
};
|
||||
|
||||
module.exports = WidgetsService;
|
||||
Reference in New Issue
Block a user