event updates - query uipdate

beta.r3js.org
cybafelo 2019-11-19 15:06:49 +01:00
parent 1f85c4e7dd
commit af670273c4
42 changed files with 786 additions and 384 deletions

View File

@ -10,7 +10,6 @@ R3.Event = function() {
* @type {{}} * @type {{}}
*/ */
R3.Event.Subscriptions = {}; R3.Event.Subscriptions = {};
R3.Event.OnceSubscriptions = {};
/** /**
* Subscribe to some events * Subscribe to some events
@ -24,46 +23,6 @@ R3.Event.prototype.subscribe = function(
return R3.Event.Subscribe(eventName, callback.bind(this)); return R3.Event.Subscribe(eventName, callback.bind(this));
}; };
// /**
// * Stop listening for this event after the callback returns true
// * @param eventName
// * @param callback
// * @returns {{fn, remove: remove}}
// */
// R3.Event.prototype.subscribeOnce = function(
// eventName,
// callback
// ) {
// throw new Error('implement first properly');
// // var fn = callback.bind(this);
// //
// // if (R3.Event.OnceSubscriptions.hasOwnProperty(eventName)) {
// // R3.Event.OnceSubscriptions[eventName].push(fn);
// // } else {
// // R3.Event.OnceSubscriptions[eventName] = [];
// // R3.Event.OnceSubscriptions[eventName].push(fn);
// // }
// //
// // /**
// // * Return a handle to the caller to allow us to unsubscribe to this event
// // */
// // return {
// // fn : fn,
// // remove : function() {
// // R3.Event.Subscriptions[eventName].splice(
// // R3.Event.Subscriptions[eventName].indexOf(fn),
// // 1
// // );
// // }
// // }
// };
/**
*
* @param eventName
* @param data
*/
/** /**
* Publish some event happened with some data * Publish some event happened with some data
* @param eventName * @param eventName
@ -87,8 +46,8 @@ R3.Event.prototype.emit = function(
}; };
/** /**
* Static method call * Static Synchrnonous Event - Calls clientCallback directly after the event result is obtained
* @param eventName * @param eventId
* @param data * @param data
* @param clientCallback is executed ideally when the event completed * @param clientCallback is executed ideally when the event completed
* @param clientErrorCallback * @param clientErrorCallback
@ -96,111 +55,41 @@ R3.Event.prototype.emit = function(
* @constructor * @constructor
*/ */
R3.Event.Emit = function( R3.Event.Emit = function(
eventName, eventId,
data, data,
clientCallback, clientCallback,
clientErrorCallback clientErrorCallback
) { ) {
var count = 0; if (R3.Event.Subscriptions.hasOwnProperty(eventId)) {
if (R3.Event.Subscriptions.hasOwnProperty(eventName)) { var subscriptionIds = Object.keys(R3.Event.Subscriptions[eventId]);
if (R3.Event.Subscriptions[eventName].length === 0) { subscriptionIds.map(
function(subscriptionId) {
if (clientCallback) { try {
/** var result = R3.Event.Subscriptions[eventId][subscriptionId](data);
* We execute the client callback immediately since there are no subscriptions to this event
*/
clientCallback();
}
if (clientErrorCallback) {
clientErrorCallback({
message : 'No subscriptions for event ' + eventName
})
}
}
/**
* We need to execute all the callbacks, but not execute them twice, but also keep in mind they can remove
* themselves during execution
*/
// var length = R3.Event.Subscriptions[eventName].length;
//
// for (var i = 0; i < length; i++) {
//
// var object = R3.Event.Subscriptions[eventName][i];
//
// if (object.fn && object.executed === false) {
// object.fn(data, clientCallback, clientErrorCallback);
// object.executed = true;
// }
//
// if (length !== R3.Event.Subscriptions[eventName].length) {
// /**
// * this callback removed a subscription - reset i and reset the length
// */
// i = 0;
// length = R3.Event.Subscriptions[eventName].length;
// }
// }
//
// R3.Event.Subscriptions[eventName].map(
// function(object){
// object.executed = false;
// }
// )
R3.Event.Subscriptions[eventName].map(
function(subscription) {
if (subscription) {
try {
var result = subscription(data, clientCallback, clientErrorCallback);
} catch (error) {
if (clientErrorCallback) {
try {
clientErrorCallback(error);
} catch (error2) {
console.error('failed to execute client callback error:', error2);
}
}
return;
}
if (clientCallback) { if (clientCallback) {
clientCallback(result); clientCallback(result);
} }
count++; } catch (error) {
if (clientErrorCallback) {
clientErrorCallback(error);
} else {
console.error(error);
}
} }
} }
) )
} else {
if (clientCallback) {
/**
* We execute the client callback immediately since there are no subscriptions to this event
*/
clientCallback();
}
if (clientErrorCallback) {
clientErrorCallback({
message : 'No subscriptions for event ' + eventName
})
}
} }
return count;
}; };
/** /**
* Execute the functions which subscribe to this event, but don't process the client callback - the subscription function * Execute the functions which subscribe to this event, but don't process the client callback - the subscription function
* should execute the client callback * should execute the client callback
* @param eventName * @param eventId
* @param data * @param data
* @param clientCallback * @param clientCallback
* @param clientErrorCallback * @param clientErrorCallback
@ -208,76 +97,78 @@ R3.Event.Emit = function(
* @constructor * @constructor
*/ */
R3.Event.Async = function( R3.Event.Async = function(
eventName, eventId,
data, data,
clientCallback, clientCallback,
clientErrorCallback clientErrorCallback
) { ) {
if (R3.Event.Subscriptions.hasOwnProperty(eventId)) {
var count = 0; var subscriptionIds = Object.keys(R3.Event.Subscriptions[eventId]);
if (R3.Event.Subscriptions.hasOwnProperty(eventName)) { subscriptionIds.map(
R3.Event.Subscriptions[eventName].map( function(subscriptionId) {
function(subscription) { try {
if (subscription) { R3.Event.Subscriptions[eventId][subscriptionId](data, clientCallback, clientErrorCallback);
subscription(data, clientCallback, clientErrorCallback); } catch (error) {
count++; if (clientErrorCallback) {
clientErrorCallback(error);
} else {
console.error(error);
}
} }
} }
) )
} }
return count;
}; };
R3.Event.Subscribe = function( R3.Event.Subscribe = function(
eventName, eventName,
fn fn,
) { ) {
/**
* Todo - maybe eventually store a boolean which indicates if the function has been executed
*/
var subscriptionId = R3.Utils.RandomId(10);
if (R3.Event.Subscriptions.hasOwnProperty(eventName)) { if (R3.Event.Subscriptions.hasOwnProperty(eventName)) {
R3.Event.Subscriptions[eventName].push(fn);
// { if (R3.Event.Subscriptions[eventName][subscriptionId]) {
// fn : fn, throw new Error('A component can only subscribe to a particular event ID once');
// executed : false }
// }
// ); R3.Event.Subscriptions[eventName][subscriptionId] = fn;
} else { } else {
R3.Event.Subscriptions[eventName] = []; R3.Event.Subscriptions[eventName] = {};
R3.Event.Subscriptions[eventName].push(fn); R3.Event.Subscriptions[eventName][subscriptionId] = fn;
// {
// fn : fn,
// executed : false
// }
// );
} }
/** /**
* Return a handle to the caller to allow us to unsubscribe to this event * Return a handle to the caller to allow us to unsubscribe to this event
*/ */
return { return {
fn : fn, fn: fn,
remove : function() { remove: function (eventId, subscriptionId) {
var index = R3.Event.Subscriptions[eventName].indexOf(fn); return function () {
// reduce(
// function(result, object, index) {
// if (object.fn === fn) {
// result = index;
// }
// return result;
// },
// -1
// );
if (index === -1) { /**
throw new Error('could not remove subscription'); * Stop listening for this event from this component
*/
delete R3.Event.Subscriptions[eventId][subscriptionId];
/**
* If the length of listeners is 0, stop referencing this event
* @type {string[]}
*/
var listeners = Object.keys(R3.Event.Subscriptions[eventId]);
if (listeners.length === 0) {
delete R3.Event.Subscriptions[eventId];
}
} }
R3.Event.Subscriptions[eventName].splice( }(eventName, subscriptionId),
index, subscriptionId : subscriptionId
1 };
);
}
}
}; };

View File

@ -84,37 +84,40 @@ R3.Event.PAUSE = 0x53;
R3.Event.PAUSE_ALL_AUDIO = 0x54; R3.Event.PAUSE_ALL_AUDIO = 0x54;
R3.Event.PLAY_AUDIO = 0x55; R3.Event.PLAY_AUDIO = 0x55;
R3.Event.PROJECT_LOADED = 0x56; R3.Event.PROJECT_LOADED = 0x56;
R3.Event.QUERY_PARSED = 0x57; R3.Event.QUERY = 0x57;
R3.Event.RECEIVE_DESTINATION_CHANGED = 0x58; R3.Event.QUERY_INTERVAL_CHANGE = 0x58;
R3.Event.REGISTER_DEPENDENCIES = 0x59; R3.Event.QUERY_PARSED = 0x59;
R3.Event.REGISTER_UPDATE = 0x5a; R3.Event.RECEIVE_DESTINATION_CHANGED = 0x5a;
R3.Event.REMOVE_COMPONENT = 0x5b; R3.Event.REGISTER_COMPONENT = 0x5b;
R3.Event.REMOVE_MESH = 0x5c; R3.Event.REGISTER_DEPENDENCIES = 0x5c;
R3.Event.REMOVE_PARTICLE_ENGINE = 0x5d; R3.Event.REGISTER_UPDATE = 0x5d;
R3.Event.RENDERER_SIZE_CHANGE = 0x5e; R3.Event.REMOVE_COMPONENT = 0x5e;
R3.Event.REPLACE_COMPONENT = 0x5f; R3.Event.REMOVE_MESH = 0x5f;
R3.Event.RESOLVE_DEPENDENCIES = 0x60; R3.Event.REMOVE_PARTICLE_ENGINE = 0x60;
R3.Event.RESTART = 0x61; R3.Event.RENDERER_SIZE_CHANGE = 0x61;
R3.Event.SAVE_COMPONENT = 0x62; R3.Event.REPLACE_COMPONENT = 0x62;
R3.Event.SAVE_COMPONENT_ERROR = 0x63; R3.Event.RESOLVE_DEPENDENCIES = 0x63;
R3.Event.SAVING = 0x64; R3.Event.RESTART = 0x64;
R3.Event.SELECTION_MODE_CHANGE = 0x65; R3.Event.SAVE_COMPONENT = 0x65;
R3.Event.SIGN_IN = 0x66; R3.Event.SAVE_COMPONENT_ERROR = 0x66;
R3.Event.SIGN_OUT = 0x67; R3.Event.SAVING = 0x67;
R3.Event.START = 0x68; R3.Event.SELECTION_MODE_CHANGE = 0x68;
R3.Event.STOP_ALL_AUDIO = 0x69; R3.Event.SIGN_IN = 0x69;
R3.Event.STOP_AUDIO = 0x6a; R3.Event.SIGN_OUT = 0x6a;
R3.Event.STOP_VISUALIZE = 0x6b; R3.Event.START = 0x6b;
R3.Event.TEXTURE_ANIMATED_CHANGE = 0x6c; R3.Event.STOP_ALL_AUDIO = 0x6c;
R3.Event.TEXTURE_INSTANCE_UPDATED = 0x6d; R3.Event.STOP_AUDIO = 0x6d;
R3.Event.TOUCH_CANCEL = 0x6e; R3.Event.STOP_VISUALIZE = 0x6e;
R3.Event.TOUCH_END = 0x6f; R3.Event.TEXTURE_ANIMATED_CHANGE = 0x6f;
R3.Event.TOUCH_MOVE = 0x70; R3.Event.TEXTURE_INSTANCE_UPDATED = 0x70;
R3.Event.TOUCH_START = 0x71; R3.Event.TOUCH_CANCEL = 0x71;
R3.Event.UNRESOLVED_DEPENDENCIES_UPDATE = 0x72; R3.Event.TOUCH_END = 0x72;
R3.Event.VISUALIZE = 0x73; R3.Event.TOUCH_MOVE = 0x73;
R3.Event.WINDOW_RESIZE = 0x74; R3.Event.TOUCH_START = 0x74;
R3.Event.MAX_EVENTS = 0x75; R3.Event.UNRESOLVED_DEPENDENCIES_UPDATE = 0x75;
R3.Event.VISUALIZE = 0x76;
R3.Event.WINDOW_RESIZE = 0x77;
R3.Event.MAX_EVENTS = 0x78;
/** /**
* R3.Event.GetEventName * R3.Event.GetEventName
@ -211,36 +214,39 @@ R3.Event.GetEventName = function(eventId) {
case 0x54 : return 'pause_all_audio'; case 0x54 : return 'pause_all_audio';
case 0x55 : return 'play_audio'; case 0x55 : return 'play_audio';
case 0x56 : return 'project_loaded'; case 0x56 : return 'project_loaded';
case 0x57 : return 'query_parsed'; case 0x57 : return 'query';
case 0x58 : return 'receive_destination_changed'; case 0x58 : return 'query_interval_change';
case 0x59 : return 'register_dependencies'; case 0x59 : return 'query_parsed';
case 0x5a : return 'register_update'; case 0x5a : return 'receive_destination_changed';
case 0x5b : return 'remove_component'; case 0x5b : return 'register_component';
case 0x5c : return 'remove_mesh'; case 0x5c : return 'register_dependencies';
case 0x5d : return 'remove_particle_engine'; case 0x5d : return 'register_update';
case 0x5e : return 'renderer_size_change'; case 0x5e : return 'remove_component';
case 0x5f : return 'replace_component'; case 0x5f : return 'remove_mesh';
case 0x60 : return 'resolve_dependencies'; case 0x60 : return 'remove_particle_engine';
case 0x61 : return 'restart'; case 0x61 : return 'renderer_size_change';
case 0x62 : return 'save_component'; case 0x62 : return 'replace_component';
case 0x63 : return 'save_component_error'; case 0x63 : return 'resolve_dependencies';
case 0x64 : return 'saving'; case 0x64 : return 'restart';
case 0x65 : return 'selection_mode_change'; case 0x65 : return 'save_component';
case 0x66 : return 'sign_in'; case 0x66 : return 'save_component_error';
case 0x67 : return 'sign_out'; case 0x67 : return 'saving';
case 0x68 : return 'start'; case 0x68 : return 'selection_mode_change';
case 0x69 : return 'stop_all_audio'; case 0x69 : return 'sign_in';
case 0x6a : return 'stop_audio'; case 0x6a : return 'sign_out';
case 0x6b : return 'stop_visualize'; case 0x6b : return 'start';
case 0x6c : return 'texture_animated_change'; case 0x6c : return 'stop_all_audio';
case 0x6d : return 'texture_instance_updated'; case 0x6d : return 'stop_audio';
case 0x6e : return 'touch_cancel'; case 0x6e : return 'stop_visualize';
case 0x6f : return 'touch_end'; case 0x6f : return 'texture_animated_change';
case 0x70 : return 'touch_move'; case 0x70 : return 'texture_instance_updated';
case 0x71 : return 'touch_start'; case 0x71 : return 'touch_cancel';
case 0x72 : return 'unresolved_dependencies_update'; case 0x72 : return 'touch_end';
case 0x73 : return 'visualize'; case 0x73 : return 'touch_move';
case 0x74 : return 'window_resize'; case 0x74 : return 'touch_start';
case 0x75 : return 'unresolved_dependencies_update';
case 0x76 : return 'visualize';
case 0x77 : return 'window_resize';
default : default :
throw new Error('Event type not defined : ' + eventId); throw new Error('Event type not defined : ' + eventId);
} }

View File

@ -5,6 +5,7 @@
* @param name * @param name
* @param register * @param register
* @param selected * @param selected
* @param isPublic
* @constructor * @constructor
*/ */
R3.API.Component = function( R3.API.Component = function(

View File

@ -25,6 +25,28 @@ R3.Utils.GetFirstParent = function(object, constructor) {
}; };
R3.Utils.SyntaxHighlight = function(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
};
R3.Utils.GetParentProject = function(component) { R3.Utils.GetParentProject = function(component) {
if (R3.Utils.UndefinedOrNull(component.parent)) { if (R3.Utils.UndefinedOrNull(component.parent)) {

View File

@ -30,6 +30,17 @@ R3.Component = function() {
this.instanceCreated.bind(this) this.instanceCreated.bind(this)
); );
/**
* This component, no doubt - is a parent to some other components.
* We register this component with the EntityManager, so it can link the parent property of all
* this component's child components to this
*/
R3.Event.Emit(
R3.Event.REGISTER_COMPONENT,
this
);
this.buildVectoredComponents(); this.buildVectoredComponents();
this.buildLinkedComponents(); this.buildLinkedComponents();
@ -198,7 +209,7 @@ R3.Component.prototype.instanceCreated = function(data) {
/** /**
* Ignore components with no parent * Ignore components with no parent
*/ */
if (data.component.parent === null) { if (R3.Utils.UndefinedOrNull(data.component.parent)) {
return; return;
} }
@ -361,6 +372,7 @@ R3.Component.prototype.buildLinkedComponents = function() {
*/ */
this[property] = this[property].reduce( this[property] = this[property].reduce(
function (component, _property) { function (component, _property) {
return function (result, item, index) { return function (result, item, index) {
@ -379,7 +391,7 @@ R3.Component.prototype.buildLinkedComponents = function() {
componentId: item, componentId: item,
}, },
function (__component, __property, __index, __id, __dependencyString) { function (__component, __property, __index, __id, __dependencyString) {
return function (data) { return function (rawComponent) {
if (R3.Utils.UndefinedOrNull(__component[__property])) { if (R3.Utils.UndefinedOrNull(__component[__property])) {
throw new Error('The component took too long to load and the component property was damaged: ' + R3.GetComponentName(__component) + '.' + __property); throw new Error('The component took too long to load and the component property was damaged: ' + R3.GetComponentName(__component) + '.' + __property);
@ -393,7 +405,9 @@ R3.Component.prototype.buildLinkedComponents = function() {
throw new Error('The component loaded however it no longer exists as an id: ' + R3.GetComponentName(__component) + '.' + __property + '[' + __index + '] !==' + __id); throw new Error('The component loaded however it no longer exists as an id: ' + R3.GetComponentName(__component) + '.' + __property + '[' + __index + '] !==' + __id);
} }
__component[__property][__index] = data.component; var Constructor = R3.GetConstructorFromComponentType(rawComponent.componentType);
__component[__property][__index] = new Constructor(rawComponent);
var deleteIndex = __component.dependencies.indexOf(__dependencyString); var deleteIndex = __component.dependencies.indexOf(__dependencyString);
@ -410,12 +424,12 @@ R3.Component.prototype.buildLinkedComponents = function() {
} }
} }
}(this, _property, index, item, dependencyString), }(component, _property, index, item, dependencyString),
function (component, __property) { function (__component, __property) {
return function (error) { return function (__error) {
console.error('Failed to load ' + R3.GetComponentName(component) + '.' + __property + ' because of ' + error); console.error('Failed to load ' + R3.GetComponentName(__component) + '.' + __property + ' because of ' + __error);
}; };
}(this, _property) }(component, _property)
); );
result.push(item); result.push(item);
@ -474,6 +488,7 @@ R3.Component.prototype.buildLinkedComponents = function() {
throw new Error('Unhandled situation - could not process : ' + R3.GetComponentName(component) + '.' + _property + '[' + index + ']'); throw new Error('Unhandled situation - could not process : ' + R3.GetComponentName(component) + '.' + _property + '[' + index + ']');
}; };
}(this, property), }(this, property),
[] []
); );
@ -489,7 +504,7 @@ R3.Component.prototype.buildLinkedComponents = function() {
/** /**
* This object is not loaded yet - we should notify (a storage system perhaps) that it should be loaded and add it as a dependency * This object is not loaded yet - we should notify (a storage system perhaps) that it should be loaded and add it as a dependency
*/ */
var dependencyString = R3.GetComponentName(component) + '.' + _property + '(' + this[property] + ')'; var dependencyString = R3.GetComponentName(this) + '.' + property + '(' + this[property] + ')';
R3.Utils.PushUnique(this.dependencies, dependencyString); R3.Utils.PushUnique(this.dependencies, dependencyString);
R3.Event.Async( R3.Event.Async(
@ -497,36 +512,40 @@ R3.Component.prototype.buildLinkedComponents = function() {
{ {
componentId: this[property], componentId: this[property],
}, },
function (component, _property, _id, _dependencyString) { function (__component, __property, __id, __dependencyString) {
return function (data) {
if (R3.Utils.UndefinedOrNull(component[_property])) { return function (rawComponent) {
throw new Error('The component took too long to load and the component property was damaged: ' + R3.GetComponentName(component) + '.' + _property);
if (R3.Utils.UndefinedOrNull(__component[__property])) {
throw new Error('The component took too long to load and the component property was damaged: ' + R3.GetComponentName(__component) + '.' + __property);
} }
if (component[_property] !== _id) { if (__component[__property] !== __id) {
throw new Error('The component loaded however it no longer exists as an id: ' + R3.GetComponentName(component) + '.' + _property + ' !==' + _id); throw new Error('The component loaded however it no longer exists as an id: ' + R3.GetComponentName(__component) + '.' + __property + ' !==' + __id);
} }
component[_property] = data.component; var Constructor = R3.GetConstructorFromComponentType(rawComponent.componentType);
var deleteIndex = component.dependencies.indexOf(_dependencyString); __component[__property] = new Constructor(rawComponent);
var deleteIndex = __component.dependencies.indexOf(__dependencyString);
if (deleteIndex === -1) { if (deleteIndex === -1) {
throw new Error('The dependency ' + _dependencyString + ' was removed during the time that the component was loading'); throw new Error('The dependency ' + __dependencyString + ' was removed during the time that the component was loading');
} }
component.dependencies = component.dependencies.splice(deleteIndex, 1); __component.dependencies = __component.dependencies.splice(deleteIndex, 1);
if (component.dependencies.length === 0) { if (__component.dependencies.length === 0) {
component.performInstanceCreation(); __component.performInstanceCreation();
} }
} }
}(this, property, this[property], dependencyString), }(this, property, this[property], dependencyString),
function (component, _property) { function (__component, __property) {
return function (error) { return function (__error) {
console.error('Failed to load ' + R3.GetComponentName(component) + '.' + _property + ' because of ' + error); console.error('Failed to load ' + R3.GetComponentName(__component) + '.' + __property + ' because of ' + __error);
}; };
}(this, property) }(this, property)
); );
@ -623,17 +642,6 @@ R3.Component.prototype.createInstance = function() {
this.loaded = true; this.loaded = true;
/**
* Use this event to know that the object has now loaded and all 'INSTANCE_CREATED' events have been handled.
* The idToObject property of this component can now be trusted.
*/
R3.Event.Emit(
R3.Event.INSTANCE_LOADED,
{
component: this
}
);
if (this instanceof R3.Project) { if (this instanceof R3.Project) {
R3.Event.Emit( R3.Event.Emit(
R3.Event.PROJECT_LOADED, R3.Event.PROJECT_LOADED,
@ -652,6 +660,16 @@ R3.Component.prototype.createInstance = function() {
) )
} }
/**
* Use this event to know that the object has now loaded and all 'INSTANCE_CREATED' events have been handled.
* The idToObject property of this component can now be trusted.
*/
R3.Event.Emit(
R3.Event.INSTANCE_LOADED,
{
component: this
}
);
}; };
R3.Component.prototype.updateInstance = function(property) { R3.Component.prototype.updateInstance = function(property) {

View File

@ -27,6 +27,11 @@ R3.API.Graph.Table = function(
} }
this.rows = apiComponent.rows; this.rows = apiComponent.rows;
if (R3.Utils.UndefinedOrNull(apiComponent.pageSize)) {
apiComponent.pageSize = 10;
}
this.pageSize = apiComponent.pageSize;
}; };
R3.API.Graph.Table.prototype = Object.create(R3.API.Graph.prototype); R3.API.Graph.Table.prototype = Object.create(R3.API.Graph.prototype);

View File

@ -52,6 +52,10 @@ R3.API.Query = function(
} }
this.httpMethod = apiComponent.httpMethod; this.httpMethod = apiComponent.httpMethod;
if (R3.Utils.UndefinedOrNull(apiComponent.tooltips)) {
apiComponent.tooltips = [];
}
this.tooltips = apiComponent.tooltips;
}; };
R3.API.Query.prototype = Object.create(R3.API.Component.prototype); R3.API.Query.prototype = Object.create(R3.API.Component.prototype);
@ -61,6 +65,7 @@ R3.API.Query.QUERY_SIZE = 'QUERY_SIZE';
R3.API.Query.QUERY_START = 'QUERY_START'; R3.API.Query.QUERY_START = 'QUERY_START';
R3.API.Query.QUERY_END = 'QUERY_END'; R3.API.Query.QUERY_END = 'QUERY_END';
R3.API.Query.QUERY_TIMEZONE = 'QUERY_TIMEZONE'; R3.API.Query.QUERY_TIMEZONE = 'QUERY_TIMEZONE';
R3.API.Query.QUERY_TIME_INTERVAL = 'QUERY_TIME_INTERVAL';
R3.API.Query.QUERY_BUCKET_FIELD = 'QUERY_BUCKET_FIELD'; R3.API.Query.QUERY_BUCKET_FIELD = 'QUERY_BUCKET_FIELD';
R3.API.Query.QUERY_LOGIN_TYPE = 'QUERY_LOGIN_TYPE'; R3.API.Query.QUERY_LOGIN_TYPE = 'QUERY_LOGIN_TYPE';
R3.API.Query.QUERY_ACKNOWLEDGED = 'QUERY_ACKNOWLEDGED'; R3.API.Query.QUERY_ACKNOWLEDGED = 'QUERY_ACKNOWLEDGED';

View File

@ -47,7 +47,7 @@ R3.API.Query.Alerts.FirstTimeLogin = function(
' "term" : { "alert_type.keyword": "First Time Login" }\n' + ' "term" : { "alert_type.keyword": "First Time Login" }\n' +
' },\n' + ' },\n' +
' {\n' + ' {\n' +
' "regexp" : { "login.login_type.keyword": "' + R3.API.Query.QUERY_LOGIN_TYPE + '" }\n' + ' "regexp" : { "login.type.keyword": "' + R3.API.Query.QUERY_LOGIN_TYPE + '" }\n' +
' }\n' + ' }\n' +
' ]\n' + ' ]\n' +
' }\n' + ' }\n' +

View File

@ -28,7 +28,7 @@ R3.API.Query.Alerts.Timeseries = function(
' "mins": {\n' + ' "mins": {\n' +
' "date_histogram": {\n' + ' "date_histogram": {\n' +
' "field": "timestamp",\n' + ' "field": "timestamp",\n' +
' "calendar_interval": "1d",\n' + ' "calendar_interval": "' + R3.API.Query.QUERY_TIME_INTERVAL + '",\n' +
' "time_zone": "' + R3.API.Query.QUERY_TIMEZONE + '",\n' + ' "time_zone": "' + R3.API.Query.QUERY_TIMEZONE + '",\n' +
' "min_doc_count": 0,\n' + ' "min_doc_count": 0,\n' +
' "format" : "yyyy-MM-dd"\n' + ' "format" : "yyyy-MM-dd"\n' +
@ -63,6 +63,11 @@ R3.API.Query.Alerts.Timeseries = function(
} }
this.text = apiComponent.text; this.text = apiComponent.text;
if (R3.Utils.UndefinedOrNull(apiComponent.timeInterval)) {
apiComponent.timeInterval = '1d';
}
this.timeInterval = apiComponent.timeInterval;
R3.API.Query.Alerts.call( R3.API.Query.Alerts.call(
this, this,
apiComponent apiComponent

View File

@ -46,7 +46,7 @@ R3.API.Query.Logins = function(
' }\n' + ' }\n' +
' },\n' + ' },\n' +
' {\n' + ' {\n' +
' "regexp" : { "login_type.keyword": "(' + R3.API.Query.QUERY_LOGIN_TYPE + ')" }\n' + ' "regexp" : { "type.keyword": "(' + R3.API.Query.QUERY_LOGIN_TYPE + ')" }\n' +
' }\n' + ' }\n' +
' ]\n' + ' ]\n' +
' }\n' + ' }\n' +

View File

@ -9,6 +9,9 @@ R3.D3.Raycaster = function(
__RUNTIME_COMPONENT__; __RUNTIME_COMPONENT__;
this.linkedComponents.position = R3.Vector3;
this.linkedComponents.direction = R3.Vector3;
__UPGRADE_TO_RUNTIME__; __UPGRADE_TO_RUNTIME__;
}; };

View File

@ -28,6 +28,30 @@ R3.D3.Viewport.FixedAspect.prototype.constructor = R3.D3.Viewport.FixedAspect;
R3.D3.Viewport.FixedAspect.prototype.createInstance = function() { R3.D3.Viewport.FixedAspect.prototype.createInstance = function() {
/**
* We have a dependency on our parent which could still need to call 'createInstance'
*/
// if (typeof this.parent === 'string') {
//
// if (R3.Utils.UndefinedOrNull(this.instanceLoaded)) {
//
// this.instanceLoaded = R3.Event.Subscribe(
// R3.Event.INSTANCE_LOADED,
// function (data) {
// if (data.component.id === this.parent) {
// this.parent = data.component;
// this.createInstance();
// this.instanceLoaded.remove();
// }
// }.bind(this)
// );
//
// }
//
// return;
// }
this.calculateDimensions(); this.calculateDimensions();
this.instance = this.graphics.Vector4( this.instance = this.graphics.Vector4(

View File

@ -19,11 +19,6 @@ R3.EntityManager = function(
this.instanceDisposal = []; this.instanceDisposal = [];
R3.Event.Subscribe(
R3.Event.INSTANCE_CREATED,
this.instanceCreated.bind(this)
);
R3.Event.Subscribe( R3.Event.Subscribe(
R3.Event.REMOVE_COMPONENT, R3.Event.REMOVE_COMPONENT,
this.removeComponent.bind(this) this.removeComponent.bind(this)
@ -32,6 +27,11 @@ R3.EntityManager = function(
R3.Event.Subscribe( R3.Event.Subscribe(
R3.Event.INSTANCE_DISPOSAL, R3.Event.INSTANCE_DISPOSAL,
this.removeInstances.bind(this) this.removeInstances.bind(this)
);
R3.Event.Subscribe(
R3.Event.REGISTER_COMPONENT,
this.registerComponent.bind(this)
) )
// R3.Event.Subscribe( // R3.Event.Subscribe(
@ -42,24 +42,35 @@ R3.EntityManager = function(
}; };
R3.EntityManager.prototype.instanceCreated = function(data) { R3.EntityManager.prototype.registerComponent = function(component) {
/** /**
* Register this component in componentType to Component register * Register this component in the componentType to component register
*/ */
if (R3.Utils.UndefinedOrNull(this.register[data.component.componentType])) { if (R3.Utils.UndefinedOrNull(this.register[component.componentType])) {
this.register[data.component.componentType] = {}; this.register[component.componentType] = {};
} }
if (R3.Utils.UndefinedOrNull(this.register[data.component.componentType][data.component.id])) { this.register[component.componentType][component.id] = component;
this.register[data.component.componentType][data.component.id] = data.component;
/**
* Register this component in the id to component register
*/
if (R3.Utils.UndefinedOrNull(this.idRegister[component.id])) {
this.idRegister[component.id] = component;
} }
/** /**
* Register this component in the Component.id to Component register * If this component has a parent - link it right away
*/ */
if (R3.Utils.UndefinedOrNull(this.idRegister[data.component.id])) { if (typeof component.parent === 'string') {
this.idRegister[data.component.id] = data.component;
if (R3.Utils.UndefinedOrNull(this.idRegister[component.parent])) {
throw new Error('A component links to a parent which has not been registered yet');
}
component.parent = this.idRegister[component.parent];
} }
}; };

View File

@ -39,6 +39,7 @@ R3.Graph.Barchart.Stacked.prototype.createInstance = function() {
R3.Graph.Barchart.Stacked.prototype.updateInstance = function(property) { R3.Graph.Barchart.Stacked.prototype.updateInstance = function(property) {
if (property === 'query') { if (property === 'query') {
this.chart.destroy();
this.instance = this.graphics.BarchartStacked(this); this.instance = this.graphics.BarchartStacked(this);
} }

View File

@ -46,9 +46,23 @@ R3.Query.prototype.updateInstance = function(property) {
return; return;
} }
if (property === 'tooltips') {
console.warn('todo: update query tooltips');
return;
}
__UPDATE_INSTANCE__; __UPDATE_INSTANCE__;
}; };
R3.Query.prototype.parse = function() { R3.Query.prototype.parse = function(data) {
console.warn('override R3.Query.prototype.parse() in child function'); console.warn(data);
if (data.hits && data.hits.hits) {
data.hits.hits.map(
function(hit) {
this.tooltips.push(hit._source);
}.bind(this)
)
}
}; };

View File

@ -27,3 +27,9 @@ R3.Query.Alerts.prototype.updateInstance = function(property) {
R3.Query.prototype.updateInstance.call(this, property); R3.Query.prototype.updateInstance.call(this, property);
}; };
R3.Query.Alerts.prototype.parse = function(data) {
R3.Query.prototype.parse.call(this, data);
};

View File

@ -124,10 +124,14 @@ R3.Query.Alerts.Buckets.prototype.parse = function(data) {
] ]
); );
this.tooltips.push(bucket);
result.push(key.concat(priorities)); result.push(key.concat(priorities));
return result; return result;
}, }.bind(this),
[] []
); );
//R3.Query.Alerts.prototype.parse.call(this, data);
}; };

View File

@ -42,5 +42,9 @@ R3.Query.Alerts.FirstTimeLogin.prototype.updateInstance = function(property) {
}; };
R3.Query.Alerts.FirstTimeLogin.prototype.parse = function(data) { R3.Query.Alerts.FirstTimeLogin.prototype.parse = function(data) {
console.warn('not yet implemented'); console.warn('not yet implemented');
R3.Query.Alerts.prototype.parse.call(this, data);
}; };

View File

@ -58,14 +58,7 @@ R3.Query.Alerts.FirstTimeLogin.Applications.prototype.parse = function(data) {
]; ];
if (data.hits.hits.length === 0) { if (data.hits.hits.length === 0) {
this.rows = [ this.rows = [null];
[
'no data',
null,
null,
null
]
]
} else { } else {
this.rows = data.hits.hits.reduce( this.rows = data.hits.hits.reduce(
function (result, hit) { function (result, hit) {
@ -81,4 +74,6 @@ R3.Query.Alerts.FirstTimeLogin.Applications.prototype.parse = function(data) {
); );
} }
R3.Query.Alerts.FirstTimeLogin.prototype.parse.call(this, data);
}; };

View File

@ -65,16 +65,7 @@ R3.Query.Alerts.FirstTimeLogin.Devices.prototype.parse = function(data) {
}, },
]; ];
if (data.hits.hits.length === 0) { if (data.hits && data.hits.hits) {
this.rows = [
[
'no data',
null,
null,
null
]
]
} else {
this.rows = data.hits.hits.reduce( this.rows = data.hits.hits.reduce(
function (result, hit) { function (result, hit) {
var row = [ var row = [
@ -90,4 +81,6 @@ R3.Query.Alerts.FirstTimeLogin.Devices.prototype.parse = function(data) {
[] []
); );
} }
R3.Query.Alerts.FirstTimeLogin.prototype.parse.call(this, data);
}; };

View File

@ -86,4 +86,6 @@ R3.Query.Alerts.FirstTimeLogin.VPN.prototype.parse = function(data) {
[] []
); );
R3.Query.Alerts.FirstTimeLogin.prototype.parse.call(this, data);
}; };

