254 lines
6.8 KiB
JavaScript
254 lines
6.8 KiB
JavaScript
|
var Backbone = require('backbone');
|
||
|
var _ = require('underscore');
|
||
|
var StylesFactory = require('./styles-factory');
|
||
|
var StyleConstants = require('builder/components/form-components/_constants/_style');
|
||
|
var UndoManager = require('builder/data/undo-manager');
|
||
|
|
||
|
module.exports = Backbone.Model.extend({
|
||
|
|
||
|
parse: function (r) {
|
||
|
r = r || {};
|
||
|
return _.extend(
|
||
|
{
|
||
|
type: r.type,
|
||
|
autogenerated: r && r.autogenerated
|
||
|
},
|
||
|
r.properties
|
||
|
);
|
||
|
},
|
||
|
|
||
|
initialize: function (attrs, opts) {
|
||
|
if (!this.get('type')) {
|
||
|
this.setDefaultPropertiesByType(StyleConstants.Type.SIMPLE, 'point' /* geometryType */);
|
||
|
}
|
||
|
|
||
|
UndoManager.init(this, { track: true });
|
||
|
},
|
||
|
|
||
|
resetPropertiesFromAutoStyle: function () {
|
||
|
if (this._stylesPreAutoStyle) {
|
||
|
delete this.attributes.autoStyle;
|
||
|
this.set(this._stylesPreAutoStyle);
|
||
|
this.removeStylesPreAutoStyle();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
removeStylesPreAutoStyle: function () {
|
||
|
delete this._stylesPreAutoStyle;
|
||
|
},
|
||
|
|
||
|
setPropertiesFromAutoStyle: function (params) {
|
||
|
if (!params.definition) throw new Error('definition is required');
|
||
|
if (!params.geometryType) throw new Error('geometryType is required');
|
||
|
if (!params.widgetId) throw new Error('widgetId is required');
|
||
|
|
||
|
if (!this._stylesPreAutoStyle) {
|
||
|
this._stylesPreAutoStyle = JSON.parse(JSON.stringify(this.attributes));
|
||
|
}
|
||
|
|
||
|
// In order to trigger a proper change at the end of this function, we have
|
||
|
// to make a clear change in the attributes, like delete the autoStyle property.
|
||
|
delete this.attributes.autoStyle;
|
||
|
|
||
|
var extendAutoStyleProperties = function (attribute, newProperties) {
|
||
|
var properties = this.get(attribute);
|
||
|
// Check domain quotes
|
||
|
if (newProperties.color && newProperties.color.domain) {
|
||
|
var quotedDomain = _.compact(
|
||
|
_.map(newProperties.color.domain, function (name) {
|
||
|
if (name && name !== true) {
|
||
|
return '"' + name.toString().replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"';
|
||
|
} else {
|
||
|
return name;
|
||
|
}
|
||
|
})
|
||
|
);
|
||
|
newProperties.color.static = true;
|
||
|
newProperties.color.domain = quotedDomain;
|
||
|
newProperties.color.quantification = 'category';
|
||
|
newProperties.color.attribute_type = 'string';
|
||
|
} else {
|
||
|
newProperties.color.bins = newProperties.color.range.length;
|
||
|
newProperties.color.quantification = 'quantiles';
|
||
|
newProperties.color.attribute_type = 'number';
|
||
|
}
|
||
|
|
||
|
properties = _.extend(
|
||
|
properties,
|
||
|
newProperties
|
||
|
);
|
||
|
|
||
|
return properties;
|
||
|
}.bind(this);
|
||
|
|
||
|
var currentAttrs = JSON.parse(JSON.stringify(this.attributes));
|
||
|
var geometryType = params.geometryType;
|
||
|
var definition = params.definition[geometryType];
|
||
|
|
||
|
if (definition) {
|
||
|
if (geometryType === 'line') {
|
||
|
currentAttrs.stroke = extendAutoStyleProperties('stroke', definition);
|
||
|
} else {
|
||
|
currentAttrs.fill = extendAutoStyleProperties('fill', definition);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.set(
|
||
|
_.extend(
|
||
|
{
|
||
|
type: StyleConstants.Type.SIMPLE,
|
||
|
autoStyle: params.widgetId
|
||
|
},
|
||
|
currentAttrs
|
||
|
)
|
||
|
);
|
||
|
},
|
||
|
|
||
|
setDefaultPropertiesByType: function (styleType, geometryType, silently) {
|
||
|
// Get default aggregation and properties from factory and apply them
|
||
|
this.set(
|
||
|
_.extend(
|
||
|
{
|
||
|
type: styleType
|
||
|
},
|
||
|
StylesFactory.getDefaultStyleAttrsByType(styleType, geometryType)
|
||
|
), {
|
||
|
silently: !!silently
|
||
|
}
|
||
|
);
|
||
|
|
||
|
// Although we want to make the change silently, we have several places listening
|
||
|
// for style changes, so we trigger this custom event
|
||
|
if (silently) {
|
||
|
this.trigger('style:update');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
setFill: function (type) {
|
||
|
var simpleFill = StylesFactory.getDefaultStyleAttrsByType(type, 'point');
|
||
|
this.set('fill', simpleFill.fill);
|
||
|
},
|
||
|
|
||
|
applyLastState: function () {
|
||
|
this._undoManager.stopTracking();
|
||
|
this.trigger('change');
|
||
|
this._undoManager.startTracking();
|
||
|
},
|
||
|
|
||
|
resetStyles: function () {
|
||
|
this.setDefaultPropertiesByType(StyleConstants.Type.NONE, '');
|
||
|
},
|
||
|
|
||
|
// Backend will migrate current wizard properties to style properties,
|
||
|
// providing a flag which indicates if it is generated by them
|
||
|
isAutogenerated: function () {
|
||
|
return this.get('autogenerated');
|
||
|
},
|
||
|
|
||
|
isAggregatedType: function () {
|
||
|
return _.contains(StylesFactory.getAggregationTypes(), this.get('type'));
|
||
|
},
|
||
|
|
||
|
isAnimation: function () {
|
||
|
return this.get('type') === StyleConstants.Type.ANIMATION;
|
||
|
},
|
||
|
|
||
|
isHeatmap: function () {
|
||
|
return this.get('type') === StyleConstants.Type.HEATMAP;
|
||
|
},
|
||
|
|
||
|
hasNoneStyles: function () {
|
||
|
return this.get('type') === StyleConstants.Type.NONE;
|
||
|
},
|
||
|
|
||
|
canApplyAutoStyle: function () {
|
||
|
return this.get('type') === StyleConstants.Type.SIMPLE;
|
||
|
},
|
||
|
|
||
|
getColumnsUsedForStyle: function () {
|
||
|
var fillColumns = this._getFillColumns();
|
||
|
var strokeColumns = this._getStrokeColumns();
|
||
|
var labelColumns = this._getLabelColumns();
|
||
|
var aggregationColumns = this._getAggregationColumns();
|
||
|
|
||
|
return [].concat(fillColumns, strokeColumns, labelColumns, aggregationColumns);
|
||
|
},
|
||
|
|
||
|
// Unflatten attributes
|
||
|
toJSON: function () {
|
||
|
return {
|
||
|
type: this.get('type'),
|
||
|
properties: _.omit(this.attributes, 'type', 'autogenerated')
|
||
|
};
|
||
|
},
|
||
|
|
||
|
_getFillColumns: function () {
|
||
|
var columns = [];
|
||
|
|
||
|
var fill = this.get('fill');
|
||
|
if (fill && fill.color && fill.color.attribute) {
|
||
|
columns.push({
|
||
|
name: fill.color.attribute,
|
||
|
type: fill.color.attribute_type || 'string'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (fill && fill.size && fill.size.attribute) {
|
||
|
columns.push({
|
||
|
name: fill.size.attribute,
|
||
|
type: 'number'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return columns;
|
||
|
},
|
||
|
|
||
|
_getStrokeColumns: function () {
|
||
|
var columns = [];
|
||
|
|
||
|
var stroke = this.get('stroke');
|
||
|
if (stroke && stroke.color && stroke.color.attribute) {
|
||
|
columns.push({
|
||
|
name: stroke.color.attribute,
|
||
|
type: stroke.color.attribute_type || 'string'
|
||
|
});
|
||
|
}
|
||
|
if (stroke && stroke.size && stroke.size.attribute) {
|
||
|
columns.push({
|
||
|
name: stroke.size.attribute,
|
||
|
type: 'number'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return columns;
|
||
|
},
|
||
|
|
||
|
_getLabelColumns: function () {
|
||
|
var columns = [];
|
||
|
|
||
|
// Labels
|
||
|
var labels = this.get('labels');
|
||
|
if (labels && labels.attribute && labels.enabled) {
|
||
|
columns.push({
|
||
|
name: labels.attribute
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return columns;
|
||
|
},
|
||
|
|
||
|
_getAggregationColumns: function () {
|
||
|
var columns = [];
|
||
|
|
||
|
var aggregation = this.get('aggregation');
|
||
|
if (aggregation && aggregation.value && aggregation.value.attribute) {
|
||
|
columns.push({
|
||
|
name: aggregation.value.attribute,
|
||
|
type: aggregation.value.attribute_type || 'string'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return columns;
|
||
|
}
|
||
|
});
|