Initial commit
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
var _ = require('underscore');
|
||||
var cdb = require('internal-carto.js');
|
||||
var AutoStylerFactory = require('./auto-style/factory');
|
||||
|
||||
var TIME_SERIES_TYPE = 'time-series';
|
||||
var HISTOGRAM_TYPE = 'histogram';
|
||||
|
||||
/**
|
||||
* Default widget model
|
||||
*
|
||||
* Note: Currently all widgets have a dependency on a dataview, why it makes sense to have it here.
|
||||
* If you need a widget model that's backed up by a dataview model please implement your own model and adhere to the
|
||||
* public interface instead of extending/hacking this one.
|
||||
*/
|
||||
module.exports = cdb.core.Model.extend({
|
||||
defaults: {
|
||||
attrsNames: [],
|
||||
show_stats: false,
|
||||
show_source: false
|
||||
},
|
||||
|
||||
defaultState: {
|
||||
'collapsed': false
|
||||
},
|
||||
|
||||
initialize: function (attrs, models, opts) {
|
||||
opts = opts || {};
|
||||
if (!models.dataviewModel) throw new Error('dataviewModel is required.');
|
||||
if (!models.layerModel) throw new Error('layerModel is required.');
|
||||
|
||||
this.dataviewModel = models.dataviewModel;
|
||||
this.layerModel = models.layerModel;
|
||||
|
||||
// Autostyle could be disabled initially if the styles have an aggregation
|
||||
// If no option, autoStyleEnabled by default
|
||||
this._autoStyleEnabledWhenCreated = opts.autoStyleEnabled === undefined ? true : opts.autoStyleEnabled;
|
||||
|
||||
this.activeAutoStyler();
|
||||
this.listenTo(this, 'change:style', this.activeAutoStyler);
|
||||
},
|
||||
|
||||
activeAutoStyler: function () {
|
||||
if (this.isAutoStyleEnabled() && !this.autoStyler) {
|
||||
this.autoStyler = AutoStylerFactory.get(this.dataviewModel, this.layerModel, this.get('style'));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @param {Object} attrs, not that it should be
|
||||
* @return {Boolean} true if at least one attribute was changed
|
||||
* @throws {Error} Should throw an error if the attrs are invalid or inconsistent
|
||||
*/
|
||||
update: function (attrs) {
|
||||
var wAttrs = _.pick(attrs, this.get('attrsNames'));
|
||||
this.set(wAttrs);
|
||||
this.dataviewModel.update(attrs);
|
||||
this._triggerChangesInAutoStyle();
|
||||
return !!(this.changedAttributes() || this.dataviewModel.changedAttributes());
|
||||
},
|
||||
|
||||
_triggerChangesInAutoStyle: function () {
|
||||
var changed = this.changed && this.changed.style && this.changed.style.auto_style && this.changed.style.auto_style.definition;
|
||||
var previous = this.previousAttributes();
|
||||
var former = previous.style && previous.style.auto_style && previous.style.auto_style.definition;
|
||||
|
||||
if (!_.isEqual(changed, former)) {
|
||||
this.trigger('customAutoStyle', this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
remove: function () {
|
||||
this.dataviewModel.remove();
|
||||
this.trigger('destroy', this);
|
||||
this.stopListening();
|
||||
},
|
||||
|
||||
isAutoStyleEnabled: function () {
|
||||
var styles = this.get('style');
|
||||
|
||||
if (this.get('type') === 'category' || this.get('type') === 'histogram') {
|
||||
if (!styles || !styles.auto_style) {
|
||||
// Only when styles are undefined we check the autostyle option
|
||||
return this._autoStyleEnabledWhenCreated;
|
||||
}
|
||||
|
||||
return styles && styles.auto_style && styles.auto_style.allowed;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
getWidgetColor: function () {
|
||||
var styles = this.get('style');
|
||||
var widgetStyle = styles && styles.widget_style;
|
||||
var widgetColor = widgetStyle && widgetStyle.definition &&
|
||||
widgetStyle.definition.color &&
|
||||
widgetStyle.definition.color.fixed;
|
||||
var widgetColorChanged = (widgetStyle && widgetStyle.widget_color_changed) ||
|
||||
(widgetStyle && !widgetStyle.widget_color_changed && widgetColor !== '#9DE0AD');
|
||||
|
||||
return widgetColorChanged && widgetColor;
|
||||
},
|
||||
|
||||
hasColorsAutoStyle: function () {
|
||||
var autoStyle = this.getAutoStyle();
|
||||
var hasDefinedColors = false;
|
||||
|
||||
if (!autoStyle || _.isEmpty(autoStyle) || _.isEmpty(autoStyle.definition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check colors in all geometries
|
||||
_.each(autoStyle.definition, function (geometryStyle) {
|
||||
if (geometryStyle.color && geometryStyle.color.range && geometryStyle.color.range.length > 0) {
|
||||
hasDefinedColors = true;
|
||||
}
|
||||
}, this);
|
||||
|
||||
return hasDefinedColors;
|
||||
},
|
||||
|
||||
getColor: function (name) {
|
||||
if (this.isAutoStyleEnabled() && this.isAutoStyle() && this.get('type') === 'category') {
|
||||
return this.autoStyler.colors.getColorByCategory(name);
|
||||
} else {
|
||||
return this.getWidgetColor();
|
||||
}
|
||||
},
|
||||
|
||||
isAutoStyle: function () {
|
||||
return this.get('autoStyle');
|
||||
},
|
||||
|
||||
autoStyle: function () {
|
||||
if (!this.isAutoStyleEnabled()) return;
|
||||
if (!this.dataForAutoStyle()) return;
|
||||
|
||||
var layer = this.layerModel;
|
||||
var initialStyle = layer.get('cartocss');
|
||||
if (!initialStyle && layer.get('meta')) {
|
||||
initialStyle = layer.get('meta').cartocss;
|
||||
}
|
||||
layer.set('initialStyle', initialStyle);
|
||||
|
||||
var style = this.autoStyler.getStyle();
|
||||
layer.set('cartocss', style);
|
||||
this.set('autoStyle', true);
|
||||
},
|
||||
|
||||
dataForAutoStyle: function () {
|
||||
return this.dataviewModel.get('data').length > 0;
|
||||
},
|
||||
|
||||
reapplyAutoStyle: function () {
|
||||
var style = this.autoStyler.getStyle();
|
||||
this.layerModel.set('cartocss', style);
|
||||
this.set('autoStyle', true);
|
||||
},
|
||||
|
||||
cancelAutoStyle: function (noRestore) {
|
||||
if (!noRestore) {
|
||||
this.layerModel.restoreCartoCSS();
|
||||
}
|
||||
this.set('autoStyle', false);
|
||||
},
|
||||
|
||||
getAutoStyle: function () {
|
||||
var style = this.get('style');
|
||||
var layerModel = this.layerModel;
|
||||
var cartocss = layerModel.get('cartocss') || (layerModel.get('meta') && layerModel.get('meta').cartocss);
|
||||
|
||||
if (this.isAutoStyleEnabled() && this.autoStyler) {
|
||||
if (style && style.auto_style && style.auto_style.definition) {
|
||||
var toRet = _.extend(style.auto_style, {cartocss: cartocss});
|
||||
return _.extend({}, toRet, {definition: this.autoStyler.getDef(cartocss)});
|
||||
} else {
|
||||
return {
|
||||
definition: this.autoStyler.getDef(cartocss),
|
||||
cartocss: cartocss
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
|
||||
_updateAutoStyle: function (_model, style) {
|
||||
if (this.autoStyler) {
|
||||
this.autoStyler.updateStyle(style);
|
||||
}
|
||||
if (this.isAutoStyle()) {
|
||||
this.reapplyAutoStyle();
|
||||
}
|
||||
},
|
||||
|
||||
setInitialState: function (state) {
|
||||
this.initialState = state || {};
|
||||
},
|
||||
|
||||
applyInitialState: function () {
|
||||
var attrs = _.extend(
|
||||
this.initialState,
|
||||
{hasInitialState: true}
|
||||
);
|
||||
|
||||
this.setState(attrs);
|
||||
},
|
||||
|
||||
setState: function (state) {
|
||||
this.set(state);
|
||||
},
|
||||
|
||||
getState: function () {
|
||||
var state = {};
|
||||
for (var key in this.defaultState) {
|
||||
var attribute = this.get(key);
|
||||
var defaultValue = this.defaultState[key];
|
||||
if (typeof defaultValue !== 'undefined' && typeof attribute !== 'undefined' && !_.isEqual(attribute, defaultValue)) {
|
||||
state[key] = attribute;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
},
|
||||
|
||||
forceResize: function () {
|
||||
var type = this.get('type');
|
||||
if (type === TIME_SERIES_TYPE ||
|
||||
type === HISTOGRAM_TYPE) {
|
||||
this.trigger('forceResize');
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user