View File

@ -42,10 +42,6 @@ R3.Query.Alerts.List.prototype.updateInstance = function(property) {
R3.Query.Alerts.List.prototype.parse = function(data) { R3.Query.Alerts.List.prototype.parse = function(data) {
this.columns = [ this.columns = [
{
type : 'datetime',
name : 'Time'
},
{ {
type : 'number', type : 'number',
name : 'Priority' name : 'Priority'
@ -55,28 +51,60 @@ R3.Query.Alerts.List.prototype.parse = function(data) {
name : 'Alert Type' name : 'Alert Type'
}, },
{ {
type : 'boolean', type : 'string',
name : 'Hostname'
},
{
type : 'string',
name : 'Device'
},
{
type : 'string',
name : 'MAC Address'
},
{
type : 'string',
name : 'Acknowledged' name : 'Acknowledged'
},
{
type : 'datetime',
name : 'Time'
} }
]; ];
this.rows = data.hits.hits.reduce( this.rows = data.hits.hits.reduce(
function(result, hit) { function(result, hit) {
var row = []; var row = [];
row.push(new Date(hit._source.timestamp));
row.push(hit._source.priority); row.push(hit._source.priority);
row.push(hit._source.alert_type); row.push(hit._source.alert_type);
row.push(hit._source.acknowledged);
// if (hit._source.acknowledged) { var hostname = 'unknown';
// row.push({v:'ButtonName', f:'<input type="button" value="test" />'}); if (hit._source.login && hit._source.login.destination_hostname) {
// } else { hostname = hit._source.login.destination_hostname;
// row.push({v:'ButtonName', f:'<input type="button" value="test" />'}); }
// } row.push(hostname);
var device = 'unknown';
if (hit._source.device && hit._source.device.ip_v4) {
device = hit._source.device.ip_v4;
}
row.push(device);
row.push(hit._source.mac);
row.push({v:'ButtonName', f:hit._source.acknowledged?'Yes':'No'});
row.push(new Date(hit._source.timestamp));
result.push(row); result.push(row);
return result; return result;
}, }.bind(this),
[] []
); );
R3.Query.Alerts.prototype.parse.call(this, data);
}; };

View File

@ -44,9 +44,12 @@ R3.Query.Alerts.Summary.prototype.parse = function(data) {
this.priorities = data.aggregations.priorities.buckets.reduce( this.priorities = data.aggregations.priorities.buckets.reduce(
function(result, bucket) { function(result, bucket) {
result.push(bucket.doc_count); result.push(bucket.doc_count);
this.tooltips.push(bucket);
return result; return result;
}, }.bind(this),
[] []
); );
// R3.Query.Alerts.prototype.parse.call(this, data);
}; };

View File

@ -59,20 +59,72 @@ R3.Query.Alerts.Timeseries.prototype.parse = function(data) {
return day + '-' + monthNames[monthIndex] + '-' + year; return day + '-' + monthNames[monthIndex] + '-' + year;
} }
result.push(formatDate(new Date(bucket.key))); function formatHour(date) {
var day = date.getDate();
var hour = date.getHours();
var monthIndex = date.getMonth();
var monthNames = [
"Jan", "Feb", "Mar",
"Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct",
"Nov", "Dec"
];
return monthIndex+1 + '/' + day + ' ' + date.toLocaleTimeString();
return monthNames[monthIndex] + ' ' + day + '-' + hour + ':00';
}
function formatMinute(date) {
var hour = date.getHours();
var minute = date.getMinutes();
return date.toLocaleTimeString();
return hour + ':' + minute;
}
if (this.timeInterval === '1d') {
result.push(formatDate(new Date(bucket.key)));
} else if (this.timeInterval === '1h') {
result.push(formatHour(new Date(bucket.key)));
} else if (this.timeInterval === '1m') {
result.push(formatMinute(new Date(bucket.key)));
} else {
console.warn('invalid time format');
}
return result; return result;
}, }.bind(this),
[] []
); );
this.datasets = data.aggregations.mins.buckets.reduce( this.datasets = data.aggregations.mins.buckets.reduce(
function(result, bucket) { function(result, bucket) {
console.log('todo here');
bucket.priorities.buckets.map( var count = bucket.priorities.buckets.reduce(
function(prio) { function(struct, prio) {
result[prio.key - 1].data.push(prio.doc_count); struct[prio.key - 1] = prio.doc_count;
return struct;
},
[
0,
0,
0,
0
]
);
if (R3.Utils.UndefinedOrNull(count)) {
count = [0, 0, 0, 0];
}
count.map(
function(data, index) {
result[index].data.push(data);
} }
) );
return result; return result;
}, },
[ [
@ -138,4 +190,6 @@ R3.Query.Alerts.Timeseries.prototype.parse = function(data) {
// [] // []
// ); // );
R3.Query.Alerts.prototype.parse.call(this, data);
}; };

View File

@ -78,4 +78,5 @@ R3.Query.Devices.prototype.parse = function(data) {
); );
} }
R3.Query.prototype.parse.call(this, data);
}; };

