Initial commit
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
|
||||
module.exports = Backbone.Model.extend({
|
||||
|
||||
defaults: {
|
||||
eventName: '',
|
||||
eventProperties: {}
|
||||
},
|
||||
|
||||
url: function () {
|
||||
return this._configModel.get('base_url') + '/api/v3/metrics';
|
||||
},
|
||||
|
||||
initialize: function (attrs, opts) {
|
||||
if (!opts.configModel) { throw new Error('configModel is required'); }
|
||||
|
||||
this._userId = opts.userId;
|
||||
this._visId = opts.visId;
|
||||
this._configModel = opts.configModel;
|
||||
},
|
||||
|
||||
toJSON: function () {
|
||||
return {
|
||||
name: this.get('eventName'),
|
||||
properties: _.extend(
|
||||
{},
|
||||
this.get('eventProperties'),
|
||||
{
|
||||
visualization_id: this._visId,
|
||||
user_id: this._userId
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
var _ = require('underscore');
|
||||
var MetricsModel = require('./metrics-model');
|
||||
var MetricsTypes = require('./metrics-types');
|
||||
|
||||
/**
|
||||
* Metrics singleton tracker.
|
||||
* It sends any event to metrics endpoint.
|
||||
*/
|
||||
|
||||
module.exports = (function () {
|
||||
return {
|
||||
init: function (opts) {
|
||||
if (!opts || !opts.configModel) { throw new Error('configModel is required'); }
|
||||
|
||||
this._userId = opts.userId;
|
||||
this._visId = opts.visId;
|
||||
this._configModel = opts.configModel;
|
||||
},
|
||||
|
||||
track: function (eventName, eventProperties) {
|
||||
if (!eventName) { throw new Error('eventName is required'); }
|
||||
this._checkEventIsConfigured(eventName);
|
||||
|
||||
var metricModel = new MetricsModel({
|
||||
eventName: eventName,
|
||||
eventProperties: eventProperties
|
||||
}, {
|
||||
userId: this._userId,
|
||||
visId: this._visId,
|
||||
configModel: this._configModel
|
||||
});
|
||||
|
||||
metricModel.save();
|
||||
},
|
||||
|
||||
_checkEventIsConfigured: function (eventName) {
|
||||
var allowed = _.values(MetricsTypes);
|
||||
if (!_.contains(allowed, eventName)) {
|
||||
throw new Error(`"${eventName}" is not an allowed event type`);
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,22 @@
|
||||
// IMPORTANT: Events must be kept in sync with backend!
|
||||
// See `/lib/carto/tracking/events.rb`
|
||||
|
||||
var METRIC_TYPES = {
|
||||
STYLED_BY_VALUE: 'Styled by value',
|
||||
DOWNLOADED_LAYER: 'Downloaded layer',
|
||||
CREATED_LAYER: 'Created Layer',
|
||||
MODIFIED_ANALYSIS: 'Modified analysis',
|
||||
CREATED_ANALYSIS: 'Created analysis',
|
||||
DELETED_ANALYSIS: 'Deleted analysis',
|
||||
DRAGGED_NODE: 'Dragged node',
|
||||
APPLIED_SQL: 'Applied sql',
|
||||
WEBGL_STATS: 'WebGL stats',
|
||||
USED_ADVANCED_MODE: 'Used advanced mode',
|
||||
AGGREGATED_GEOMETRIES: 'Aggregated geometries',
|
||||
MODIFIED_STYLE_FORM: 'Modified Style Form',
|
||||
CHANGED_DEFAULT_GEOMETRY: 'Changed default geometry',
|
||||
APPLIED_CARTOCSS: 'Applied Cartocss',
|
||||
VISITED_PRIVATE_PAGE: 'visited_private_page'
|
||||
};
|
||||
|
||||
module.exports = METRIC_TYPES;
|
||||
@@ -0,0 +1,98 @@
|
||||
|
||||
var MOBILE_DEVICES_REGEX = /Android|webOS|iPad|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
||||
|
||||
function isMobileDevice () {
|
||||
return MOBILE_DEVICES_REGEX.test(navigator.userAgent);
|
||||
}
|
||||
|
||||
function getFBstatus (gl) {
|
||||
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||
switch (status) {
|
||||
case gl.FRAMEBUFFER_COMPLETE:
|
||||
return 'FRAMEBUFFER_COMPLETE';
|
||||
case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
return 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT';
|
||||
case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
return 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT';
|
||||
case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
|
||||
return 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS';
|
||||
case gl.FRAMEBUFFER_UNSUPPORTED:
|
||||
return 'FRAMEBUFFER_UNSUPPORTED';
|
||||
case gl.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
|
||||
return 'FRAMEBUFFER_INCOMPLETE_MULTISAMPLE';
|
||||
case gl.RENDERBUFFER_SAMPLES:
|
||||
return 'RENDERBUFFER_SAMPLES';
|
||||
default:
|
||||
return 'Unkown Framebuffer status';
|
||||
}
|
||||
}
|
||||
|
||||
function getWebGLsupport (canvas) {
|
||||
var support = {
|
||||
webgl1: '?',
|
||||
OES_texture_float: '-',
|
||||
EXT_blend_minmax: '-',
|
||||
MAX_RENDERBUFFER_SIZE: '-',
|
||||
renderToFloat: '-',
|
||||
mobile: isMobileDevice(),
|
||||
userAgent: navigator.userAgent
|
||||
};
|
||||
|
||||
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
|
||||
|
||||
if (!gl) {
|
||||
support.webgl1 = false;
|
||||
return support;
|
||||
} else {
|
||||
support.webgl1 = true;
|
||||
}
|
||||
|
||||
var OES_texture_float = gl.getExtension('OES_texture_float');
|
||||
support.OES_texture_float = !!OES_texture_float;
|
||||
|
||||
var EXT_blend_minmax = gl.getExtension('EXT_blend_minmax');
|
||||
support.EXT_blend_minmax = !!EXT_blend_minmax;
|
||||
|
||||
support.MAX_RENDERBUFFER_SIZE = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
|
||||
|
||||
var aux1x1FB = gl.createFramebuffer();
|
||||
var aux1x1TEX = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, aux1x1TEX);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
|
||||
1, 1, 0, gl.RGBA, gl.FLOAT,
|
||||
null);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, aux1x1FB);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, aux1x1TEX, 0);
|
||||
// Check FB completeness
|
||||
support.renderToFloat = getFBstatus(gl);
|
||||
return support;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getWebGLStats: function () {
|
||||
var testCanvas = document.createElement('canvas');
|
||||
var stats;
|
||||
testCanvas.style.position = 'absolute';
|
||||
testCanvas.style.top = '0';
|
||||
testCanvas.style.left = '0';
|
||||
testCanvas.style.zIndex = '-1';
|
||||
testCanvas.style.width = '1px';
|
||||
testCanvas.style.height = '1px';
|
||||
testCanvas.style.pointerEvents = 'none';
|
||||
document.body.appendChild(testCanvas);
|
||||
|
||||
try {
|
||||
stats = getWebGLsupport(testCanvas);
|
||||
} catch (error) {
|
||||
stats = {
|
||||
error: error
|
||||
};
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user