View File

@ -81,4 +81,5 @@ R3.Query.Devices.Known.prototype.parse = function(data) {
); );
} }
R3.Query.Devices.prototype.parse.call(this, data);
}; };

View File

@ -45,20 +45,28 @@ R3.Query.Devices.SQL.prototype.parse = function(data) {
this.columns = [ this.columns = [
{ {
type: 'string', type: 'string',
name: 'Hostname' name: 'IP'
}, },
{ {
type: 'string', type: 'string',
name: 'IP' name: 'Hostname'
}, },
{ {
type: 'string', type: 'string',
name: 'MAC Address' name: 'MAC Address'
}, },
{ {
type: 'datetime', type: 'string',
name: 'Created' name: 'Agent ID'
}, },
{
type: 'string',
name: 'Acknowledged'
},
{
type: 'datetime',
name: 'First Seen'
}
]; ];
if (data.error) { if (data.error) {
@ -69,14 +77,17 @@ R3.Query.Devices.SQL.prototype.parse = function(data) {
this.rows = data.devices.reduce( this.rows = data.devices.reduce(
function (result, device) { function (result, device) {
var row = [ var row = [
device.hostname,
device.ip_v4, device.ip_v4,
device.hostname,
device.mac, device.mac,
device.agent_id,
{v:'ButtonName', f:device.acknowledged?'Yes':'No'},
new Date(device.created) new Date(device.created)
]; ];
result.push(row); result.push(row);
this.tooltips.push(device);
return result; return result;
}, }.bind(this),
[] []
); );
} }

View File

@ -82,4 +82,5 @@ R3.Query.Devices.Unknown.prototype.parse = function(data) {
); );
} }
R3.Query.Devices.prototype.parse.call(this, data);
}; };

View File

@ -29,3 +29,9 @@ R3.Query.Logins.prototype.updateInstance = function(property) {
R3.Query.prototype.updateInstance.call(this, property); R3.Query.prototype.updateInstance.call(this, property);
}; };
R3.Query.Logins.prototype.parse = function(data) {
R3.Query.prototype.parse.call(this, data);
};

View File

@ -51,6 +51,10 @@ R3.Query.Logins.Applications.prototype.parse = function(data) {
type: 'string', type: 'string',
name: 'Application' name: 'Application'
}, },
{
type: 'string',
name: 'Login Result'
},
{ {
type: 'datetime', type: 'datetime',
name: 'Time' name: 'Time'
@ -62,6 +66,7 @@ R3.Query.Logins.Applications.prototype.parse = function(data) {
var row = [ var row = [
hit._source.username, hit._source.username,
hit._source.application, hit._source.application,
hit._source.success?'Login Success':'Login Failure',
new Date(hit._source.timestamp) new Date(hit._source.timestamp)
]; ];
result.push(row); result.push(row);
@ -70,4 +75,6 @@ R3.Query.Logins.Applications.prototype.parse = function(data) {
[] []
); );
R3.Query.Logins.prototype.parse.call(this, data);
}; };

View File

@ -51,6 +51,10 @@ R3.Query.Logins.Devices.prototype.parse = function(data) {
type : 'string', type : 'string',
name : 'Device' name : 'Device'
}, },
{
type : 'string',
name : 'Login Result'
},
{ {
type : 'string', type : 'string',
name : 'Type' name : 'Type'
@ -65,15 +69,14 @@ R3.Query.Logins.Devices.prototype.parse = function(data) {
}, },
]; ];
this.rows = data.hits.hits.reduce( this.rows = data.hits.hits.reduce(
function(result, hit) { function(result, hit) {
console.log('device login : ', hit);
var row = [ var row = [
hit._source.username, hit._source.username,
hit._source.destination_hostname, hit._source.destination_hostname,
hit._source.login_type, hit._source.success?'Login Success':'Login Failure',
hit._source.login_protocol, hit._source.type,
hit._source.application,
new Date(hit._source.timestamp) new Date(hit._source.timestamp)
]; ];
result.push(row); result.push(row);
@ -82,4 +85,6 @@ R3.Query.Logins.Devices.prototype.parse = function(data) {
[] []
); );
R3.Query.Logins.prototype.parse.call(this, data);
}; };

View File

@ -76,4 +76,5 @@ R3.Query.Logins.VPN.prototype.parse = function(data) {
[] []
); );
R3.Query.Logins.prototype.parse.call(this, data);
}; };

View File

@ -75,6 +75,7 @@ R3.Query.UserDevices.prototype.parse = function(data) {
return result; return result;
}, },
[] []
) );
R3.Query.prototype.parse.call(this, data);
}; };

View File

@ -44,19 +44,15 @@ R3.Query.Users.prototype.parse = function(data) {
this.columns = [ this.columns = [
{ {
type: 'string', type: 'string',
name: 'Email' name: 'User'
}, },
{ {
type: 'datetime', type: 'datetime',
name: 'Created' name: 'First Seen'
}, },
]; ];
if (data.error) { if (!data.error) {
this.rows = [
['error', null, null, null]
]
} else {
this.rows = data.users.reduce( this.rows = data.users.reduce(
function (result, user) { function (result, user) {
var row = [ var row = [
@ -64,10 +60,14 @@ R3.Query.Users.prototype.parse = function(data) {
new Date(user.created) new Date(user.created)
]; ];
result.push(row); result.push(row);
this.tooltips.push(user);
return result; return result;
}, }.bind(this),
[] []
); );
} }
}; };

View File

@ -7,10 +7,10 @@ R3.Renderer.D3 = function(
inherited inherited
) { ) {
__INHERIT_ONLY__ __INHERIT_ONLY__;
this.linkedComponents.viewports = [R3.D3.Viewport]; this.linkedComponents.viewports = [R3.D3.Viewport];
this.linkedComponents.scenes = [R3.D3.Scenes]; this.linkedComponents.scenes = [R3.D3.Scene];
R3.Renderer.call( R3.Renderer.call(
this, this,

View File

@ -9,7 +9,7 @@ R3.Renderer.D3.Canvas = function(
inherited inherited
) { ) {
__INHERIT_AND_INSTANTIATE__ __INHERIT_AND_INSTANTIATE__;
this.linkedComponents.canvas = R3.Canvas; this.linkedComponents.canvas = R3.Canvas;

View File

@ -29,7 +29,17 @@ R3.Runtime.Graphics.Chart.prototype.createInstance = function() {
*/ */
R3.Runtime.Graphics.Chart.prototype.BarchartStacked = function(runtimeObject) { R3.Runtime.Graphics.Chart.prototype.BarchartStacked = function(runtimeObject) {
var ctx = document.getElementById(runtimeObject.domElement.domElementId).getContext('2d'); var domElement = document.getElementById(runtimeObject.domElement.domElementId);
//
// var divs = domElement.parentElement.getElementsByTagName('div');
//
// for (var div of divs) {
// domElement.parentElement.removeChild(div);
// }
var ctx = domElement.getContext('2d');
var barChartData = { var barChartData = {
labels: runtimeObject.query.labels, labels: runtimeObject.query.labels,

View File

@ -22,15 +22,169 @@ R3.Runtime.Graphics.Google.prototype.createInstance = function() {
this.instance = google.charts; this.instance = google.charts;
}; };
R3.Runtime.Graphics.Google.Tooltip = function(domTable, table, graph) {
var tooltip = document.createElement('div');
tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-minimized');
var header = document.createElement('div');
header.setAttribute('class', 'tooltip-header');
var headerTitle = document.createElement('div');
headerTitle.innerText = 'Click for more info...';
var button = document.createElement('button');
button.setAttribute('class', 'btn btn-info btn-white close-button');
button.innerText = 'X';
header.appendChild(headerTitle);
header.appendChild(button);
var tooltipContent = document.createElement('pre');
tooltip.appendChild(header);
tooltip.appendChild(tooltipContent);
if (graph.tooltip) {
document.body.removeChild(graph.tooltip);
}
graph.tooltip = tooltip;
document.body.appendChild(tooltip);
if (graph.mouseover) {
domTable.removeEventListener('mouseover', graph.mouseover);
}
if (graph.mouseout) {
domTable.removeEventListener('mouseout', graph.mouseout);
}
if (graph.mousemove) {
domTable.removeEventListener('mousemove', graph.mousemove);
}
graph.mouseover = function(tooltip) {
return function(event) {
tooltip.style.display = 'flex';
tooltip.style.left = (event.pageX + 10) + "px";
tooltip.style.top = (event.pageY + 10) + "px";
};
}(tooltip);
graph.mouseout = function(tooltip) {
return function(event) {
tooltip.style.display = 'none';
};
}(tooltip);
graph.mousemove = function(tooltip) {
return function(event) {
tooltip.style.left = (event.pageX + 10) + "px";
tooltip.style.top = (event.pageY + 10) + "px";
};
}(tooltip);
button.addEventListener('click', function(graph, tooltip, button, domTable) {
return function(event) {
domTable.addEventListener('mouseover', graph.mouseover);
domTable.addEventListener('mouseout', graph.mouseout);
domTable.addEventListener('mousemove', graph.mousemove);
tooltip.style.left = (event.pageX + 10) + "px";
tooltip.style.top = (event.pageY + 10) + "px";
tooltip.style.display = 'none';
tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-minimized');
button.style.display = 'none';
}
}(graph, tooltip, button, domTable));
google.visualization.events.addListener(
table,
'ready',
function(domTable, graph) {
return function() {
domTable.addEventListener('mouseover', graph.mouseover);
domTable.addEventListener('mouseout', graph.mouseout);
domTable.addEventListener('mousemove', graph.mousemove);
};
}(domTable, graph)
);
google.visualization.events.addListener(
table,
'select',
function(domTable, graph, tooltipContent) {
return function() {
domTable.removeEventListener('mouseover', graph.mouseover);
domTable.removeEventListener('mouseout', graph.mouseout);
domTable.removeEventListener('mousemove', graph.mousemove);
tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-maximized');
button.style.display = 'block';
var selection = table.getSelection();
var row = 0;
if (selection && selection[0]) {
row = selection[0].row
}
tooltipContent.innerHTML = R3.Utils.SyntaxHighlight(JSON.stringify(graph.query.tooltips[row], null, 2));
}
}(domTable, graph, tooltipContent)
);
return {
main : tooltip,
closeButton : button,
header : header,
title : headerTitle,
content : tooltipContent
};
};
R3.Runtime.Graphics.Google.prototype.Table = function(runtimeObject) { R3.Runtime.Graphics.Google.prototype.Table = function(runtimeObject) {
google.charts.load('current', {'packages':['table']}); google.charts.load('current', {'packages':['table']});
google.charts.setOnLoadCallback( google.charts.setOnLoadCallback(
function(graph) { function(graph) {
return function() { return function() {
var dataTable = new google.visualization.DataTable(); var dataTable = new google.visualization.DataTable();
// var makeTooltipActive = function(object, moveEventListener, overOutEventListener, table) {
// return function(event) {
// var selection = table.getSelection();
//
// object.domElement.instance.removeEventListener('mousemove', moveTooltip);
//
// var closeButton = document.getElementById('button-close-tooltip');
// closeButton.style.display = 'block';
// var tooltip = document.getElementById('div-tooltip');
// tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-maximized');
// var tooltipContent = document.getElementById('pre-tooltip-content');
// tooltipContent.style.display = 'block';
//
//
// var row = selection[0].row;
// var tooltip = document.getElementById('div-tooltip');
// var tooltipContent = document.getElementById('pre-tooltip-content');
// var tooltipHeader = document.getElementById('div-tooltip-header');
// tooltipContent.innerHTML = R3.Utils.SyntaxHighlight(JSON.stringify(object.query.tooltips[row], null, 2));
// tooltip.style.display = 'flex';
// moveTooltip(event);
//
// }
// };
//
// var closeButtonClick = ;
//
// var closeButton = document.getElementById('button-close-tooltip');
// closeButton.addEventListener('click', closeButtonClick);
graph.columns.map( graph.columns.map(
function(column) { function(column) {
dataTable.addColumn(column.type, column.name); dataTable.addColumn(column.type, column.name);
@ -39,9 +193,38 @@ R3.Runtime.Graphics.Google.prototype.Table = function(runtimeObject) {
dataTable.addRows(graph.rows); dataTable.addRows(graph.rows);
var table = new google.visualization.Table(document.getElementById(graph.domElement.domElementId)); var domTable = document.getElementById(graph.domElement.domElementId);
table.draw(dataTable, {showRowNumber: false, width: '100%', height: '100%'}); var table = new google.visualization.Table(domTable);
var tooltip = R3.Runtime.Graphics.Google.Tooltip(
domTable,
table,
graph
);
table.draw(
dataTable,
{
showRowNumber: false,
allowHtml : true,
cssClassNames: {
tableCell: 'fixed-row-height',
hoverTableRow : 'hover-row'
},
width: '100%',
height: '100%',
page: 'enable',
pageSize: graph.pageSize,
sortColumn: graph.columns.length - 1,
sortAscending : false,
pagingSymbols: {
prev: 'prev',
next: 'next'
},
pagingButtonsConfiguration: 'auto'
}
);
} }
}(runtimeObject) }(runtimeObject)

View File

@ -14,6 +14,7 @@ R3.System.Input = function() {
R3.Event.Emit( R3.Event.Emit(
R3.Event.GET_APPLICATION_MODE, R3.Event.GET_APPLICATION_MODE,
null,
function(applicationMode) { function(applicationMode) {
this.applicationMode = applicationMode; this.applicationMode = applicationMode;
}.bind(this) }.bind(this)

View File

@ -21,10 +21,38 @@ R3.System.Query.prototype.start = function() {
this.query this.query
); );
this.querySubscription = R3.Event.Subscribe(
R3.Event.QUERY,
this.query
);
this.intervalChangeSubscription = R3.Event.Subscribe(
R3.Event.QUERY_INTERVAL_CHANGE,
this.intervalChange.bind(this)
);
R3.System.prototype.start.call(this); R3.System.prototype.start.call(this);
}; };
R3.System.Query.prototype.intervalChange = function(data) {
var graphs = R3.EntityManager.Instance.findComponentsByConstructor(R3.Graph);
graphs.map(
function(graph) {
graph.query.start = 'now-' + data.interval;
graph.query.timeInterval = data.timeInterval;
R3.Event.Emit(
R3.Event.QUERY,
{
component : graph.query
}
)
}
);
};
/** /**
* Check for query instances - then run them * Check for query instances - then run them
@ -81,6 +109,10 @@ R3.System.Query.prototype.query = function(data) {
queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_ACKNOWLEDGED, "g"), query.acknowledged); queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_ACKNOWLEDGED, "g"), query.acknowledged);
} }
if (R3.Utils.Defined(query.timeInterval)) {
queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_TIME_INTERVAL, "g"), query.timeInterval);
}
if (typeof XMLHttpRequest === 'undefined') { if (typeof XMLHttpRequest === 'undefined') {
console.log('Implement server side query here'); console.log('Implement server side query here');
return; return;
@ -123,6 +155,8 @@ R3.System.Query.prototype.stop = function() {
this.querySubscription.remove(); this.querySubscription.remove();
this.intervalChangeSubscription.remove();
R3.System.prototype.stop.call(this); R3.System.prototype.stop.call(this);
}; };

View File

@ -642,7 +642,19 @@ R3.System.Storage.prototype.createRuntimeObject = function(responseText, clientE
return runtimeComponent; return runtimeComponent;
}; };
R3.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeDependencies, clientCallback, clientErrorCallback) { /**
* Loads a component and its dependencies if specified
* @param urlData
* @param componentData
* @param clientCallback
* @param clientErrorCallback
*/
R3.System.Storage.prototype.loadComponent = function(
urlData,
componentData,
clientCallback,
clientErrorCallback
) {
/** /**
* TODO: ensure parents of this component are loaded first * TODO: ensure parents of this component are loaded first
@ -655,7 +667,8 @@ R3.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeD
* We don't override runtime versions of the dependencies of the loading components - since they could be later. * We don't override runtime versions of the dependencies of the loading components - since they could be later.
* But we do override runtime versions of the loading component since the user actually selected them and clicked 'load' * But we do override runtime versions of the loading component since the user actually selected them and clicked 'load'
*/ */
toProcess.map( componentData.ids.map(
function(id) { function(id) {
R3.Utils.PushUnique(this.loading, id); R3.Utils.PushUnique(this.loading, id);
@ -665,15 +678,27 @@ R3.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeD
if (component) { if (component) {
component.remove(); component.remove();
} }
}.bind(this) }.bind(this)
); );
toProcess.map( componentData.ids.map(
function(id) { function(id) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open(
'GET',
urlData.apiUrl + '/component/load/' + id
);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("x-api-authorization", urlData.apiAuthorization);
xhr.setRequestHeader('x-api-user-token', urlData.apiUserToken);
xhr.onload = function(__system) { xhr.onload = function(__system) {
return function() { return function() {
@ -844,12 +869,6 @@ R3.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeD
}.bind(this); }.bind(this);
}(id); }(id);
xhr.open(
'GET',
apiUrl + '/component/load/' + id
);
xhr.send(); xhr.send();
}.bind(this) }.bind(this)
@ -862,34 +881,36 @@ R3.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeD
/** /**
* 'Loads' data from a url * 'Loads' data from a url
*/ */
R3.System.Storage.prototype.load = function(data, clientCallback, clientErrorCallback) { R3.System.Storage.prototype.load = function(componentData, clientCallback, clientErrorCallback) {
this.emit(
R3.Event.GET_API_URL, if (typeof XMLHttpRequest === 'undefined') {
throw new Error('Implement server side save here');
}
if (R3.Utils.UndefinedOrNull(componentData.ids) || componentData.ids.length < 1) {
throw new Error('No components defined for loading');
}
var event = R3.Event.GET_API_URL;
if (componentData.remote) {
event = R3.Event.GET_REMOTE_API_URL
}
R3.Event.Emit(
event,
null, null,
function(urlData) { function(urlData) {
if (typeof XMLHttpRequest === 'undefined') { this.loadComponent(
console.log('Implement server side load here'); urlData,
return; componentData,
} clientCallback,
clientErrorCallback
if (data.ids && data.ids.length > 0) { );
this.loadComponent(
urlData.apiUrl,
data.ids,
data.includeDependencies,
clientCallback,
clientErrorCallback
);
} else {
console.log('No components selected');
}
}.bind(this), }.bind(this),
function(error) { console.error
console.error(error.message); )
throw new Error(error.message);
}
);
}; };

View File

@ -27,6 +27,30 @@ R3.Vector3.prototype.constructor = R3.Vector3;
*/ */
R3.Vector3.prototype.createInstance = function() { R3.Vector3.prototype.createInstance = function() {
/**
* We have a dependency on our parent which could still need to call 'createInstance'
*/
// if (typeof this.parent === 'string') {
//
// if (R3.Utils.UndefinedOrNull(this.instanceLoaded)) {
//
// this.instanceLoaded = R3.Event.Subscribe(
// R3.Event.INSTANCE_LOADED,
// function (data) {
// if (data.component.id === this.parent) {
// this.parent = data.component;
// this.createInstance();
// this.instanceLoaded.remove();
// }
// }.bind(this)
// );
//
// }
//
// return;
// }
var runtime = R3.Component.GetComponentRuntime(this.parent); var runtime = R3.Component.GetComponentRuntime(this.parent);
switch (runtime) { switch (runtime) {