From c9638adb24ef5bbe6faf024520d169c009d646c9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 27 Jul 2020 18:00:09 +0200 Subject: [PATCH 001/192] Update Plotter.js --- Plotting/Plotter.js | 138 +++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 73 deletions(-) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index 85f3e6873..f8be7b23a 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -1,4 +1,4 @@ -function newPlotter () { +function newPlotter() { const MODULE_NAME = 'Plotter' const ERROR_LOG = true const INTENSIVE_LOG = false @@ -58,7 +58,7 @@ function newPlotter () { let logged = false return thisObject - function finalize () { + function finalize() { try { /* Stop listening to the necesary events. */ thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) @@ -92,7 +92,7 @@ function newPlotter () { } } - function initialize (pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) { + function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) { try { /* Store the information received. */ marketFiles = pStorage.marketFiles[0] @@ -134,20 +134,20 @@ function newPlotter () { } } - function initializeCoordinateSystem () { + function initializeCoordinateSystem() { scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) } - function finalizeCoordinateSystem () { + function finalizeCoordinateSystem() { coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId) } - function onScaleChanged () { + function onScaleChanged() { mustRecalculateDataPoints = true recalculate() } - function onMouseOver (event) { + function onMouseOver(event) { let userPosition = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem) userPositionDate = userPosition.valueOf() @@ -164,7 +164,7 @@ function newPlotter () { maxUserPositionRate = getRateFromPointAtBrowserCanvas(maxPositionPoint, thisObject.container, coordinateSystem) } - function onMarketFilesUpdated () { + function onMarketFilesUpdated() { try { let newMarketFile = marketFiles.getFile(timeFrame) if (newMarketFile !== undefined) { @@ -177,7 +177,7 @@ function newPlotter () { } } - function onDailyFilesUpdated () { + function onDailyFilesUpdated() { try { let newFileCursor = dailyFiles.getFileCursor(timeFrame) if (newFileCursor !== undefined) { @@ -190,14 +190,14 @@ function newPlotter () { } } - function getContainer (point) { + function getContainer(point) { try { let container /* First we check if this point is inside this space. */ if (thisObject.container.frame.isThisPointHere(point) === true) { return thisObject.container } else { - /* This point does not belong to this space. */ + /* This point does not belong to this space. */ return undefined } } catch (err) { @@ -205,29 +205,15 @@ function newPlotter () { } } - function setTimeFrame (pTimeFrame) { + function setTimeFrame(pTimeFrame) { try { if (timeFrame !== pTimeFrame) { timeFrame = pTimeFrame mustRecalculateDataPoints = true if (timeFrame >= _1_HOUR_IN_MILISECONDS) { - let newMarketFile = marketFiles.getFile(pTimeFrame) - - if (newMarketFile !== undefined) { - marketFile = newMarketFile - recalculate() - } else { - logger.write('[WARN] setTimeFrame -> Could not change to market file for timeFrame = ' + pTimeFrame) - } + marketFile = marketFiles.getFile(pTimeFrame) } else { - let newFileCursor = dailyFiles.getFileCursor(pTimeFrame) - - if (newFileCursor !== undefined) { - fileCursor = newFileCursor - recalculate() - } else { - logger.write('[WARN] setTimeFrame -> Could not change to market file for timeFrame = ' + pTimeFrame) - } + fileCursor = dailyFiles.getFileCursor(pTimeFrame) } } } catch (err) { @@ -235,17 +221,17 @@ function newPlotter () { } } - function setDatetime (pDatetime) { + function setDatetime(pDatetime) { datetime = pDatetime } - function setCoordinateSystem (pCoordinateSystem) { + function setCoordinateSystem(pCoordinateSystem) { finalizeCoordinateSystem() coordinateSystem = pCoordinateSystem initializeCoordinateSystem() } - function onDailyFileLoaded (event) { + function onDailyFileLoaded(event) { try { if (event.currentValue === event.totalValue) { /* This happens only when all of the files in the cursor have been loaded. */ @@ -256,7 +242,7 @@ function newPlotter () { } } - function draw () { + function draw() { try { thisObject.container.frame.draw() plot() @@ -265,7 +251,7 @@ function newPlotter () { } } - function recalculate () { + function recalculate() { if (canvas.chartingSpace.visible !== true) { return } try { if (timeFrame >= _1_HOUR_IN_MILISECONDS) { @@ -279,11 +265,11 @@ function newPlotter () { } } - function jsonifyDataFile (dataFile, recordDefinition, farLeftDate, farRightDate) { - /* - This function has as an input the raw data on files and creates with it an array of JSON objects - with not calculated properties for later being consumed by Formulas - */ + function jsonifyDataFile(dataFile, recordDefinition, farLeftDate, farRightDate) { + /* + This function has as an input the raw data on files and creates with it an array of JSON objects + with not calculated properties for later being consumed by Formulas + */ let jsonifiedArray = [] let previous @@ -298,9 +284,9 @@ function newPlotter () { } if ( - (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) && - (record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x) - ) { + (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) && + (record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x) + ) { record.previous = previous jsonifiedArray.push(record) previous = record @@ -316,11 +302,11 @@ function newPlotter () { return jsonifiedArray } - function calculationsProcedure (jsonArray, recordDefinition, calculationsProcedure, timeFrame) { - /* - This function has as an input an array of JSON objects, and it adds calculated properties to - complete the set of properties that will be available. - */ + function calculationsProcedure(jsonArray, recordDefinition, calculationsProcedure, timeFrame) { + /* + This function has as an input an array of JSON objects, and it adds calculated properties to + complete the set of properties that will be available. + */ let system = { // These are the available system variables to be used in User Code and Formulas timeFrame: timeFrame, @@ -387,9 +373,12 @@ function newPlotter () { return results } - function recalculateUsingDailyFiles () { + function recalculateUsingDailyFiles() { try { - if (fileCursor === undefined) { return } // We need to wait until there is a fileCursor + if (fileCursor === undefined) { + records = [] + return + } // We need to wait until there is a fileCursor available or maybe this indicator does not produce data for the current Time Frame if (fileCursor.files.size === 0) { return } // We need to wait until there are files in the cursor let daysOnSides = getSideDays(timeFrame) @@ -441,9 +430,12 @@ function newPlotter () { } } - function recalculateUsingMarketFiles () { + function recalculateUsingMarketFiles() { try { - if (marketFile === undefined) { return } // Initialization not complete yet. + if (marketFile === undefined) { + records = [] + return + } // Initialization not complete yet or this indicator does not produce data for the current time frame let daysOnSides = getSideDays(timeFrame) @@ -480,7 +472,7 @@ function newPlotter () { } } - function recalculateScale () { + function recalculateScale() { try { if (coordinateSystem.maxValue > 0) { return } // Already calculated. /* First we calculate the default scale */ @@ -495,17 +487,17 @@ function newPlotter () { } coordinateSystem.initialize( - minValue, - maxValue, - thisObject.container.frame.width, - thisObject.container.frame.height - ) + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ) } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] recalculateScale -> err = ' + err.stack) } } } - function plot () { + function plot() { try { /* Clean the pannel at places where there is no record. */ thisObject.container.eventHandler.raiseEvent('Current Record Changed', undefined) @@ -593,17 +585,17 @@ function newPlotter () { y: y } - /* - The information we store in files is independent from the charing system and its coordinate systems. - That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline. - */ + /* + The information we store in files is independent from the charing system and its coordinate systems. + That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline. + */ let dataPoint dataPoint = coordinateSystem.transformThisPoint(rawPoint) dataPoint = transformThisPoint(dataPoint, thisObject.container) dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) dataPoint = thisObject.fitFunction(dataPoint) - /* Store the data point at the local map */ + /* Store the data point at the local map */ dataPoint.rawPoint = rawPoint dataPoints.set(point.id, dataPoint) } @@ -636,7 +628,7 @@ function newPlotter () { } calculatedStyle = record.fillStyle.get(polygon.id) if (calculatedStyle !== undefined) { - /* We use the already calculated style */ + /* We use the already calculated style */ fillStyle = calculatedStyle } else { /* Get the default style if exists */ @@ -691,7 +683,7 @@ function newPlotter () { } calculatedStyle = record.strokeStyle.get(polygon.id) if (calculatedStyle !== undefined) { - /* We use the already calculated style */ + /* We use the already calculated style */ strokeStyle = calculatedStyle } else { /* Get the default style if exists */ @@ -771,7 +763,7 @@ function newPlotter () { } browserCanvasContext.closePath() - /* Apply the fill style to the canvas object */ + /* Apply the fill style to the canvas object */ if (polygon.polygonBody !== undefined) { /* Replace the fill style if we are at mouse position */ if (atMousePosition === true) { @@ -785,7 +777,7 @@ function newPlotter () { browserCanvasContext.fill() } - /* Apply the stroke style to the canvas object */ + /* Apply the stroke style to the canvas object */ if (polygon.polygonBorder !== undefined) { /* Replace the stroke style if we are at mouse position */ if (atMousePosition === true) { @@ -815,7 +807,7 @@ function newPlotter () { let imageSize = 0 let offsetX = 0 let offsetY = 0 - let imagePosition = {x: 0, y: 0} + let imagePosition = { x: 0, y: 0 } if (image.config.codeName !== undefined) { imageName = image.config.codeName } if (image.config.size !== undefined) { imageSize = image.config.size } if (image.imagePosition.config.offsetX !== undefined) { offsetX = image.imagePosition.config.offsetX } @@ -853,7 +845,7 @@ function newPlotter () { let paletteColor = UI_COLOR.GREY let offsetX = 0 let offsetY = 0 - let textPosition = {x: 0, y: 0} + let textPosition = { x: 0, y: 0 } if (text.textStyle.config.fontSize !== undefined) { fontSize = text.textStyle.config.fontSize } if (text.textStyle.config.opacity !== undefined) { opacity = text.textStyle.config.opacity } if (text.textStyle.config.paletteColor !== undefined) { paletteColor = eval(text.textStyle.config.paletteColor) } @@ -888,7 +880,7 @@ function newPlotter () { } } - function onViewportZoomChanged (event) { + function onViewportZoomChanged(event) { try { mustRecalculateDataPoints = true recalculate() @@ -897,19 +889,19 @@ function newPlotter () { } } - function onDragFinished () { + function onDragFinished() { recalculate() } - function onDisplace (event) { + function onDisplace(event) { recalculateAll(event) } - function onViewportPositionChanged (event) { + function onViewportPositionChanged(event) { recalculateAll(event) } - function recalculateAll (event) { + function recalculateAll(event) { mustRecalculateDataPoints = true if (event !== undefined) { if (event.recalculate === true) { From 120f5eb20ddde5888b163727a5334effbee0fffe Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 28 Jul 2020 12:46:33 +0200 Subject: [PATCH 002/192] Update Layer.js --- Panels/Layer.js | 150 +++++++++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 67 deletions(-) diff --git a/Panels/Layer.js b/Panels/Layer.js index cc2514911..8d4d16611 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -1,4 +1,4 @@ -function newLayer () { +function newLayer() { const MODULE_NAME = 'Layer' const ERROR_LOG = true const logger = newWebDebugLog() @@ -80,7 +80,7 @@ function newLayer () { let timeFrame = INITIAL_TIME_PERIOD let datetime = NEW_SESSION_INITIAL_DATE - /* Add an Event Handler */ + /* Add an Event Handler */ thisObject.eventHandler = newEventHandler() let imagesLoaded = 0 @@ -89,7 +89,7 @@ function newLayer () { return thisObject - function finalize () { + function finalize() { thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) thisObject.container.finalize() @@ -132,15 +132,15 @@ function newLayer () { thisObject.networkNode = undefined } - function initialize (callBackFunction) { - /* Create this objects continer */ + function initialize(callBackFunction) { + /* Create this objects continer */ try { thisObject.container = newContainer() thisObject.container.initialize(MODULE_NAME + ' ' + thisObject.payload.node.id) thisObject.container.isDraggeable = false thisObject.container.isClickeable = true - /* Lets set the basic dimensions of this thisObject. */ + /* Lets set the basic dimensions of this thisObject. */ let position = { x: 0, y: 0 @@ -152,32 +152,32 @@ function newLayer () { let functionLibraryProtocolNode = newProtocolNode() let lightingPath = - '->Layer->' + - 'Data Product->Single Market Data->Exchange Data Products->' + - 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + - 'Data Storage->Network Node->' + - 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + - 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + - 'Market->Market Base Asset->Asset->' + - 'Market Quoted Asset->Asset->' + - 'Exchange Markets->Crypto Exchange->' + - 'Product Definition->' + - 'Sensor Bot->Indicator Bot->Trading Bot->' + - 'Data Mine->' + - 'Dataset Definition->' + - 'Record Definition->Record Property->Formula->' + - 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + - 'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + - 'Plotter Module->Plotter->' + - 'Shapes->' + - 'Chart Points->Point->Point Formula->' + - 'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' + - 'Polygon Border->Style->Style Condition->Style->' + - 'Polygon Vertex->Point->' + - 'Image->Image Condition->Image Position->Point->' + - 'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' + - 'Plotter Panel->Javascript Code->Panel Data->Data Formula->' + - 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' + '->Layer->' + + 'Data Product->Single Market Data->Exchange Data Products->' + + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + + 'Data Storage->Network Node->' + + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + + 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + + 'Market->Market Base Asset->Asset->' + + 'Market Quoted Asset->Asset->' + + 'Exchange Markets->Crypto Exchange->' + + 'Product Definition->' + + 'Sensor Bot->Indicator Bot->Trading Bot->' + + 'Data Mine->' + + 'Dataset Definition->' + + 'Record Definition->Record Property->Formula->' + + 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + + 'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + + 'Plotter Module->Plotter->' + + 'Shapes->' + + 'Chart Points->Point->Point Formula->' + + 'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' + + 'Polygon Border->Style->Style Condition->Style->' + + 'Polygon Vertex->Point->' + + 'Image->Image Condition->Image Position->Point->' + + 'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' + + 'Plotter Panel->Javascript Code->Panel Data->Data Formula->' + + 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) /* Here we validate that we have all the needed information */ @@ -198,7 +198,7 @@ function newLayer () { if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return } if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode === undefined) { return } - /* Lets listen to our own events to react when we have a Mouse Click */ + /* Lets listen to our own events to react when we have a Mouse Click */ onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) /* Get ready to draw this layer */ @@ -242,7 +242,7 @@ function newLayer () { thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode } - function getIcon (node) { + function getIcon(node) { let nodeDefinition = getNodeDefinition(node) let iconName if (nodeDefinition.alternativeIcons !== undefined) { @@ -267,7 +267,7 @@ function newLayer () { } } - function checkStatusAtShutDown () { + function checkStatusAtShutDown() { /* Mechanism to recover a layer that was left loading the last time the browser was shut dowm. */ let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status') if (storedValue !== undefined) { @@ -278,7 +278,7 @@ function newLayer () { } } - function getContainer (point) { + function getContainer(point) { if (panelsVisibleButton !== undefined) { let container = panelsVisibleButton.getContainer(point) if (container !== undefined) { @@ -290,11 +290,11 @@ function newLayer () { } } - function setDatetime (pDatetime) { - /* - When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and - get ready to receive events on files loaded. - */ + function setDatetime(pDatetime) { + /* + When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and + get ready to receive events on files loaded. + */ let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS) @@ -307,11 +307,11 @@ function newLayer () { } } - function setTimeFrame (pTimeFrame) { - /* - When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and - get ready to receive events on files loaded. - */ + function setTimeFrame(pTimeFrame) { + /* + When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and + get ready to receive events on files loaded. + */ if (timeFrame !== pTimeFrame) { timeFrame = pTimeFrame @@ -321,15 +321,23 @@ function newLayer () { } } - function onMarketFileLoaded (event) { - marketFileProgressBar.value = Math.trunc(event.totalValue * 100 / event.totalValue) + function onMarketFileLoaded(event) { + if (event.totalValue === 0) { + marketFileProgressBar.value = 100 + return + } + marketFileProgressBar.value = Math.trunc((event.currentValue + event.filesNotLoaded) * 100 / event.totalValue) marketFileProgressBar.fillStyle = LOADING_FILL_STYLE marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100 } } - function onDailyFileLoaded (event) { + function onDailyFileLoaded(event) { + if (event.totalValue === 0) { + dailyFileProgressBar.value = 100 + return + } dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE @@ -337,7 +345,11 @@ function newLayer () { if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100 } } - function onSingleFileLoaded (event) { + function onSingleFileLoaded(event) { + if (event.totalValue === 0) { + singleFileProgressBar.value = 100 + return + } singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) singleFileProgressBar.fillStyle = LOADING_FILL_STYLE singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE @@ -345,7 +357,11 @@ function newLayer () { if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100 } } - function onFileSequenceLoaded (event) { + function onFileSequenceLoaded(event) { + if (event.totalValue === 0) { + fileSequenceProgressBar.value = 100 + return + } fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE @@ -353,21 +369,21 @@ function newLayer () { if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100 } } - function turnOff () { + function turnOff() { if (thisObject.status !== LAYER_STATUS.OFF) { resetProgressBars() changeStatusTo(LAYER_STATUS.OFF) } } - function turnOn () { + function turnOn() { if (thisObject.status === LAYER_STATUS.OFF) { resetProgressBars() changeStatusTo(LAYER_STATUS.LOADING) } } - function onMouseClick (event) { + function onMouseClick(event) { switch (thisObject.status) { case LAYER_STATUS.ON: resetProgressBars() @@ -383,7 +399,7 @@ function newLayer () { } } - function resetProgressBars () { + function resetProgressBars() { marketFileProgressBar.animatedValue = 0 marketFileProgressBar.value = 0 marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE @@ -405,12 +421,12 @@ function newLayer () { fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE } - function physics () { + function physics() { statusPhysics() childrenPhysics() } - function childrenPhysics () { + function childrenPhysics() { /* Panels Visible Button Setup */ if (thisObject.status === LAYER_STATUS.ON) { if (panelsVisibleButton === undefined) { @@ -435,8 +451,8 @@ function newLayer () { } } - function statusPhysics () { - /* We retrieve the stored status at the config. */ + function statusPhysics() { + /* We retrieve the stored status at the config. */ try { let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status') @@ -456,7 +472,7 @@ function newLayer () { changeStatusTo(LAYER_STATUS.OFF) } } catch (err) { - // we ignore errors here since most likely they will be parsing errors. + // we ignore errors here since most likely they will be parsing errors. } /* Check when the loading finishes */ @@ -469,7 +485,7 @@ function newLayer () { } } - function changeStatusTo (newStatus) { + function changeStatusTo(newStatus) { if (thisObject.status !== newStatus) { thisObject.status = newStatus @@ -486,18 +502,18 @@ function newLayer () { } } - function draw () { + function draw() { drawLayer() if (panelsVisibleButton !== undefined) { panelsVisibleButton.draw() } } - function drawLayer () { + function drawLayer() { drawLayerDisplay() } - function drawProgressBar (progressBar, lineWidth, offsetY) { + function drawProgressBar(progressBar, lineWidth, offsetY) { const ANIMATED_INCREMENT = 5 const OPACITY_INCREMENT = 0.01 const OPACITY_MIN = 1 @@ -510,7 +526,7 @@ function newLayer () { return } - /* Animate */ + /* Animate */ if (progressBar.animatedValue < progressBar.value) { progressBar.animatedValue = progressBar.animatedValue + ANIMATED_INCREMENT progressBar.opacity = progressBar.opacity + OPACITY_INCREMENT @@ -535,7 +551,7 @@ function newLayer () { y: thisObject.container.frame.height + offsetY } - /* Now the transformations. */ + /* Now the transformations. */ point1 = thisObject.container.frame.frameThisPoint(point1) point2 = thisObject.container.frame.frameThisPoint(point2) @@ -555,7 +571,7 @@ function newLayer () { browserCanvasContext.stroke() } - function drawLayerDisplay () { + function drawLayerDisplay() { let label1 = thisObject.payload.node.name let label2 = thisObject.exchange.name.substring(0, 15) + ' - ' + thisObject.market let label3 = thisObject.status.toUpperCase() From 1a52e5494e2efab1cd283a7386587f164b36ec3a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 29 Jul 2020 11:03:51 +0200 Subject: [PATCH 003/192] fix --- .vscode/settings.json | 3 + Plotting/Plotter.js | 1709 ++++++++++++++++++++--------------------- 2 files changed, 857 insertions(+), 855 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..1bcba0f85 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.detectIndentation": false +} \ No newline at end of file diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index f8be7b23a..6b96b66d2 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -1,916 +1,915 @@ function newPlotter() { - const MODULE_NAME = 'Plotter' - const ERROR_LOG = true - const INTENSIVE_LOG = false - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + const MODULE_NAME = 'Plotter' + const ERROR_LOG = true + const INTENSIVE_LOG = false + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - currentRecord: undefined, - container: undefined, - fitFunction: undefined, - onDailyFileLoaded: onDailyFileLoaded, - initialize: initialize, - finalize: finalize, - getContainer: getContainer, - setTimeFrame: setTimeFrame, - setDatetime: setDatetime, - setCoordinateSystem: setCoordinateSystem, - draw: draw - } - - let container = newContainer() - container.initialize() - thisObject.container = container - - let coordinateSystem - let slotHeight = (canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topLeft.y) / 10 // This is the amount of slots available - let mustRecalculateDataPoints = false - let atMousePositionFillStyles = new Map() - let atMousePositionStrokeStyles = new Map() - - let timeFrame // This will hold the current Time Frame the user is at. - let datetime // This will hold the current Datetime the user is at. - - let marketFile // This is the current Market File being plotted. - let fileCursor // This is the current File Cursor being used to retrieve Daily Files. - - let marketFiles // This object will provide the different Market Files at different Time Periods. - let dailyFiles // This object will provide the different File Cursors at different Time Periods. - - let productDefinition // Here we store a snapshot of the product definition which references this plotter. - - let records = [] // We will have the information to be plotted here. - let userPositionDate - let minUserPositionRate - let maxUserPositionRate - - let onMouseOverEventSuscriptionId - let zoomChangedEventSubscriptionId - let offsetChangedEventSubscriptionId - let dragFinishedEventSubscriptionId - let dimmensionsChangedEventSubscriptionId - let marketFilesUpdatedEventSubscriptionId - let dailyFilesUpdatedEventSubscriptionId - let onDisplaceEventSubscriptionId - let scaleChangedEventSubscriptionId - - let logged = false - return thisObject - - function finalize() { - try { - /* Stop listening to the necesary events. */ - thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) - canvas.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId) - canvas.chartingSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId) - canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId) - thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId) - marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId) - dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onDisplaceEventSubscriptionId) - thisObject.fitFunction = undefined - - /* Clear References */ - marketFiles = undefined - dailyFiles = undefined - - datetime = undefined - timeFrame = undefined - - marketFile = undefined - fileCursor = undefined - - finalizeCoordinateSystem() - coordinateSystem = undefined - slotHeight = undefined - mustRecalculateDataPoints = undefined - atMousePositionFillStyles = undefined - atMousePositionStrokeStyles = undefined - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack.stack) } - } - } - - function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) { - try { - /* Store the information received. */ - marketFiles = pStorage.marketFiles[0] - dailyFiles = pStorage.dailyFiles[0] - - datetime = pDatetime - timeFrame = pTimeFrame - coordinateSystem = pCoordinateSystem - initializeCoordinateSystem() - - productDefinition = pProductDefinition - - /* We need a Market File in order to calculate the Y scale, since this scale depends on actual data. */ - marketFile = marketFiles.getFile(ONE_DAY_IN_MILISECONDS) // This file is the one processed faster. - - /* Now we set the right files according to current Period. */ - marketFile = marketFiles.getFile(pTimeFrame) - fileCursor = dailyFiles.getFileCursor(pTimeFrame) - - /* Listen to the necesary events. */ - zoomChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged) - offsetChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Position Changed', onViewportPositionChanged) - dragFinishedEventSubscriptionId = canvas.eventHandler.listenToEvent('Drag Finished', onDragFinished) - marketFilesUpdatedEventSubscriptionId = marketFiles.eventHandler.listenToEvent('Files Updated', onMarketFilesUpdated) - dailyFilesUpdatedEventSubscriptionId = dailyFiles.eventHandler.listenToEvent('Files Updated', onDailyFilesUpdated) - onDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace) - onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - - /* Get ready for plotting. */ - recalculate() - dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () { - recalculate() - }) - - callBackFunction() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } - } - - function initializeCoordinateSystem() { - scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) - } - - function finalizeCoordinateSystem() { - coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId) - } - - function onScaleChanged() { - mustRecalculateDataPoints = true - recalculate() - } - - function onMouseOver(event) { - let userPosition = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem) - userPositionDate = userPosition.valueOf() - - let minPositionPoint = { - x: event.x, - y: event.y + 2 - } - minUserPositionRate = getRateFromPointAtBrowserCanvas(minPositionPoint, thisObject.container, coordinateSystem) - - let maxPositionPoint = { - x: event.x, - y: event.y - 2 - } - maxUserPositionRate = getRateFromPointAtBrowserCanvas(maxPositionPoint, thisObject.container, coordinateSystem) - } - - function onMarketFilesUpdated() { - try { - let newMarketFile = marketFiles.getFile(timeFrame) - if (newMarketFile !== undefined) { - marketFile = newMarketFile - mustRecalculateDataPoints = true - recalculate() - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onMarketFilesUpdated -> err = ' + err.stack.stack) } - } - } - - function onDailyFilesUpdated() { - try { - let newFileCursor = dailyFiles.getFileCursor(timeFrame) - if (newFileCursor !== undefined) { - fileCursor = newFileCursor - mustRecalculateDataPoints = true - recalculate() - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onDailyFilesUpdated -> err = ' + err.stack.stack) } - } - } - - function getContainer(point) { - try { - let container - /* First we check if this point is inside this space. */ - if (thisObject.container.frame.isThisPointHere(point) === true) { - return thisObject.container - } else { - /* This point does not belong to this space. */ - return undefined - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] getContainer -> err = ' + err.stack) } - } - } - - function setTimeFrame(pTimeFrame) { - try { - if (timeFrame !== pTimeFrame) { - timeFrame = pTimeFrame - mustRecalculateDataPoints = true - if (timeFrame >= _1_HOUR_IN_MILISECONDS) { - marketFile = marketFiles.getFile(pTimeFrame) - } else { - fileCursor = dailyFiles.getFileCursor(pTimeFrame) - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] setTimeFrame -> err = ' + err.stack) } - } - } - - function setDatetime(pDatetime) { - datetime = pDatetime - } - - function setCoordinateSystem(pCoordinateSystem) { - finalizeCoordinateSystem() - coordinateSystem = pCoordinateSystem - initializeCoordinateSystem() - } - - function onDailyFileLoaded(event) { - try { - if (event.currentValue === event.totalValue) { - /* This happens only when all of the files in the cursor have been loaded. */ - recalculate() - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onDailyFileLoaded -> err = ' + err.stack) } - } - } - - function draw() { - try { - thisObject.container.frame.draw() - plot() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] draw -> err = ' + err.stack) } - } - } - - function recalculate() { - if (canvas.chartingSpace.visible !== true) { return } - try { - if (timeFrame >= _1_HOUR_IN_MILISECONDS) { - recalculateUsingMarketFiles() - } else { - recalculateUsingDailyFiles() - } - thisObject.container.eventHandler.raiseEvent('CandleStairs Changed', records) // --> Check This - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] recalculate -> err = ' + err.stack) } - } - } - - function jsonifyDataFile(dataFile, recordDefinition, farLeftDate, farRightDate) { - /* - This function has as an input the raw data on files and creates with it an array of JSON objects - with not calculated properties for later being consumed by Formulas - */ - - let jsonifiedArray = [] - let previous - - for (let i = 0; i < dataFile.length; i++) { - let record = {} - for (let j = 0; j < recordDefinition.properties.length; j++) { - let property = recordDefinition.properties[j] - if (property.config.isCalculated !== true) { - record[property.config.codeName] = dataFile[i][j] - } - } - - if ( - (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) && - (record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x) - ) { - record.previous = previous - jsonifiedArray.push(record) - previous = record - - if (record.begin === undefined || record.end === undefined) { console.log('Could not find the property begin or end which are needed for the plotter to work.') } - if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) { - thisObject.currentRecord = record - thisObject.container.eventHandler.raiseEvent('Current Record Changed', thisObject.currentRecord) - } - } + let thisObject = { + currentRecord: undefined, + container: undefined, + fitFunction: undefined, + onDailyFileLoaded: onDailyFileLoaded, + initialize: initialize, + finalize: finalize, + getContainer: getContainer, + setTimeFrame: setTimeFrame, + setDatetime: setDatetime, + setCoordinateSystem: setCoordinateSystem, + draw: draw } - return jsonifiedArray - } + let container = newContainer() + container.initialize() + thisObject.container = container - function calculationsProcedure(jsonArray, recordDefinition, calculationsProcedure, timeFrame) { - /* - This function has as an input an array of JSON objects, and it adds calculated properties to - complete the set of properties that will be available. - */ + let coordinateSystem + let slotHeight = (canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topLeft.y) / 10 // This is the amount of slots available + let mustRecalculateDataPoints = false + let atMousePositionFillStyles = new Map() + let atMousePositionStrokeStyles = new Map() - let system = { // These are the available system variables to be used in User Code and Formulas - timeFrame: timeFrame, - ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS - } - let variable = {} // This is the structure where the user will define its own variables that will be shared across different config blocks and formulas. - let results = [] + let timeFrame // This will hold the current Time Frame the user is at. + let datetime // This will hold the current Datetime the user is at. - /* This is Initialization Code */ - if (calculationsProcedure.initialization !== undefined) { - if (calculationsProcedure.initialization.javascriptCode !== undefined) { + let marketFile // This is the current Market File being plotted. + let fileCursor // This is the current File Cursor being used to retrieve Daily Files. + + let marketFiles // This object will provide the different Market Files at different Time Periods. + let dailyFiles // This object will provide the different File Cursors at different Time Periods. + + let productDefinition // Here we store a snapshot of the product definition which references this plotter. + + let records = [] // We will have the information to be plotted here. + let userPositionDate + let minUserPositionRate + let maxUserPositionRate + + let onMouseOverEventSuscriptionId + let zoomChangedEventSubscriptionId + let offsetChangedEventSubscriptionId + let dragFinishedEventSubscriptionId + let dimmensionsChangedEventSubscriptionId + let marketFilesUpdatedEventSubscriptionId + let dailyFilesUpdatedEventSubscriptionId + let onDisplaceEventSubscriptionId + let scaleChangedEventSubscriptionId + + let logged = false + return thisObject + + function finalize() { try { - eval(calculationsProcedure.initialization.javascriptCode.code) + /* Stop listening to the necesary events. */ + thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) + canvas.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId) + canvas.chartingSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId) + canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId) + thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId) + marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId) + dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onDisplaceEventSubscriptionId) + thisObject.fitFunction = undefined + + /* Clear References */ + marketFiles = undefined + dailyFiles = undefined + + datetime = undefined + timeFrame = undefined + + marketFile = undefined + fileCursor = undefined + + finalizeCoordinateSystem() + coordinateSystem = undefined + slotHeight = undefined + mustRecalculateDataPoints = undefined + atMousePositionFillStyles = undefined + atMousePositionStrokeStyles = undefined } catch (err) { - logger.write('[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Error = ' + err.stack.stack) - logger.write('[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Code = ' + calculationsProcedure.initialization.javascriptCode.code) - throw ('Error Executing User Code.') + if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack.stack) } } - } } - /* This is Initialization Code */ - if (calculationsProcedure.loop !== undefined) { - if (calculationsProcedure.loop.javascriptCode !== undefined) { - for (let index = 0; index < jsonArray.length; index++) { - let product = jsonArray[index] + function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) { + try { + /* Store the information received. */ + marketFiles = pStorage.marketFiles[0] + dailyFiles = pStorage.dailyFiles[0] - /* This is Loop Code */ - try { - eval(calculationsProcedure.loop.javascriptCode.code) - } catch (err) { - logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. Error = ' + err.stack.stack) - logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. product = ' + JSON.stringify(product)) - logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. Code = ' + calculationsProcedure.loop.javascriptCode.code) - throw ('Error Executing User Code.') - } + datetime = pDatetime + timeFrame = pTimeFrame + coordinateSystem = pCoordinateSystem + initializeCoordinateSystem() - /* For each calculated property we apply its formula */ - for (let j = 0; j < recordDefinition.properties.length; j++) { - let property = recordDefinition.properties[j] - if (property.config.isCalculated === true) { - if (property.formula !== undefined) { - if (property.formula.code !== undefined) { - try { - let newValue = eval(property.formula.code) - let currentRecord = product - currentRecord[property.config.codeName] = newValue - } catch (err) { - logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Error = ' + err.stack.stack) - logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. product = ' + JSON.stringify(product)) - logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Code = ' + property.formula.code) - throw ('Error Executing User Code.') - } - } - } + productDefinition = pProductDefinition + + /* We need a Market File in order to calculate the Y scale, since this scale depends on actual data. */ + marketFile = marketFiles.getFile(ONE_DAY_IN_MILISECONDS) // This file is the one processed faster. + + /* Now we set the right files according to current Period. */ + marketFile = marketFiles.getFile(pTimeFrame) + fileCursor = dailyFiles.getFileCursor(pTimeFrame) + + /* Listen to the necesary events. */ + zoomChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged) + offsetChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Position Changed', onViewportPositionChanged) + dragFinishedEventSubscriptionId = canvas.eventHandler.listenToEvent('Drag Finished', onDragFinished) + marketFilesUpdatedEventSubscriptionId = marketFiles.eventHandler.listenToEvent('Files Updated', onMarketFilesUpdated) + dailyFilesUpdatedEventSubscriptionId = dailyFiles.eventHandler.listenToEvent('Files Updated', onDailyFilesUpdated) + onDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace) + onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + + /* Get ready for plotting. */ + recalculate() + dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () { + recalculate() + }) + + callBackFunction() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } + + function initializeCoordinateSystem() { + scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) + } + + function finalizeCoordinateSystem() { + coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId) + } + + function onScaleChanged() { + mustRecalculateDataPoints = true + recalculate() + } + + function onMouseOver(event) { + let userPosition = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem) + userPositionDate = userPosition.valueOf() + + let minPositionPoint = { + x: event.x, + y: event.y + 2 + } + minUserPositionRate = getRateFromPointAtBrowserCanvas(minPositionPoint, thisObject.container, coordinateSystem) + + let maxPositionPoint = { + x: event.x, + y: event.y - 2 + } + maxUserPositionRate = getRateFromPointAtBrowserCanvas(maxPositionPoint, thisObject.container, coordinateSystem) + } + + function onMarketFilesUpdated() { + try { + let newMarketFile = marketFiles.getFile(timeFrame) + if (newMarketFile !== undefined) { + marketFile = newMarketFile + mustRecalculateDataPoints = true + recalculate() } - } - - /* Adding the new element to the resulting array */ - results.push(product) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onMarketFilesUpdated -> err = ' + err.stack.stack) } } - } } - return results - } - function recalculateUsingDailyFiles() { - try { - if (fileCursor === undefined) { - records = [] - return - } // We need to wait until there is a fileCursor available or maybe this indicator does not produce data for the current Time Frame - if (fileCursor.files.size === 0) { return } // We need to wait until there are files in the cursor - - let daysOnSides = getSideDays(timeFrame) - - let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem) - let rightDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem) - - let dateDiff = rightDate.valueOf() - leftDate.valueOf() - - let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5) - let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5) - - let currentDate = new Date(farLeftDate.valueOf()) - - records = [] - - while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) { - let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2) - - let dailyFile = fileCursor.files.get(stringDate) - - if (dailyFile !== undefined) { - /* Transform the current file content into an array of JSON objects */ - let jsonData = jsonifyDataFile(dailyFile, productDefinition.record, farLeftDate, farRightDate) - - /* Add the calculated properties */ - if (productDefinition.calculations !== undefined) { - let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timeFrame) - records.push(...calculationsResult) // This adds records to the current array. - } else { - records.push(...jsonData)// This adds records to the current array. - } + function onDailyFilesUpdated() { + try { + let newFileCursor = dailyFiles.getFileCursor(timeFrame) + if (newFileCursor !== undefined) { + fileCursor = newFileCursor + mustRecalculateDataPoints = true + recalculate() + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onDailyFilesUpdated -> err = ' + err.stack.stack) } } + } - currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS) - } - - /* Lests check if all the visible screen is going to be covered by candle-record. */ - let lowerEnd = leftDate.valueOf() - let upperEnd = rightDate.valueOf() - - if (records.length > 0) { - if (records[0].begin > lowerEnd || records[records.length - 1].end < upperEnd) { - setTimeout(recalculate, 2000) + function getContainer(point) { + try { + let container + /* First we check if this point is inside this space. */ + if (thisObject.container.frame.isThisPointHere(point) === true) { + return thisObject.container + } else { + /* This point does not belong to this space. */ + return undefined + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] getContainer -> err = ' + err.stack) } } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingDailyFiles -> err = ' + err.stack) } } - } - function recalculateUsingMarketFiles() { - try { - if (marketFile === undefined) { - records = [] - return - } // Initialization not complete yet or this indicator does not produce data for the current time frame - - let daysOnSides = getSideDays(timeFrame) - - let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem) - let rightDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem) - - let dateDiff = rightDate.valueOf() - leftDate.valueOf() - - leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5) - rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5) - - for (let i = 0; i < records.length; i++) { - let record = records[i] - record.fillStyle = undefined - record.strokeStyle = undefined - record.dataPoints = undefined - record.previous = undefined - records[i] = {} - } - records = [] - - /* Transform the current file content into an array of JSON objects */ - let jsonData = jsonifyDataFile(marketFile, productDefinition.record, leftDate, rightDate) - - /* Add the calculated properties */ - if (productDefinition.calculations !== undefined) { - let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timeFrame) - records.push(...calculationsResult) // This adds records to the current array. - } else { - records.push(...jsonData)// This adds records to the current array. - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingMarketFiles -> err = ' + err.stack) } + function setTimeFrame(pTimeFrame) { + try { + if (timeFrame !== pTimeFrame) { + timeFrame = pTimeFrame + mustRecalculateDataPoints = true + if (timeFrame >= _1_HOUR_IN_MILISECONDS) { + marketFile = marketFiles.getFile(pTimeFrame) + } else { + fileCursor = dailyFiles.getFileCursor(pTimeFrame) + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] setTimeFrame -> err = ' + err.stack) } + } } - } - function recalculateScale() { - try { - if (coordinateSystem.maxValue > 0) { return } // Already calculated. - /* First we calculate the default scale */ - let minValue = { - x: MIN_PLOTABLE_DATE.valueOf(), - y: 0 - } - - let maxValue = { - x: MAX_PLOTABLE_DATE.valueOf(), - y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 // TODO: This 4 is temporary - } - - coordinateSystem.initialize( - minValue, - maxValue, - thisObject.container.frame.width, - thisObject.container.frame.height - ) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] recalculateScale -> err = ' + err.stack) } + function setDatetime(pDatetime) { + datetime = pDatetime } - } - function plot() { - try { - /* Clean the pannel at places where there is no record. */ - thisObject.container.eventHandler.raiseEvent('Current Record Changed', undefined) + function setCoordinateSystem(pCoordinateSystem) { + finalizeCoordinateSystem() + coordinateSystem = pCoordinateSystem + initializeCoordinateSystem() + } - for (let i = 0; i < records.length; i++) { - let record = records[i] + function onDailyFileLoaded(event) { + try { + if (event.currentValue === event.totalValue) { + /* This happens only when all of the files in the cursor have been loaded. */ + recalculate() + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onDailyFileLoaded -> err = ' + err.stack) } + } + } + function draw() { + try { + thisObject.container.frame.draw() + plot() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] draw -> err = ' + err.stack) } + } + } + + function recalculate() { + try { + if (timeFrame >= _1_HOUR_IN_MILISECONDS) { + recalculateUsingMarketFiles() + } else { + recalculateUsingDailyFiles() + } + thisObject.container.eventHandler.raiseEvent('CandleStairs Changed', records) // --> Check This + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] recalculate -> err = ' + err.stack) } + } + } + + function jsonifyDataFile(dataFile, recordDefinition, farLeftDate, farRightDate) { /* - In the formulas to create plotters, we allos users to reference the previous record. - To enable that we need to link all records to the previous one in this way. + This function has as an input the raw data on files and creates with it an array of JSON objects + with not calculated properties for later being consumed by Formulas */ - if (i == 0) { - record.previous = {} // this way it wont be undefined - } else { - record.previous = records[i - 1] - } - let beginPoint = { - x: record.begin, - y: 0 - } + let jsonifiedArray = [] + let previous - let endPoint = { - x: record.end, - y: 0 - } - - beginPoint = coordinateSystem.transformThisPoint(beginPoint) - endPoint = coordinateSystem.transformThisPoint(endPoint) - - beginPoint = transformThisPoint(beginPoint, thisObject.container) - endPoint = transformThisPoint(endPoint, thisObject.container) - - beginPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(beginPoint) - endPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(endPoint) - - beginPoint = thisObject.fitFunction(beginPoint) - endPoint = thisObject.fitFunction(endPoint) - - if (endPoint.x < canvas.chartingSpace.viewport.visibleArea.bottomLeft.x || beginPoint.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x) { - continue - } - - let atMousePosition = false - if (userPositionDate >= record.begin && userPositionDate <= record.end) { - if (record.rate !== undefined && productDefinition.referenceParent.config.useRateAtMousePosition === true) { - /* Current Record depends also on rate */ - if (record.rate >= minUserPositionRate && record.rate <= maxUserPositionRate) { - atMousePosition = true - thisObject.container.eventHandler.raiseEvent('Current Record Changed', record) - } - } else { - /* Current Record depends only on begin and end. */ - atMousePosition = true - thisObject.container.eventHandler.raiseEvent('Current Record Changed', record) - } - } - - /* If there is code we execute it now. */ - if (productDefinition.referenceParent.javascriptCode !== undefined) { - eval(productDefinition.referenceParent.javascriptCode.code) - } - - if (productDefinition.referenceParent.shapes === undefined) { continue } - if (productDefinition.referenceParent.shapes.chartPoints === undefined) { continue } - let dataPoints = new Map() - if (record.dataPoints !== undefined && mustRecalculateDataPoints === false) { - /* We use the datapoints already calculated. */ - dataPoints = record.dataPoints - } else { - if (logged === false) { - logged = true - } - /* It seems we need to calculate the data points this time. */ - for (let k = 0; k < productDefinition.referenceParent.shapes.chartPoints.length; k++) { - let chartPoints = productDefinition.referenceParent.shapes.chartPoints[k] - for (let j = 0; j < chartPoints.points.length; j++) { - let point = chartPoints.points[j] - if (point.pointFormula !== undefined) { - let x = 0 - let y = 0 - eval(point.pointFormula.code) - let rawPoint = { - x: x, - y: y + for (let i = 0; i < dataFile.length; i++) { + let record = {} + for (let j = 0; j < recordDefinition.properties.length; j++) { + let property = recordDefinition.properties[j] + if (property.config.isCalculated !== true) { + record[property.config.codeName] = dataFile[i][j] } + } + + if ( + (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) && + (record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x) + ) { + record.previous = previous + jsonifiedArray.push(record) + previous = record + + if (record.begin === undefined || record.end === undefined) { console.log('Could not find the property begin or end which are needed for the plotter to work.') } + if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) { + thisObject.currentRecord = record + thisObject.container.eventHandler.raiseEvent('Current Record Changed', thisObject.currentRecord) + } + } + } + + return jsonifiedArray + } + + function calculationsProcedure(jsonArray, recordDefinition, calculationsProcedure, timeFrame) { + /* + This function has as an input an array of JSON objects, and it adds calculated properties to + complete the set of properties that will be available. + */ + + let system = { // These are the available system variables to be used in User Code and Formulas + timeFrame: timeFrame, + ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS + } + let variable = {} // This is the structure where the user will define its own variables that will be shared across different config blocks and formulas. + let results = [] + + /* This is Initialization Code */ + if (calculationsProcedure.initialization !== undefined) { + if (calculationsProcedure.initialization.javascriptCode !== undefined) { + try { + eval(calculationsProcedure.initialization.javascriptCode.code) + } catch (err) { + logger.write('[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Error = ' + err.stack.stack) + logger.write('[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Code = ' + calculationsProcedure.initialization.javascriptCode.code) + throw ('Error Executing User Code.') + } + } + } + + /* This is Initialization Code */ + if (calculationsProcedure.loop !== undefined) { + if (calculationsProcedure.loop.javascriptCode !== undefined) { + for (let index = 0; index < jsonArray.length; index++) { + let product = jsonArray[index] + + /* This is Loop Code */ + try { + eval(calculationsProcedure.loop.javascriptCode.code) + } catch (err) { + logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. Error = ' + err.stack.stack) + logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. product = ' + JSON.stringify(product)) + logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. Code = ' + calculationsProcedure.loop.javascriptCode.code) + throw ('Error Executing User Code.') + } + + /* For each calculated property we apply its formula */ + for (let j = 0; j < recordDefinition.properties.length; j++) { + let property = recordDefinition.properties[j] + if (property.config.isCalculated === true) { + if (property.formula !== undefined) { + if (property.formula.code !== undefined) { + try { + let newValue = eval(property.formula.code) + let currentRecord = product + currentRecord[property.config.codeName] = newValue + } catch (err) { + logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Error = ' + err.stack.stack) + logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. product = ' + JSON.stringify(product)) + logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Code = ' + property.formula.code) + throw ('Error Executing User Code.') + } + } + } + } + } + + /* Adding the new element to the resulting array */ + results.push(product) + } + } + } + return results + } + + function recalculateUsingDailyFiles() { + try { + if (fileCursor === undefined) { + records = [] + return + } // We need to wait until there is a fileCursor available or maybe this indicator does not produce data for the current Time Frame + if (fileCursor.files.size === 0) { return } // We need to wait until there are files in the cursor + + let daysOnSides = getSideDays(timeFrame) + + let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem) + let rightDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem) + + let dateDiff = rightDate.valueOf() - leftDate.valueOf() + + let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5) + let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5) + + let currentDate = new Date(farLeftDate.valueOf()) + + records = [] + + while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) { + let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2) + + let dailyFile = fileCursor.files.get(stringDate) + + if (dailyFile !== undefined) { + /* Transform the current file content into an array of JSON objects */ + let jsonData = jsonifyDataFile(dailyFile, productDefinition.record, farLeftDate, farRightDate) + + /* Add the calculated properties */ + if (productDefinition.calculations !== undefined) { + let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timeFrame) + records.push(...calculationsResult) // This adds records to the current array. + } else { + records.push(...jsonData)// This adds records to the current array. + } + } + + currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS) + } + + /* Lests check if all the visible screen is going to be covered by candle-record. */ + let lowerEnd = leftDate.valueOf() + let upperEnd = rightDate.valueOf() + + if (records.length > 0) { + if (records[0].begin > lowerEnd || records[records.length - 1].end < upperEnd) { + setTimeout(recalculate, 2000) + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingDailyFiles -> err = ' + err.stack) } + } + } + + function recalculateUsingMarketFiles() { + try { + if (marketFile === undefined) { + records = [] + return + } // Initialization not complete yet or this indicator does not produce data for the current time frame + + let daysOnSides = getSideDays(timeFrame) + + let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem) + let rightDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem) + + let dateDiff = rightDate.valueOf() - leftDate.valueOf() + + leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5) + rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5) + + for (let i = 0; i < records.length; i++) { + let record = records[i] + record.fillStyle = undefined + record.strokeStyle = undefined + record.dataPoints = undefined + record.previous = undefined + records[i] = {} + } + records = [] + + /* Transform the current file content into an array of JSON objects */ + let jsonData = jsonifyDataFile(marketFile, productDefinition.record, leftDate, rightDate) + + /* Add the calculated properties */ + if (productDefinition.calculations !== undefined) { + let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timeFrame) + records.push(...calculationsResult) // This adds records to the current array. + } else { + records.push(...jsonData)// This adds records to the current array. + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingMarketFiles -> err = ' + err.stack) } + } + } + + function recalculateScale() { + try { + if (coordinateSystem.maxValue > 0) { return } // Already calculated. + /* First we calculate the default scale */ + let minValue = { + x: MIN_PLOTABLE_DATE.valueOf(), + y: 0 + } + + let maxValue = { + x: MAX_PLOTABLE_DATE.valueOf(), + y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 // TODO: This 4 is temporary + } + + coordinateSystem.initialize( + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] recalculateScale -> err = ' + err.stack) } + } + } + + function plot() { + try { + /* Clean the pannel at places where there is no record. */ + thisObject.container.eventHandler.raiseEvent('Current Record Changed', undefined) + + for (let i = 0; i < records.length; i++) { + let record = records[i] /* - The information we store in files is independent from the charing system and its coordinate systems. - That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline. + In the formulas to create plotters, we allos users to reference the previous record. + To enable that we need to link all records to the previous one in this way. */ - let dataPoint - dataPoint = coordinateSystem.transformThisPoint(rawPoint) - dataPoint = transformThisPoint(dataPoint, thisObject.container) - dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) - dataPoint = thisObject.fitFunction(dataPoint) - - /* Store the data point at the local map */ - dataPoint.rawPoint = rawPoint - dataPoints.set(point.id, dataPoint) - } - } - } - - /* Remember this datapoints, so that we do not need to calculate them again. */ - record.dataPoints = dataPoints - } - - /* Here we are going to plot all the polygons. */ - for (let j = 0; j < productDefinition.referenceParent.shapes.polygons.length; j++) { - let polygon = productDefinition.referenceParent.shapes.polygons[j] - /* We will check if we need to plot this Polygon or not. */ - if (polygon.polygonCondition !== undefined) { - let mustPlot = eval(polygon.polygonCondition.code) - if (mustPlot !== true) { continue } - } - - let calculatedStyle - - /* Finding out the fill style */ - let fillStyle = { // default values - opacity: 1, - paletteColor: UI_COLOR.BLACK - } - if (polygon.polygonBody !== undefined) { - if (record.fillStyle === undefined) { - record.fillStyle = new Map() - } - calculatedStyle = record.fillStyle.get(polygon.id) - if (calculatedStyle !== undefined) { - /* We use the already calculated style */ - fillStyle = calculatedStyle - } else { - /* Get the default style if exists */ - if (polygon.polygonBody.style !== undefined) { - if (polygon.polygonBody.style.config !== undefined) { - if (polygon.polygonBody.style.config.default !== undefined) { - let bodyStyle = polygon.polygonBody.style.config.default - if (bodyStyle.opacity !== undefined) { fillStyle.opacity = bodyStyle.opacity } - if (bodyStyle.paletteColor !== undefined) { fillStyle.paletteColor = eval(bodyStyle.paletteColor) } - } + if (i == 0) { + record.previous = {} // this way it wont be undefined + } else { + record.previous = records[i - 1] } - } - /* Apply conditional styles */ - if (polygon.polygonBody.styleConditions !== undefined) { - for (let k = 0; k < polygon.polygonBody.styleConditions.length; k++) { - let condition = polygon.polygonBody.styleConditions[k] - let value = eval(condition.code) - if (value === true) { - if (condition.style !== undefined) { - let bodyStyle = condition.style.config - if (bodyStyle.opacity !== undefined) { fillStyle.opacity = bodyStyle.opacity } - if (bodyStyle.paletteColor !== undefined) { fillStyle.paletteColor = eval(bodyStyle.paletteColor) } + + let beginPoint = { + x: record.begin, + y: 0 + } + + let endPoint = { + x: record.end, + y: 0 + } + + beginPoint = coordinateSystem.transformThisPoint(beginPoint) + endPoint = coordinateSystem.transformThisPoint(endPoint) + + beginPoint = transformThisPoint(beginPoint, thisObject.container) + endPoint = transformThisPoint(endPoint, thisObject.container) + + beginPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(beginPoint) + endPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(endPoint) + + beginPoint = thisObject.fitFunction(beginPoint) + endPoint = thisObject.fitFunction(endPoint) + + if (endPoint.x < canvas.chartingSpace.viewport.visibleArea.bottomLeft.x || beginPoint.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x) { + continue + } + + let atMousePosition = false + if (userPositionDate >= record.begin && userPositionDate <= record.end) { + if (record.rate !== undefined && productDefinition.referenceParent.config.useRateAtMousePosition === true) { + /* Current Record depends also on rate */ + if (record.rate >= minUserPositionRate && record.rate <= maxUserPositionRate) { + atMousePosition = true + thisObject.container.eventHandler.raiseEvent('Current Record Changed', record) + } + } else { + /* Current Record depends only on begin and end. */ + atMousePosition = true + thisObject.container.eventHandler.raiseEvent('Current Record Changed', record) } - } } - } - /* Get the atMousePosition style if exists */ - if (polygon.polygonBody.style !== undefined) { - if (polygon.polygonBody.style.config.atMousePosition !== undefined) { - let atMousePositionStyleDefinition = polygon.polygonBody.style.config.atMousePosition - let atMousePositionStyle = {} - if (atMousePositionStyleDefinition.opacity !== undefined) { atMousePositionStyle.opacity = atMousePositionStyleDefinition.opacity } - if (atMousePositionStyleDefinition.paletteColor !== undefined) { atMousePositionStyle.paletteColor = eval(atMousePositionStyleDefinition.paletteColor) } - atMousePositionFillStyles.set(polygon.id, atMousePositionStyle) - } - } - record.fillStyle.set(polygon.id, fillStyle) - } - } - - /* Finding out the stroke style */ - let strokeStyle = { // default values - opacity: 1, - paletteColor: UI_COLOR.BLACK, - lineWidth: 1, - lineDash: [0, 0] - } - if (polygon.polygonBorder !== undefined) { - if (record.strokeStyle === undefined) { - record.strokeStyle = new Map() - } - calculatedStyle = record.strokeStyle.get(polygon.id) - if (calculatedStyle !== undefined) { - /* We use the already calculated style */ - strokeStyle = calculatedStyle - } else { - /* Get the default style if exists */ - if (polygon.polygonBorder.style !== undefined) { - if (polygon.polygonBorder.style.config !== undefined) { - if (polygon.polygonBorder.style.config.default !== undefined) { - let borderStyle = polygon.polygonBorder.style.config.default - if (borderStyle.opacity !== undefined) { strokeStyle.opacity = borderStyle.opacity } - if (borderStyle.paletteColor !== undefined) { strokeStyle.paletteColor = eval(borderStyle.paletteColor) } - if (borderStyle.lineWidth !== undefined) { strokeStyle.lineWidth = borderStyle.lineWidth } - if (borderStyle.lineDash !== undefined) { strokeStyle.lineDash = borderStyle.lineDash } - } + /* If there is code we execute it now. */ + if (productDefinition.referenceParent.javascriptCode !== undefined) { + eval(productDefinition.referenceParent.javascriptCode.code) } - } - /* Apply conditional styles */ - if (polygon.polygonBorder.styleConditions !== undefined) { - for (let k = 0; k < polygon.polygonBorder.styleConditions.length; k++) { - let condition = polygon.polygonBorder.styleConditions[k] - let value = eval(condition.code) - if (value === true) { - if (condition.style !== undefined) { - let borderStyle = condition.style.config - if (borderStyle.opacity !== undefined) { strokeStyle.opacity = borderStyle.opacity } - if (borderStyle.paletteColor !== undefined) { strokeStyle.paletteColor = eval(borderStyle.paletteColor) } - if (borderStyle.lineWidth !== undefined) { strokeStyle.lineWidth = borderStyle.lineWidth } - if (borderStyle.lineDash !== undefined) { strokeStyle.lineDash = borderStyle.lineDash } + + if (productDefinition.referenceParent.shapes === undefined) { continue } + if (productDefinition.referenceParent.shapes.chartPoints === undefined) { continue } + let dataPoints = new Map() + if (record.dataPoints !== undefined && mustRecalculateDataPoints === false) { + /* We use the datapoints already calculated. */ + dataPoints = record.dataPoints + } else { + if (logged === false) { + logged = true } - } + /* It seems we need to calculate the data points this time. */ + for (let k = 0; k < productDefinition.referenceParent.shapes.chartPoints.length; k++) { + let chartPoints = productDefinition.referenceParent.shapes.chartPoints[k] + for (let j = 0; j < chartPoints.points.length; j++) { + let point = chartPoints.points[j] + if (point.pointFormula !== undefined) { + let x = 0 + let y = 0 + eval(point.pointFormula.code) + let rawPoint = { + x: x, + y: y + } + + /* + The information we store in files is independent from the charing system and its coordinate systems. + That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline. + */ + let dataPoint + dataPoint = coordinateSystem.transformThisPoint(rawPoint) + dataPoint = transformThisPoint(dataPoint, thisObject.container) + dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) + dataPoint = thisObject.fitFunction(dataPoint) + + /* Store the data point at the local map */ + dataPoint.rawPoint = rawPoint + dataPoints.set(point.id, dataPoint) + } + } + } + + /* Remember this datapoints, so that we do not need to calculate them again. */ + record.dataPoints = dataPoints } - } - /* Get the atMousePosition style if exists */ - if (polygon.polygonBorder.style !== undefined) { - if (polygon.polygonBorder.style.config.atMousePosition !== undefined) { - let atMousePositionStyleDefinition = polygon.polygonBorder.style.config.atMousePosition - let atMousePositionStyle = {} - if (atMousePositionStyleDefinition.opacity !== undefined) { atMousePositionStyle.opacity = atMousePositionStyleDefinition.opacity } - if (atMousePositionStyleDefinition.paletteColor !== undefined) { atMousePositionStyle.paletteColor = eval(atMousePositionStyleDefinition.paletteColor) } - if (atMousePositionStyleDefinition.lineWidth !== undefined) { atMousePositionStyle.lineWidth = atMousePositionStyleDefinition.lineWidth } - if (atMousePositionStyleDefinition.lineDash !== undefined) { atMousePositionStyle.lineDash = atMousePositionStyleDefinition.lineDash } - atMousePositionStrokeStyles.set(polygon.id, atMousePositionStyle) + + /* Here we are going to plot all the polygons. */ + for (let j = 0; j < productDefinition.referenceParent.shapes.polygons.length; j++) { + let polygon = productDefinition.referenceParent.shapes.polygons[j] + /* We will check if we need to plot this Polygon or not. */ + if (polygon.polygonCondition !== undefined) { + let mustPlot = eval(polygon.polygonCondition.code) + if (mustPlot !== true) { continue } + } + + let calculatedStyle + + /* Finding out the fill style */ + let fillStyle = { // default values + opacity: 1, + paletteColor: UI_COLOR.BLACK + } + if (polygon.polygonBody !== undefined) { + if (record.fillStyle === undefined) { + record.fillStyle = new Map() + } + calculatedStyle = record.fillStyle.get(polygon.id) + if (calculatedStyle !== undefined) { + /* We use the already calculated style */ + fillStyle = calculatedStyle + } else { + /* Get the default style if exists */ + if (polygon.polygonBody.style !== undefined) { + if (polygon.polygonBody.style.config !== undefined) { + if (polygon.polygonBody.style.config.default !== undefined) { + let bodyStyle = polygon.polygonBody.style.config.default + if (bodyStyle.opacity !== undefined) { fillStyle.opacity = bodyStyle.opacity } + if (bodyStyle.paletteColor !== undefined) { fillStyle.paletteColor = eval(bodyStyle.paletteColor) } + } + } + } + /* Apply conditional styles */ + if (polygon.polygonBody.styleConditions !== undefined) { + for (let k = 0; k < polygon.polygonBody.styleConditions.length; k++) { + let condition = polygon.polygonBody.styleConditions[k] + let value = eval(condition.code) + if (value === true) { + if (condition.style !== undefined) { + let bodyStyle = condition.style.config + if (bodyStyle.opacity !== undefined) { fillStyle.opacity = bodyStyle.opacity } + if (bodyStyle.paletteColor !== undefined) { fillStyle.paletteColor = eval(bodyStyle.paletteColor) } + } + } + } + } + /* Get the atMousePosition style if exists */ + if (polygon.polygonBody.style !== undefined) { + if (polygon.polygonBody.style.config.atMousePosition !== undefined) { + let atMousePositionStyleDefinition = polygon.polygonBody.style.config.atMousePosition + let atMousePositionStyle = {} + if (atMousePositionStyleDefinition.opacity !== undefined) { atMousePositionStyle.opacity = atMousePositionStyleDefinition.opacity } + if (atMousePositionStyleDefinition.paletteColor !== undefined) { atMousePositionStyle.paletteColor = eval(atMousePositionStyleDefinition.paletteColor) } + atMousePositionFillStyles.set(polygon.id, atMousePositionStyle) + } + } + + record.fillStyle.set(polygon.id, fillStyle) + } + } + + /* Finding out the stroke style */ + let strokeStyle = { // default values + opacity: 1, + paletteColor: UI_COLOR.BLACK, + lineWidth: 1, + lineDash: [0, 0] + } + if (polygon.polygonBorder !== undefined) { + if (record.strokeStyle === undefined) { + record.strokeStyle = new Map() + } + calculatedStyle = record.strokeStyle.get(polygon.id) + if (calculatedStyle !== undefined) { + /* We use the already calculated style */ + strokeStyle = calculatedStyle + } else { + /* Get the default style if exists */ + if (polygon.polygonBorder.style !== undefined) { + if (polygon.polygonBorder.style.config !== undefined) { + if (polygon.polygonBorder.style.config.default !== undefined) { + let borderStyle = polygon.polygonBorder.style.config.default + if (borderStyle.opacity !== undefined) { strokeStyle.opacity = borderStyle.opacity } + if (borderStyle.paletteColor !== undefined) { strokeStyle.paletteColor = eval(borderStyle.paletteColor) } + if (borderStyle.lineWidth !== undefined) { strokeStyle.lineWidth = borderStyle.lineWidth } + if (borderStyle.lineDash !== undefined) { strokeStyle.lineDash = borderStyle.lineDash } + } + } + } + /* Apply conditional styles */ + if (polygon.polygonBorder.styleConditions !== undefined) { + for (let k = 0; k < polygon.polygonBorder.styleConditions.length; k++) { + let condition = polygon.polygonBorder.styleConditions[k] + let value = eval(condition.code) + if (value === true) { + if (condition.style !== undefined) { + let borderStyle = condition.style.config + if (borderStyle.opacity !== undefined) { strokeStyle.opacity = borderStyle.opacity } + if (borderStyle.paletteColor !== undefined) { strokeStyle.paletteColor = eval(borderStyle.paletteColor) } + if (borderStyle.lineWidth !== undefined) { strokeStyle.lineWidth = borderStyle.lineWidth } + if (borderStyle.lineDash !== undefined) { strokeStyle.lineDash = borderStyle.lineDash } + } + } + } + } + /* Get the atMousePosition style if exists */ + if (polygon.polygonBorder.style !== undefined) { + if (polygon.polygonBorder.style.config.atMousePosition !== undefined) { + let atMousePositionStyleDefinition = polygon.polygonBorder.style.config.atMousePosition + let atMousePositionStyle = {} + if (atMousePositionStyleDefinition.opacity !== undefined) { atMousePositionStyle.opacity = atMousePositionStyleDefinition.opacity } + if (atMousePositionStyleDefinition.paletteColor !== undefined) { atMousePositionStyle.paletteColor = eval(atMousePositionStyleDefinition.paletteColor) } + if (atMousePositionStyleDefinition.lineWidth !== undefined) { atMousePositionStyle.lineWidth = atMousePositionStyleDefinition.lineWidth } + if (atMousePositionStyleDefinition.lineDash !== undefined) { atMousePositionStyle.lineDash = atMousePositionStyleDefinition.lineDash } + atMousePositionStrokeStyles.set(polygon.id, atMousePositionStyle) + } + } + + record.strokeStyle.set(polygon.id, strokeStyle) + } + } + + /* Draw the Polygon */ + browserCanvasContext.beginPath() + for (let k = 0; k < polygon.polygonVertexes.length; k++) { + let polygonVertex = polygon.polygonVertexes[k] + if (polygonVertex.referenceParent !== undefined) { + let dataPointObject = dataPoints.get(polygonVertex.referenceParent.id) + if (dataPointObject === undefined) { + console.log('[WARN] You have a Polygon Vertex not referencing any Point.') + continue + } + + /* Contributing to Auto-Scale */ + if (dataPointObject.rawPoint.y > 1 && dataPointObject.rawPoint.y !== undefined && isNaN(dataPointObject.rawPoint.y) === false) { + coordinateSystem.reportYValue(dataPointObject.rawPoint.y) + } + + let dataPoint = { + x: dataPointObject.x, + y: dataPointObject.y + } + /* We make sure the points do not fall outside the viewport visible area. This step allways need to be done. */ + dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) + dataPoint = thisObject.fitFunction(dataPoint) + if (k === 0) { + browserCanvasContext.moveTo(dataPoint.x, dataPoint.y) + } else { + browserCanvasContext.lineTo(dataPoint.x, dataPoint.y) + } + } + } + browserCanvasContext.closePath() + + /* Apply the fill style to the canvas object */ + if (polygon.polygonBody !== undefined) { + /* Replace the fill style if we are at mouse position */ + if (atMousePosition === true) { + let atMousePositionFillStyle = atMousePositionFillStyles.get(polygon.id) + if (atMousePositionFillStyle !== undefined) { + fillStyle = atMousePositionFillStyle + } + } + + browserCanvasContext.fillStyle = 'rgba(' + fillStyle.paletteColor + ', ' + fillStyle.opacity + ')' + browserCanvasContext.fill() + } + + /* Apply the stroke style to the canvas object */ + if (polygon.polygonBorder !== undefined) { + /* Replace the stroke style if we are at mouse position */ + if (atMousePosition === true) { + let atMousePositionStrokeStyle = atMousePositionStrokeStyles.get(polygon.id) + if (atMousePositionStrokeStyle !== undefined) { + strokeStyle = atMousePositionStrokeStyle + } + } + + browserCanvasContext.lineWidth = strokeStyle.lineWidth + browserCanvasContext.setLineDash(strokeStyle.lineDash) + browserCanvasContext.strokeStyle = 'rgba(' + strokeStyle.paletteColor + ', ' + strokeStyle.opacity + ')' + browserCanvasContext.stroke() + } } - } - record.strokeStyle.set(polygon.id, strokeStyle) - } - } + /* Here we are going to plot images. */ + for (let j = 0; j < productDefinition.referenceParent.shapes.images.length; j++) { + let image = productDefinition.referenceParent.shapes.images[j] + if (image.imagePosition === undefined) { continue } + if (image.imagePosition.referenceParent === undefined) { continue } + if (image.imageCondition !== undefined) { + let mustPlot = eval(image.imageCondition.code) + if (mustPlot !== true) { continue } + } + let imageName = '' + let imageSize = 0 + let offsetX = 0 + let offsetY = 0 + let imagePosition = { x: 0, y: 0 } + if (image.config.codeName !== undefined) { imageName = image.config.codeName } + if (image.config.size !== undefined) { imageSize = image.config.size } + if (image.imagePosition.config.offsetX !== undefined) { offsetX = image.imagePosition.config.offsetX } + if (image.imagePosition.config.offsetY !== undefined) { offsetY = image.imagePosition.config.offsetY } + let dataPointObject = dataPoints.get(image.imagePosition.referenceParent.id) + if (dataPointObject === undefined) { continue } + let dataPoint = { + x: dataPointObject.x, + y: dataPointObject.y + } + dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) + dataPoint = thisObject.fitFunction(dataPoint) + imagePosition.x = dataPoint.x + imagePosition.y = dataPoint.y + let imageToDraw = canvas.designSpace.iconCollection.get(imageName) + if (imageToDraw.canDrawIcon === true) { + browserCanvasContext.drawImage(imageToDraw, imagePosition.x - imageSize / 2 + offsetX, imagePosition.y - imageSize / 2 - offsetY, imageSize, imageSize) + } + } - /* Draw the Polygon */ - browserCanvasContext.beginPath() - for (let k = 0; k < polygon.polygonVertexes.length; k++) { - let polygonVertex = polygon.polygonVertexes[k] - if (polygonVertex.referenceParent !== undefined) { - let dataPointObject = dataPoints.get(polygonVertex.referenceParent.id) - if (dataPointObject === undefined) { - console.log('[WARN] You have a Polygon Vertex not referencing any Point.') - continue - } + /* Here we are going to plot texts. */ + for (let j = 0; j < productDefinition.referenceParent.shapes.texts.length; j++) { + let text = productDefinition.referenceParent.shapes.texts[j] + if (text.textPosition === undefined) { continue } + if (text.textPosition.referenceParent === undefined) { continue } + if (text.textCondition !== undefined) { + let mustPlot = eval(text.textCondition.code) + if (mustPlot !== true) { continue } + } + if (text.textFormula === undefined) { continue } + if (text.textStyle === undefined) { continue } + let value = eval(text.textFormula.code) + let fontSize = 0 + let opacity = 0 + let paletteColor = UI_COLOR.GREY + let offsetX = 0 + let offsetY = 0 + let textPosition = { x: 0, y: 0 } + if (text.textStyle.config.fontSize !== undefined) { fontSize = text.textStyle.config.fontSize } + if (text.textStyle.config.opacity !== undefined) { opacity = text.textStyle.config.opacity } + if (text.textStyle.config.paletteColor !== undefined) { paletteColor = eval(text.textStyle.config.paletteColor) } + if (text.textPosition.config.offsetX !== undefined) { offsetX = text.textPosition.config.offsetX } + if (text.textPosition.config.offsetY !== undefined) { offsetY = text.textPosition.config.offsetY } + let dataPointObject = dataPoints.get(text.textPosition.referenceParent.id) + if (dataPointObject === undefined) { continue } + let dataPoint = { + x: dataPointObject.x, + y: dataPointObject.y + } + dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) + dataPoint = thisObject.fitFunction(dataPoint) + textPosition.x = dataPoint.x + textPosition.y = dataPoint.y - /* Contributing to Auto-Scale */ - if (dataPointObject.rawPoint.y > 1 && dataPointObject.rawPoint.y !== undefined && isNaN(dataPointObject.rawPoint.y) === false) { - coordinateSystem.reportYValue(dataPointObject.rawPoint.y) - } - - let dataPoint = { - x: dataPointObject.x, - y: dataPointObject.y - } - /* We make sure the points do not fall outside the viewport visible area. This step allways need to be done. */ - dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) - dataPoint = thisObject.fitFunction(dataPoint) - if (k === 0) { - browserCanvasContext.moveTo(dataPoint.x, dataPoint.y) - } else { - browserCanvasContext.lineTo(dataPoint.x, dataPoint.y) - } - } - } - browserCanvasContext.closePath() - - /* Apply the fill style to the canvas object */ - if (polygon.polygonBody !== undefined) { - /* Replace the fill style if we are at mouse position */ - if (atMousePosition === true) { - let atMousePositionFillStyle = atMousePositionFillStyles.get(polygon.id) - if (atMousePositionFillStyle !== undefined) { - fillStyle = atMousePositionFillStyle - } + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + paletteColor + ', ' + opacity + ')' + browserCanvasContext.fillText(value, textPosition.x + offsetX, textPosition.y - offsetY) + } } - browserCanvasContext.fillStyle = 'rgba(' + fillStyle.paletteColor + ', ' + fillStyle.opacity + ')' - browserCanvasContext.fill() - } - - /* Apply the stroke style to the canvas object */ - if (polygon.polygonBorder !== undefined) { - /* Replace the stroke style if we are at mouse position */ - if (atMousePosition === true) { - let atMousePositionStrokeStyle = atMousePositionStrokeStyles.get(polygon.id) - if (atMousePositionStrokeStyle !== undefined) { - strokeStyle = atMousePositionStrokeStyle - } + if (coordinateSystem.autoMinYScale === true || coordinateSystem.autoMinYScale === true) { + mustRecalculateDataPoints = true + } else { + mustRecalculateDataPoints = false } - browserCanvasContext.lineWidth = strokeStyle.lineWidth - browserCanvasContext.setLineDash(strokeStyle.lineDash) - browserCanvasContext.strokeStyle = 'rgba(' + strokeStyle.paletteColor + ', ' + strokeStyle.opacity + ')' - browserCanvasContext.stroke() - } + logged = false + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] plot -> err = ' + err.stack) } } - - /* Here we are going to plot images. */ - for (let j = 0; j < productDefinition.referenceParent.shapes.images.length; j++) { - let image = productDefinition.referenceParent.shapes.images[j] - if (image.imagePosition === undefined) { continue } - if (image.imagePosition.referenceParent === undefined) { continue } - if (image.imageCondition !== undefined) { - let mustPlot = eval(image.imageCondition.code) - if (mustPlot !== true) { continue } - } - let imageName = '' - let imageSize = 0 - let offsetX = 0 - let offsetY = 0 - let imagePosition = { x: 0, y: 0 } - if (image.config.codeName !== undefined) { imageName = image.config.codeName } - if (image.config.size !== undefined) { imageSize = image.config.size } - if (image.imagePosition.config.offsetX !== undefined) { offsetX = image.imagePosition.config.offsetX } - if (image.imagePosition.config.offsetY !== undefined) { offsetY = image.imagePosition.config.offsetY } - let dataPointObject = dataPoints.get(image.imagePosition.referenceParent.id) - if (dataPointObject === undefined) { continue } - let dataPoint = { - x: dataPointObject.x, - y: dataPointObject.y - } - dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) - dataPoint = thisObject.fitFunction(dataPoint) - imagePosition.x = dataPoint.x - imagePosition.y = dataPoint.y - let imageToDraw = canvas.designSpace.iconCollection.get(imageName) - if (imageToDraw.canDrawIcon === true) { - browserCanvasContext.drawImage(imageToDraw, imagePosition.x - imageSize / 2 + offsetX, imagePosition.y - imageSize / 2 - offsetY, imageSize, imageSize) - } - } - - /* Here we are going to plot texts. */ - for (let j = 0; j < productDefinition.referenceParent.shapes.texts.length; j++) { - let text = productDefinition.referenceParent.shapes.texts[j] - if (text.textPosition === undefined) { continue } - if (text.textPosition.referenceParent === undefined) { continue } - if (text.textCondition !== undefined) { - let mustPlot = eval(text.textCondition.code) - if (mustPlot !== true) { continue } - } - if (text.textFormula === undefined) { continue } - if (text.textStyle === undefined) { continue } - let value = eval(text.textFormula.code) - let fontSize = 0 - let opacity = 0 - let paletteColor = UI_COLOR.GREY - let offsetX = 0 - let offsetY = 0 - let textPosition = { x: 0, y: 0 } - if (text.textStyle.config.fontSize !== undefined) { fontSize = text.textStyle.config.fontSize } - if (text.textStyle.config.opacity !== undefined) { opacity = text.textStyle.config.opacity } - if (text.textStyle.config.paletteColor !== undefined) { paletteColor = eval(text.textStyle.config.paletteColor) } - if (text.textPosition.config.offsetX !== undefined) { offsetX = text.textPosition.config.offsetX } - if (text.textPosition.config.offsetY !== undefined) { offsetY = text.textPosition.config.offsetY } - let dataPointObject = dataPoints.get(text.textPosition.referenceParent.id) - if (dataPointObject === undefined) { continue } - let dataPoint = { - x: dataPointObject.x, - y: dataPointObject.y - } - dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) - dataPoint = thisObject.fitFunction(dataPoint) - textPosition.x = dataPoint.x - textPosition.y = dataPoint.y - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + paletteColor + ', ' + opacity + ')' - browserCanvasContext.fillText(value, textPosition.x + offsetX, textPosition.y - offsetY) - } - } - - if (coordinateSystem.autoMinYScale === true || coordinateSystem.autoMinYScale === true) { - mustRecalculateDataPoints = true - } else { - mustRecalculateDataPoints = false - } - - logged = false - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] plot -> err = ' + err.stack) } } - } - function onViewportZoomChanged(event) { - try { - mustRecalculateDataPoints = true - recalculate() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onViewportZoomChanged -> err = ' + err.stack) } + function onViewportZoomChanged(event) { + try { + mustRecalculateDataPoints = true + recalculate() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onViewportZoomChanged -> err = ' + err.stack) } + } } - } - function onDragFinished() { - recalculate() - } - - function onDisplace(event) { - recalculateAll(event) - } - - function onViewportPositionChanged(event) { - recalculateAll(event) - } - - function recalculateAll(event) { - mustRecalculateDataPoints = true - if (event !== undefined) { - if (event.recalculate === true) { + function onDragFinished() { recalculate() - return - } } - if (Math.random() * 100 > 95) { - recalculate() + + function onDisplace(event) { + recalculateAll(event) + } + + function onViewportPositionChanged(event) { + recalculateAll(event) + } + + function recalculateAll(event) { + mustRecalculateDataPoints = true + if (event !== undefined) { + if (event.recalculate === true) { + recalculate() + return + } + } + if (Math.random() * 100 > 95) { + recalculate() + } } - } } From 199a71a4e5725ab0b14010a999beebb4dfd0a2b4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 29 Jul 2020 11:09:04 +0200 Subject: [PATCH 004/192] Change in Code Indentation --- Animation.js | 292 +- Canvas.js | 2100 +++++----- ChartingSpace/ChartUtilities.js | 206 +- ChartingSpace/CoordinateSystem.js | 612 +-- ChartingSpace/EdgeEditor.js | 1308 +++--- ChartingSpace/PlottersManager.js | 868 ++-- ChartingSpace/TimeMachine.js | 1528 +++---- ChartingSpace/TimelineChart.js | 798 ++-- ChartingSpace/Viewport.js | 744 ++-- CockpitSpace/AssetBalances.js | 208 +- CockpitSpace/FullScreen.js | 314 +- CockpitSpace/Speedometer.js | 476 +-- Container.js | 480 +-- .../FunctionLibraries/CCXTFunctions.js | 422 +- .../FunctionLibraries/ChainAttachDetach.js | 392 +- .../FunctionLibraries/DependenciesFilter.js | 118 +- .../FunctionLibraries/NodeChildren.js | 124 +- .../FunctionLibraries/NodeCloning.js | 308 +- .../FunctionLibraries/NodeDeleter.js | 236 +- .../Workspace/FunctionLibraries/OnFocus.js | 94 +- .../FunctionLibraries/ProtocolNode.js | 342 +- .../ReferenceAttachDetach.js | 56 +- .../FunctionLibraries/SessionFunctions.js | 324 +- .../FunctionLibraries/ShortcutKeys.js | 92 +- .../FunctionLibraries/SuperScripts.js | 152 +- .../FunctionLibraries/TaskFunctions.js | 404 +- .../FunctionLibraries/UiObjectsFromNodes.js | 1088 ++--- .../FunctionLibraries/WebhookFunctions.js | 32 +- DesignSpace/Workspace/Workspace.js | 1170 +++--- EventHandler.js | 76 +- EventsServerClient.js | 386 +- FloatingSpace/BusyProgressBar.js | 116 +- FloatingSpace/CircularMenu.js | 386 +- FloatingSpace/CircularMenuItem.js | 822 ++-- FloatingSpace/CircularProgressBar.js | 260 +- FloatingSpace/CodeEditor.js | 354 +- FloatingSpace/ConditionEditor.js | 2206 +++++----- FloatingSpace/ConfigEditor.js | 364 +- FloatingSpace/FloatingLayer.js | 1056 ++--- FloatingSpace/FloatingObject.js | 1288 +++--- FloatingSpace/FormulaEditor.js | 354 +- FloatingSpace/Picker.js | 408 +- FloatingSpace/UiObject.js | 3638 ++++++++--------- FloatingSpace/UiObjectConstructor.js | 1204 +++--- FloatingSpace/UiObjectTitle.js | 642 +-- Frame.js | 954 ++--- Globals.js | 54 +- Panels/Layer.js | 1214 +++--- Panels/LayersPanel.js | 956 ++--- Panels/LeftRightButton.js | 424 +- Panels/PanelsVisibleButton.js | 154 +- Panels/PlotterPanel.js | 322 +- Panels/UpDownButton.js | 424 +- Plotting/NodesAnnouncements.js | 84 +- Plotting/NodesErrors.js | 84 +- Plotting/NodesHighlights.js | 76 +- Plotting/NodesProgress.js | 84 +- Plotting/NodesRunning.js | 84 +- Plotting/NodesStatus.js | 84 +- Plotting/NodesValues.js | 84 +- Plotting/RecordValues.js | 154 +- PostLoader.js | 140 +- ProductStorage.js | 534 +-- Scales/AutoScaleButton.js | 370 +- Scales/Commons.js | 66 +- Scales/RateScale.js | 1036 ++--- Scales/TimeFrameScale.js | 708 ++-- Scales/TimeScale.js | 650 +-- SideSpace/ListItem.js | 200 +- SideSpace/ListView.js | 490 +-- SideSpace/SidePanelTab.js | 430 +- Spaces/ChartingSpace.js | 778 ++-- Spaces/CockpitSpace.js | 614 +-- Spaces/DesignSpace.js | 674 +-- Spaces/FloatingSpace.js | 726 ++-- Spaces/PanelsSpace.js | 686 ++-- Spaces/SideSpace.js | 274 +- Spaces/TopSpace.js | 184 +- SplashScreen.js | 230 +- Utilities.js | 144 +- Utilities/CoordinateTransformations.js | 16 +- Utilities/DateRateTransformations.js | 58 +- Utilities/Download.js | 96 +- Utilities/DrawPrint.js | 398 +- Utilities/HiriarchyMap.js | 68 +- Utilities/LoadSaveFrame.js | 40 +- Utilities/NodeConfig.js | 30 +- VideoRecorder.js | 426 +- WebDebugLog.js | 36 +- 89 files changed, 22093 insertions(+), 22093 deletions(-) diff --git a/Animation.js b/Animation.js index b43fcf413..3be427501 100644 --- a/Animation.js +++ b/Animation.js @@ -1,9 +1,9 @@ -function newAnimation () { - const MODULE_NAME = 'Animation' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newAnimation() { + const MODULE_NAME = 'Animation' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME /* @@ -13,162 +13,162 @@ function newAnimation () { */ - let animationLoopHandle // This is the handle to the animation loop. With this handle we can cancel the loop, for instance. - let callBackFunctions = new Map() + let animationLoopHandle // This is the handle to the animation loop. With this handle we can cancel the loop, for instance. + let callBackFunctions = new Map() - let thisObject = { - start: start, - stop: stop, - addCallBackFunction: addCallBackFunction, - removeCallBackFunction: removeCallBackFunction, - initialize: initialize, - finalize: finalize - } + let thisObject = { + start: start, + stop: stop, + addCallBackFunction: addCallBackFunction, + removeCallBackFunction: removeCallBackFunction, + initialize: initialize, + finalize: finalize + } - let totalConsumption = 0 - let totalCounter = 0 - let pointerIcon - let videoRecorder - return thisObject + let totalConsumption = 0 + let totalCounter = 0 + let pointerIcon + let videoRecorder + return thisObject - function finalize () { - thisObject.stop() - pointerIcon = undefined - videoRecorder = undefined - } + function finalize() { + thisObject.stop() + pointerIcon = undefined + videoRecorder = undefined + } - function initialize () { - videoRecorder = newVideoRecorder() - } + function initialize() { + videoRecorder = newVideoRecorder() + } - function start () { - animationLoop() // Inside this function the animation process is started, and at the same time it creates a loop. - } + function start() { + animationLoop() // Inside this function the animation process is started, and at the same time it creates a loop. + } - function stop () { - window.cancelAnimationFrame(animationLoopHandle) - } + function stop() { + window.cancelAnimationFrame(animationLoopHandle) + } - function addCallBackFunction (key, callBack) { - callBackFunctions.set(key, callBack) - } + function addCallBackFunction(key, callBack) { + callBackFunctions.set(key, callBack) + } - function removeCallBackFunction (key) { - callBackFunctions.delete(key) - } + function removeCallBackFunction(key) { + callBackFunctions.delete(key) + } - function animationLoop () { - try { - /* First thing is to clear the actual canvas */ - clearBrowserCanvas() + function animationLoop() { + try { + /* First thing is to clear the actual canvas */ + clearBrowserCanvas() - /* We loop through the callback functions collections and execute them all. */ - let performanceMap = new Map() - let totalTimeConsumed = 0 - let totalElements = 0 - let chanceToExecute - let randomNumber - let mustExecute + /* We loop through the callback functions collections and execute them all. */ + let performanceMap = new Map() + let totalTimeConsumed = 0 + let totalElements = 0 + let chanceToExecute + let randomNumber + let mustExecute - // console.clear() - let row = 0 - for (const [key, callBackFunction] of callBackFunctions.entries()) { - row++ - switch (key) { - case 'Floating Space Physics': - chanceToExecute = 50 - randomNumber = Math.random() * 100 * chanceToExecute - if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false } - break - default: { - mustExecute = true - } + // console.clear() + let row = 0 + for (const [key, callBackFunction] of callBackFunctions.entries()) { + row++ + switch (key) { + case 'Floating Space Physics': + chanceToExecute = 50 + randomNumber = Math.random() * 100 * chanceToExecute + if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false } + break + default: { + mustExecute = true + } - } - let timeConsumed = 0 - if (mustExecute === true) { - let t0 = performance.now() - callBackFunction() - let t1 = performance.now() - timeConsumed = t1 - t0 - if (key === 'Charting Space Draw') { - if (Math.random() * 100 > 99) { - totalConsumption = 0 - totalCounter = 0 + } + let timeConsumed = 0 + if (mustExecute === true) { + let t0 = performance.now() + callBackFunction() + let t1 = performance.now() + timeConsumed = t1 - t0 + if (key === 'Charting Space Draw') { + if (Math.random() * 100 > 99) { + totalConsumption = 0 + totalCounter = 0 + } + + totalConsumption = totalConsumption + timeConsumed + totalCounter = totalCounter + 1 + } + performanceMap.set(key, timeConsumed) + totalTimeConsumed = totalTimeConsumed + timeConsumed + totalElements++ + } } - totalConsumption = totalConsumption + timeConsumed - totalCounter = totalCounter + 1 - } - performanceMap.set(key, timeConsumed) - totalTimeConsumed = totalTimeConsumed + timeConsumed - totalElements++ + /* Frame per Seconds */ + + ANIMATION_FRAME_PER_SECONDS = Math.trunc(1000 / totalTimeConsumed) + + /* Performance Check */ + if (SHOW_ANIMATION_PERFORMACE === true) { + row = 0 + for (const [key, timeConsumed] of performanceMap.entries()) { + row++ + labelToPrint = key + ' ' + timeConsumed.toFixed(4) + printLabel(labelToPrint, 10, 100 + row * 30, 1, 20, UI_COLOR.RED) + let percentage = timeConsumed * 100 / totalTimeConsumed + labelToPrint = key + ' ' + percentage.toFixed(1) + '%' + printLabel(labelToPrint, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) + } + + /* Other Variables */ + row++ + printLabel(DEBUG.variable1, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) + row++ + printLabel(DEBUG.variable2, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) + row++ + printLabel(DEBUG.variable3, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) + row++ + printLabel(DEBUG.variable4, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) + row++ + printLabel('Animation Frame Per Seconds: ' + ANIMATION_FRAME_PER_SECONDS, 300, 100 + row * 30, 1, 20, UI_COLOR.TITANIUM_YELLOW) + } + + /* Video Recording */ + videoRecorder.physics() + if (ARE_WE_RECORDING_A_VIDEO === true) { + videoRecorder.recordCanvas() + } + + /* Panorama Recording */ + if (ARE_WE_RECORDING_A_MARKET_PANORAMA === true) { + if (PANORAMA_WAS_PANNED === true) { + addToMarketPanorama() + PANORAMA_WAS_PANNED = false + } + } + + /* We request the next frame to be drawn, and stablishing a loop */ + + /* Use this code for full animation speed. */ + animationLoopHandle = window.requestAnimationFrame(animationLoop) + + /* Use this code for max 10 frames per second animation speed, if the app is consumming too much of your CPU. */ + /* + setTimeout(nextLoop, 100) + function nextLoop () { + animationLoopHandle = window.requestAnimationFrame(animationLoop) + } + */ + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] animationLoop -> err = ' + err.stack) } } - } - - /* Frame per Seconds */ - - ANIMATION_FRAME_PER_SECONDS = Math.trunc(1000 / totalTimeConsumed) - - /* Performance Check */ - if (SHOW_ANIMATION_PERFORMACE === true) { - row = 0 - for (const [key, timeConsumed] of performanceMap.entries()) { - row++ - labelToPrint = key + ' ' + timeConsumed.toFixed(4) - printLabel(labelToPrint, 10, 100 + row * 30, 1, 20, UI_COLOR.RED) - let percentage = timeConsumed * 100 / totalTimeConsumed - labelToPrint = key + ' ' + percentage.toFixed(1) + '%' - printLabel(labelToPrint, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) - } - - /* Other Variables */ - row++ - printLabel(DEBUG.variable1, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) - row++ - printLabel(DEBUG.variable2, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) - row++ - printLabel(DEBUG.variable3, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) - row++ - printLabel(DEBUG.variable4, 300, 100 + row * 30, 1, 20, UI_COLOR.RED) - row++ - printLabel('Animation Frame Per Seconds: ' + ANIMATION_FRAME_PER_SECONDS, 300, 100 + row * 30, 1, 20, UI_COLOR.TITANIUM_YELLOW) - } - - /* Video Recording */ - videoRecorder.physics() - if (ARE_WE_RECORDING_A_VIDEO === true) { - videoRecorder.recordCanvas() - } - - /* Panorama Recording */ - if (ARE_WE_RECORDING_A_MARKET_PANORAMA === true) { - if (PANORAMA_WAS_PANNED === true) { - addToMarketPanorama() - PANORAMA_WAS_PANNED = false - } - } - - /* We request the next frame to be drawn, and stablishing a loop */ - - /* Use this code for full animation speed. */ - animationLoopHandle = window.requestAnimationFrame(animationLoop) - - /* Use this code for max 10 frames per second animation speed, if the app is consumming too much of your CPU. */ - /* - setTimeout(nextLoop, 100) - function nextLoop () { - animationLoopHandle = window.requestAnimationFrame(animationLoop) - } - */ - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] animationLoop -> err = ' + err.stack) } } - } - function clearBrowserCanvas () { - if (canWeDraw === false) { return } - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.clearRect(0, 0, browserCanvas.width, browserCanvas.height) - } + function clearBrowserCanvas() { + if (canWeDraw === false) { return } + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.clearRect(0, 0, browserCanvas.width, browserCanvas.height) + } } diff --git a/Canvas.js b/Canvas.js index 50f08991c..d5b2cf6ac 100644 --- a/Canvas.js +++ b/Canvas.js @@ -4,1105 +4,1105 @@ let browserCanvasContext // The context of the canvas object. let stepsInitializationCounter = 0 // This counter the initialization steps required to be able to turn off the splash screen. let marketInitializationCounter = 0 // This counter the initialization of markets required to be able to turn off the splash screen. -function newCanvas () { - const MODULE_NAME = 'Canvas' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newCanvas() { + const MODULE_NAME = 'Canvas' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - /* Mouse event related variables. */ + /* Mouse event related variables. */ - let containerDragStarted = false - let floatingObjectDragStarted = false - let floatingObjectBeingDragged - let containerBeingDragged - let viewPortBeingDragged = false - let ignoreNextClick = false + let containerDragStarted = false + let floatingObjectDragStarted = false + let floatingObjectBeingDragged + let containerBeingDragged + let viewPortBeingDragged = false + let ignoreNextClick = false - let dragVector = { - downX: 0, - downY: 0, - upX: 0, - upY: 0 - } - - /* canvas object */ - - let thisObject = { - eventHandler: undefined, - topSpace: undefined, - sideSpace: undefined, - chartingSpace: undefined, - floatingSpace: undefined, - panelsSpace: undefined, - cockpitSpace: undefined, - designSpace: undefined, - splashScreen: undefined, - animation: undefined, - mouse: undefined, - shorcutNumbers: new Map(), - initialize: initialize, - finalize: finalize - } - - thisObject.eventHandler = newEventHandler() - - let lastContainerMouseOver - let lastShortcutKeyRejection - - thisObject.mouse = { - position: { - x: 0, - y: 0 - }, - action: '' - } - - return thisObject - - function finalize () { - try { - thisObject.sideSpace.finalize() - thisObject.chartingSpace.finalize() - thisObject.floatingSpace.finalize() - thisObject.shorcutNumbers = undefined - - browserCanvas.removeEventListener('mousedown', onMouseDown, false) - browserCanvas.removeEventListener('mouseup', onMouseUp, false) - browserCanvas.removeEventListener('mousemove', onMouseMove, false) - browserCanvas.removeEventListener('click', onMouseClick, false) - browserCanvas.removeEventListener('mouseout', onMouseOut, false) - - if (browserCanvas.removeEventListener) { - browserCanvas.removeEventListener('mousewheel', onMouseWheel, false)// IE9, Chrome, Safari, Opera - browserCanvas.removeEventListener('DOMMouseScroll', onMouseWheel, false) // Firefox - } else browserCanvas.detachEvent('onmousewheel', onMouseWheel) // IE 6/7/8 - - browserCanvas.removeEventListener('dragenter', onDragEnter, false) - browserCanvas.removeEventListener('dragleave', onDragLeave, false) - browserCanvas.removeEventListener('dragover', onDragOver, false) - browserCanvas.removeEventListener('drop', onDragDrop, false) - - browserCanvas.removeEventListener('keydown', onKeyDown, false) - browserCanvas.removeEventListener('keyup', onKeyUp, false) - - thisObject.splashScreen = undefined - lastContainerMouseOver = undefined - - hisObject.mouse = undefined - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) } + let dragVector = { + downX: 0, + downY: 0, + upX: 0, + upY: 0 } - } - function initialize () { - try { - browserResized() - initializeBrowserCanvas() - addCanvasEvents() + /* canvas object */ - /* Instantiate all the children spaces of Canvas object */ - thisObject.floatingSpace = newFloatingSpace() - thisObject.floatingSpace.initialize() - - thisObject.topSpace = newTopSpace() - thisObject.topSpace.initialize() - - thisObject.cockpitSpace = newCockpitSpace() - thisObject.cockpitSpace.initialize() - - thisObject.designSpace = newDesignSpace() - thisObject.designSpace.initialize() - - thisObject.panelsSpace = newPanelsSpace() - thisObject.panelsSpace.initialize() - - thisObject.chartingSpace = newChartingSpace() - thisObject.chartingSpace.initialize() - - thisObject.sideSpace = newSideSpace() - thisObject.sideSpace.initialize() - - thisObject.splashScreen = newSplashScreen() - - let animation = newAnimation() - animation.initialize() - - thisObject.animation = animation - - /* Spcaces Physics */ - animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics) - animation.addCallBackFunction('Floating Space Physics', thisObject.floatingSpace.physics) - animation.addCallBackFunction('Charting Space Physics', thisObject.chartingSpace.physics) - animation.addCallBackFunction('Design Space Physics', thisObject.designSpace.physics) - animation.addCallBackFunction('Panels Space Physics', thisObject.panelsSpace.physics) - animation.addCallBackFunction('Side Space Physics', thisObject.sideSpace.physics) - - /* Spcaces Drawing */ - animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw) - animation.addCallBackFunction('Charting Space Draw', thisObject.chartingSpace.draw) - animation.addCallBackFunction('Panels Space', thisObject.panelsSpace.draw) - animation.addCallBackFunction('CockpitSpace Draw', thisObject.cockpitSpace.draw) - animation.addCallBackFunction('Design Space Draw', thisObject.designSpace.draw) - animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw) - animation.addCallBackFunction('Side Space Draw', thisObject.sideSpace.draw) - animation.addCallBackFunction('Splash Screen Draw', thisObject.splashScreen.draw) - animation.start() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } + let thisObject = { + eventHandler: undefined, + topSpace: undefined, + sideSpace: undefined, + chartingSpace: undefined, + floatingSpace: undefined, + panelsSpace: undefined, + cockpitSpace: undefined, + designSpace: undefined, + splashScreen: undefined, + animation: undefined, + mouse: undefined, + shorcutNumbers: new Map(), + initialize: initialize, + finalize: finalize } - } - function initializeBrowserCanvas () { - try { - browserCanvasContext = browserCanvas.getContext('2d') - browserCanvasContext.font = 'Saira Condensed' - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initializeBrowserCanvas -> err = ' + err.stack) } + thisObject.eventHandler = newEventHandler() + + let lastContainerMouseOver + let lastShortcutKeyRejection + + thisObject.mouse = { + position: { + x: 0, + y: 0 + }, + action: '' } - } - function addCanvasEvents () { - try { - canvas.eventHandler.listenToEvent('Browser Resized', browserResized) + return thisObject - /* Keyboard events */ - window.addEventListener('keydown', onKeyDown, true) - window.addEventListener('keyup', onKeyUp, true) + function finalize() { + try { + thisObject.sideSpace.finalize() + thisObject.chartingSpace.finalize() + thisObject.floatingSpace.finalize() + thisObject.shorcutNumbers = undefined - /* Mouse Events */ - browserCanvas.addEventListener('mousedown', onMouseDown, false) - browserCanvas.addEventListener('mouseup', onMouseUp, false) - browserCanvas.addEventListener('mousemove', onMouseMove, false) - browserCanvas.addEventListener('click', onMouseClick, false) - browserCanvas.addEventListener('mouseout', onMouseOut, false) + browserCanvas.removeEventListener('mousedown', onMouseDown, false) + browserCanvas.removeEventListener('mouseup', onMouseUp, false) + browserCanvas.removeEventListener('mousemove', onMouseMove, false) + browserCanvas.removeEventListener('click', onMouseClick, false) + browserCanvas.removeEventListener('mouseout', onMouseOut, false) - if (browserCanvas.addEventListener) { - browserCanvas.addEventListener('mousewheel', onMouseWheel, false) // IE9, Chrome, Safari, Opera - browserCanvas.addEventListener('DOMMouseScroll', onMouseWheel, false) // Firefox - } else browserCanvas.attachEvent('onmousewheel', onMouseWheel)// IE 6/7/8 + if (browserCanvas.removeEventListener) { + browserCanvas.removeEventListener('mousewheel', onMouseWheel, false)// IE9, Chrome, Safari, Opera + browserCanvas.removeEventListener('DOMMouseScroll', onMouseWheel, false) // Firefox + } else browserCanvas.detachEvent('onmousewheel', onMouseWheel) // IE 6/7/8 - /* Dragging Files Over the Canvas */ - browserCanvas.addEventListener('dragenter', onDragEnter, false) - browserCanvas.addEventListener('dragleave', onDragLeave, false) - browserCanvas.addEventListener('dragover', onDragOver, false) - browserCanvas.addEventListener('drop', onDragDrop, false) + browserCanvas.removeEventListener('dragenter', onDragEnter, false) + browserCanvas.removeEventListener('dragleave', onDragLeave, false) + browserCanvas.removeEventListener('dragover', onDragOver, false) + browserCanvas.removeEventListener('drop', onDragDrop, false) - // Disables the context menu when you right mouse click the canvas. - browserCanvas.oncontextmenu = function (e) { - e.preventDefault() - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] addCanvasEvents -> err = ' + err.stack) } - } - } + browserCanvas.removeEventListener('keydown', onKeyDown, false) + browserCanvas.removeEventListener('keyup', onKeyUp, false) - function browserResized () { - browserCanvas = document.getElementById('canvas') + thisObject.splashScreen = undefined + lastContainerMouseOver = undefined - browserCanvas.width = window.innerWidth - browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN - } - - function checkMediaRecording (event) { - if ((event.ctrlKey === true || event.metaKey === true)) { - let constructorParams - switch (event.keyCode) { - case 118: { // F7 - downloadPanorama('Superalgos.Market.Panorama') - return - break + hisObject.mouse = undefined + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) } } - case 119: { // F8 - downloadCanvas('Superalgos.Image.Capture', browserCanvas) - return - break + } + + function initialize() { + try { + browserResized() + initializeBrowserCanvas() + addCanvasEvents() + + /* Instantiate all the children spaces of Canvas object */ + thisObject.floatingSpace = newFloatingSpace() + thisObject.floatingSpace.initialize() + + thisObject.topSpace = newTopSpace() + thisObject.topSpace.initialize() + + thisObject.cockpitSpace = newCockpitSpace() + thisObject.cockpitSpace.initialize() + + thisObject.designSpace = newDesignSpace() + thisObject.designSpace.initialize() + + thisObject.panelsSpace = newPanelsSpace() + thisObject.panelsSpace.initialize() + + thisObject.chartingSpace = newChartingSpace() + thisObject.chartingSpace.initialize() + + thisObject.sideSpace = newSideSpace() + thisObject.sideSpace.initialize() + + thisObject.splashScreen = newSplashScreen() + + let animation = newAnimation() + animation.initialize() + + thisObject.animation = animation + + /* Spcaces Physics */ + animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics) + animation.addCallBackFunction('Floating Space Physics', thisObject.floatingSpace.physics) + animation.addCallBackFunction('Charting Space Physics', thisObject.chartingSpace.physics) + animation.addCallBackFunction('Design Space Physics', thisObject.designSpace.physics) + animation.addCallBackFunction('Panels Space Physics', thisObject.panelsSpace.physics) + animation.addCallBackFunction('Side Space Physics', thisObject.sideSpace.physics) + + /* Spcaces Drawing */ + animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw) + animation.addCallBackFunction('Charting Space Draw', thisObject.chartingSpace.draw) + animation.addCallBackFunction('Panels Space', thisObject.panelsSpace.draw) + animation.addCallBackFunction('CockpitSpace Draw', thisObject.cockpitSpace.draw) + animation.addCallBackFunction('Design Space Draw', thisObject.designSpace.draw) + animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw) + animation.addCallBackFunction('Side Space Draw', thisObject.sideSpace.draw) + animation.addCallBackFunction('Splash Screen Draw', thisObject.splashScreen.draw) + animation.start() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } } - case 120: { // F9 - constructorParams = { format: 'gif', workersPath: 'externalScripts/', framerate: 8, name: 'Superalgos.Video.Capture'} - break + } + + function initializeBrowserCanvas() { + try { + browserCanvasContext = browserCanvas.getContext('2d') + browserCanvasContext.font = 'Saira Condensed' + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initializeBrowserCanvas -> err = ' + err.stack) } } - case 121: { // F10 - constructorParams = { format: 'webm', framerate: 8, name: 'Superalgos.Video.Capture' } - break + } + + function addCanvasEvents() { + try { + canvas.eventHandler.listenToEvent('Browser Resized', browserResized) + + /* Keyboard events */ + window.addEventListener('keydown', onKeyDown, true) + window.addEventListener('keyup', onKeyUp, true) + + /* Mouse Events */ + browserCanvas.addEventListener('mousedown', onMouseDown, false) + browserCanvas.addEventListener('mouseup', onMouseUp, false) + browserCanvas.addEventListener('mousemove', onMouseMove, false) + browserCanvas.addEventListener('click', onMouseClick, false) + browserCanvas.addEventListener('mouseout', onMouseOut, false) + + if (browserCanvas.addEventListener) { + browserCanvas.addEventListener('mousewheel', onMouseWheel, false) // IE9, Chrome, Safari, Opera + browserCanvas.addEventListener('DOMMouseScroll', onMouseWheel, false) // Firefox + } else browserCanvas.attachEvent('onmousewheel', onMouseWheel)// IE 6/7/8 + + /* Dragging Files Over the Canvas */ + browserCanvas.addEventListener('dragenter', onDragEnter, false) + browserCanvas.addEventListener('dragleave', onDragLeave, false) + browserCanvas.addEventListener('dragover', onDragOver, false) + browserCanvas.addEventListener('drop', onDragDrop, false) + + // Disables the context menu when you right mouse click the canvas. + browserCanvas.oncontextmenu = function (e) { + e.preventDefault() + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] addCanvasEvents -> err = ' + err.stack) } } - default: return - } - - if (ARE_WE_RECORDING_A_VIDEO === false) { - console.log('RECORDING', constructorParams.format) - mediaRecorder = new CCapture(constructorParams) - mediaRecorder.start() - ARE_WE_RECORDING_A_VIDEO = true - } else { - console.log('SAVING', constructorParams.format) - ARE_WE_RECORDING_A_VIDEO = false - mediaRecorder.stop() - mediaRecorder.save() - } - } - } - - function onKeyUp (event) { - thisObject.mouse.event = event - thisObject.mouse.action = 'key up' - } - - function onKeyDown (event) { - if (EDITOR_ON_FOCUS === true) { return } - thisObject.mouse.event = event - thisObject.mouse.action = 'key down' - - checkMediaRecording(event) - canvas.chartingSpace.onKeyPressed(event) - - /* Shourcuts to Menu Items */ - if ((event.keyCode >= 48 && event.keyCode <= 57)) { - let number = event.key - if (MENU_ITEM_ON_FOCUS !== undefined) { - let menuItem = thisObject.shorcutNumbers.get(number) - if (menuItem !== undefined) { - menuItem.shorcutNumber = undefined - } - thisObject.shorcutNumbers.set(number, MENU_ITEM_ON_FOCUS) - MENU_ITEM_ON_FOCUS.shorcutNumber = number - } else { - let menuItem = thisObject.shorcutNumbers.get(number) - if (menuItem !== undefined) { - menuItem.internalClick() - } - } } - if (event.key === 'Escape' && canvas.floatingSpace.inMapMode === true) { - canvas.floatingSpace.exitMapMode() + function browserResized() { + browserCanvas = document.getElementById('canvas') + + browserCanvas.width = window.innerWidth + browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN } - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'M' || event.key === 'm')) { - canvas.floatingSpace.toggleMapMode() - event.preventDefault() - return - } + function checkMediaRecording(event) { + if ((event.ctrlKey === true || event.metaKey === true)) { + let constructorParams + switch (event.keyCode) { + case 118: { // F7 + downloadPanorama('Superalgos.Market.Panorama') + return + break + } + case 119: { // F8 + downloadCanvas('Superalgos.Image.Capture', browserCanvas) + return + break + } + case 120: { // F9 + constructorParams = { format: 'gif', workersPath: 'externalScripts/', framerate: 8, name: 'Superalgos.Video.Capture' } + break + } + case 121: { // F10 + constructorParams = { format: 'webm', framerate: 8, name: 'Superalgos.Video.Capture' } + break + } + default: return + } - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'R' || event.key === 'r')) { - canvas.floatingSpace.toggleDrawReferenceLines() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'C' || event.key === 'c')) { - canvas.floatingSpace.toggleDrawChainLines() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'S' || event.key === 's')) { - canvas.designSpace.workspace.save() - event.preventDefault() - return - } - - let nodeOnFocus = canvas.designSpace.workspace.getNodeThatIsOnFocus() - if (nodeOnFocus !== undefined) { - if (nodeOnFocus.payload.uiObject.codeEditor !== undefined) { - if (nodeOnFocus.payload.uiObject.codeEditor.visible === true) { - return - } - } - if (nodeOnFocus.payload.uiObject.configEditor !== undefined) { - if (nodeOnFocus.payload.uiObject.configEditor.visible === true) { - return - } - } - if (nodeOnFocus.payload.uiObject.formulaEditor !== undefined) { - if (nodeOnFocus.payload.uiObject.formulaEditor.visible === true) { - return - } - } - if (nodeOnFocus.payload.uiObject.conditionEditor !== undefined) { - if (nodeOnFocus.payload.uiObject.conditionEditor.visible === true) { - return - } - } - if (nodeOnFocus.payload.uiObject.uiObjectTitle !== undefined) { - if (nodeOnFocus.payload.uiObject.uiObjectTitle.editMode === true) { - return - } - } - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true && event.shiftKey === true && event.keyCode === 123) { // Dev Tool when used with F12 - if (nodeOnFocus !== undefined) { - console.log(nodeOnFocus) - return - } - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true && event.shiftKey === true && event.keyCode === 122) { // Dev Tool when used with F11 - if (SHOW_ANIMATION_PERFORMACE === false) { - SHOW_ANIMATION_PERFORMACE = true - } else { - SHOW_ANIMATION_PERFORMACE = false - } - return - } - - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowUp') { - thisObject.cockpitSpace.toTop() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowDown') { - thisObject.cockpitSpace.toBottom() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowLeft') { - thisObject.cockpitSpace.moveUp() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowRight') { - thisObject.cockpitSpace.moveDown() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowLeft') { - canvas.chartingSpace.oneScreenLeft() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowRight') { - canvas.chartingSpace.oneScreenRight() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowUp') { - canvas.chartingSpace.oneScreenUp() - event.preventDefault() - return - } - - if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowDown') { - canvas.chartingSpace.oneScreenDown() - event.preventDefault() - return - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowLeft') { - let displaceVector = canvas.floatingSpace.oneScreenLeft() - if (displaceVector !== undefined) { - dragVector.downX = dragVector.downX + displaceVector.x - dragVector.downY = dragVector.downY + displaceVector.y - checkDrag() - } - event.preventDefault() - return - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowRight') { - let displaceVector = canvas.floatingSpace.oneScreenRight() - if (displaceVector !== undefined) { - dragVector.downX = dragVector.downX + displaceVector.x - dragVector.downY = dragVector.downY + displaceVector.y - checkDrag() - } - event.preventDefault() - return - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowUp') { - let displaceVector = canvas.floatingSpace.oneScreenUp() - if (displaceVector !== undefined) { - dragVector.downX = dragVector.downX + displaceVector.x - dragVector.downY = dragVector.downY + displaceVector.y - checkDrag() - } - event.preventDefault() - return - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowDown') { - let displaceVector = canvas.floatingSpace.oneScreenDown() - if (displaceVector !== undefined) { - dragVector.downX = dragVector.downX + displaceVector.x - dragVector.downY = dragVector.downY + displaceVector.y - checkDrag() - } - event.preventDefault() - return - } - - if (event.code === 'Period') { - if (nodeOnFocus !== undefined) { - nodeOnFocus.payload.uiObject.setValue('Id: ' + nodeOnFocus.id) - return - } - } - - if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true) { - /* Shortcuts to nodes */ - if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 65 && event.keyCode <= 90)) { - /* From here we prevent the default behaviour. Putting it earlier prevents imput box and text area to receive keystrokes */ - event.preventDefault() - - let nodeUsingThisKey = canvas.designSpace.workspace.getNodeByShortcutKey(event.key) - - if (nodeOnFocus === undefined && nodeUsingThisKey !== undefined) { - /* Then we displace the whole workspace to center it at the node using this key */ - nodeUsingThisKey = canvas.floatingSpace.positionAtNode(nodeUsingThisKey) - return - } - - /* If there is a node in focus, we try to assign the key to it. */ - if (nodeUsingThisKey !== undefined && nodeOnFocus !== undefined) { - if (nodeUsingThisKey.id === nodeOnFocus.id) { - nodeOnFocus.payload.uiObject.shortcutKey = '' - nodeOnFocus.payload.uiObject.setValue('Shortcut Key Removed ') - return - } else { - if (lastShortcutKeyRejection !== event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) { - /* The first time we show a warning that this key is in use. */ - nodeOnFocus.payload.uiObject.setErrorMessage('Key already in use by ' + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) - lastShortcutKeyRejection = event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name - return + if (ARE_WE_RECORDING_A_VIDEO === false) { + console.log('RECORDING', constructorParams.format) + mediaRecorder = new CCapture(constructorParams) + mediaRecorder.start() + ARE_WE_RECORDING_A_VIDEO = true } else { - /* After the warning, we allow the key to be re-assigned */ - nodeUsingThisKey.payload.uiObject.shortcutKey = '' - nodeUsingThisKey === undefined + console.log('SAVING', constructorParams.format) + ARE_WE_RECORDING_A_VIDEO = false + mediaRecorder.stop() + mediaRecorder.save() } - } } - /* If there is not node using this key and a node in focus, we assign this key to this node */ - if (nodeUsingThisKey === undefined && nodeOnFocus !== undefined) { - nodeOnFocus.payload.uiObject.shortcutKey = event.key - nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + event.key) - } - return - } } - if (event.ctrlKey === true && event.altKey === true && nodeOnFocus !== undefined) { - if (nodeOnFocus.payload.uiObject.shortcutKey !== undefined && nodeOnFocus.payload.uiObject.shortcutKey !== '') { - nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + nodeOnFocus.payload.uiObject.shortcutKey) - } + function onKeyUp(event) { + thisObject.mouse.event = event + thisObject.mouse.action = 'key up' } - } - function onDragEnter (event) { - try { - event.preventDefault() - event.stopPropagation() - thisObject.cockpitSpace.toTop() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onDragEnter -> err = ' + err.stack) } - } - } + function onKeyDown(event) { + if (EDITOR_ON_FOCUS === true) { return } + thisObject.mouse.event = event + thisObject.mouse.action = 'key down' - function onDragLeave (event) { - try { - event.preventDefault() - event.stopPropagation() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onDragLeave -> err = ' + err.stack) } - } - } + checkMediaRecording(event) + canvas.chartingSpace.onKeyPressed(event) - function onDragOver (event) { - try { - event.preventDefault() - event.stopPropagation() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onDragOver -> err = ' + err.stack) } - } - } - - function onDragDrop (event) { - try { - event.preventDefault() - event.stopPropagation() - - let files = event.dataTransfer.files - - handleFiles(files) - function handleFiles (files) { - ([...files]).forEach(loadFileData) - } - - function loadFileData (file) { - let reader = new FileReader() - reader.readAsText(file) - reader.onloadend = function () { - let mousePosition = { - x: event.x, - y: event.y - } - thisObject.designSpace.workspace.spawn(reader.result, mousePosition) - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onDragDrop -> err = ' + err.stack) } - } - } - - function onMouseDown (event) { - try { - thisObject.mouse.event = event - thisObject.mouse.position.x = event.pageX - thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN - switch (event.buttons) { - case 1: { - thisObject.mouse.action = 'clicking with left button' - break - } - case 2: { - thisObject.mouse.action = 'clicking with right button' - break - } - } - - let point = event - point.x = event.pageX - point.y = event.pageY - CURRENT_TOP_MARGIN - - dragVector.downX = point.x - dragVector.downY = point.y - - let container - - /* We check if the mouse is over an element of the Side Space / */ - container = thisObject.sideSpace.getContainer(point) - - if (container !== undefined && container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - return - } - - if (container !== undefined && container.isDraggeable === false) { - return - } - - /* We check if the mouse is over an element of the Design Space / */ - container = thisObject.designSpace.getContainer(point) - - if (container !== undefined && container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - return - } - - if (container !== undefined && container.isDraggeable === false) { - return - } - - /* We check if the mouse is over an element of the Top Space / */ - container = thisObject.topSpace.getContainer(point) - - if (container !== undefined && container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - return - } - - /* We check if the mouse is over an element of the CockpitSpace / */ - container = thisObject.cockpitSpace.getContainer(point) - - if (container !== undefined && container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - return - } - - if (container !== undefined && container.isClickeable === true) { - /* We dont want to mess up with the click */ - return - } - - /* We check if the mouse is over a panel/ */ - container = thisObject.panelsSpace.getContainer(point, GET_CONTAINER_PURPOSE.DRAGGING) - - if (container !== undefined && event.shiftKey === false) { - if (container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - return - } else { - return - } - } - - if (container !== undefined && container.isClickeable === true) { - /* We dont want to mess up with the click */ - return - } - - /* we check if it is over any of the existing containers at the Charting Space. */ - container = thisObject.chartingSpace.getContainer(point, GET_CONTAINER_PURPOSE.DRAGGING) - - if (container !== undefined) { - if (container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - return - } else { - if (container.isClickeable === false) { - if (event.buttons === 2) { - viewPortBeingDragged = true + /* Shourcuts to Menu Items */ + if ((event.keyCode >= 48 && event.keyCode <= 57)) { + let number = event.key + if (MENU_ITEM_ON_FOCUS !== undefined) { + let menuItem = thisObject.shorcutNumbers.get(number) + if (menuItem !== undefined) { + menuItem.shorcutNumber = undefined + } + thisObject.shorcutNumbers.set(number, MENU_ITEM_ON_FOCUS) + MENU_ITEM_ON_FOCUS.shorcutNumber = number + } else { + let menuItem = thisObject.shorcutNumbers.get(number) + if (menuItem !== undefined) { + menuItem.internalClick() + } } - } - return } - } - container = thisObject.floatingSpace.getContainer(point) - - if (container !== undefined && container.isDraggeable === true) { - containerBeingDragged = container - containerDragStarted = true - floatingObjectDragStarted = true - containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) - - if (event.candelDragging === true) { - containerBeingDragged = undefined - containerDragStarted = false - floatingObjectDragStarted = false + if (event.key === 'Escape' && canvas.floatingSpace.inMapMode === true) { + canvas.floatingSpace.exitMapMode() } - return - } - if (container !== undefined && container.isClickeable === true) { - /* We dont want to mess up with the click */ - return - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onMouseDown -> err = ' + err.stack) } - } - } + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'M' || event.key === 'm')) { + canvas.floatingSpace.toggleMapMode() + event.preventDefault() + return + } - function onMouseClick (event) { - try { - if (ignoreNextClick === true) { - ignoreNextClick = false - return - } + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'R' || event.key === 'r')) { + canvas.floatingSpace.toggleDrawReferenceLines() + event.preventDefault() + return + } - let point = event - point.x = event.pageX - point.y = event.pageY - CURRENT_TOP_MARGIN + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'C' || event.key === 'c')) { + canvas.floatingSpace.toggleDrawChainLines() + event.preventDefault() + return + } - let container + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'S' || event.key === 's')) { + canvas.designSpace.workspace.save() + event.preventDefault() + return + } - /* We check if the mouse is over an element of the Side Space / */ - container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - - /* We check if the mouse is over an element of the Design Space / */ - container = thisObject.designSpace.getContainer(point) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - - /* We check if the mouse is over an element of the Top Space / */ - container = thisObject.topSpace.getContainer(point) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - - /* We check if the mouse is over an element of the CockpitSpace / */ - container = thisObject.cockpitSpace.getContainer(point) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - - /* We check if the mouse is over a panel/ */ - container = thisObject.panelsSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - - /* If it is not, then we check if it is over any of the existing containers at the Charting Space. */ - container = thisObject.chartingSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - - /* We check if the mouse is over a floatingObject/ */ - container = thisObject.floatingSpace.getContainer(point) - - if (container !== undefined && container.isClickeable === true) { - container.eventHandler.raiseEvent('onMouseClick', point) - return - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onMouseClick -> err = ' + err.stack) } - } - } - - function onMouseOut (event) { - deactivateDragging(event) - - /* When the mouse leaves the canvas, our elements needs to react to the fact that the mouse is over a far away place */ - let thisEvent = { - pageX: VERY_LARGE_NUMBER, - pageY: VERY_LARGE_NUMBER - } - onMouseOver(thisEvent) - } - - function onMouseUp (event) { - deactivateDragging(event) - } - - function onMouseMove (event) { - try { - thisObject.mouse.event = event - thisObject.mouse.position.x = event.pageX - thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN - thisObject.mouse.action = 'moving' - - /* Processing the event */ - let point = event - point.x = event.pageX - point.y = event.pageY - CURRENT_TOP_MARGIN - - if (canvas.chartingSpace.viewport !== undefined) { - canvas.chartingSpace.viewport.mousePosition.x = point.x - canvas.chartingSpace.viewport.mousePosition.y = point.y - } - - if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) { - if (floatingObjectDragStarted === true) { - let targetContainer = thisObject.floatingSpace.getContainer(point) - if (targetContainer !== undefined) { - if (targetContainer.id !== containerBeingDragged.id) { - containerBeingDragged.eventHandler.raiseEvent('onDragFinished', point) - containerBeingDragged = undefined - containerDragStarted = false - floatingObjectDragStarted = false - browserCanvas.style.cursor = 'auto' - ignoreNextClick = true - return + let nodeOnFocus = canvas.designSpace.workspace.getNodeThatIsOnFocus() + if (nodeOnFocus !== undefined) { + if (nodeOnFocus.payload.uiObject.codeEditor !== undefined) { + if (nodeOnFocus.payload.uiObject.codeEditor.visible === true) { + return + } } - } else { - containerBeingDragged.eventHandler.raiseEvent('onDragFinished', point) + if (nodeOnFocus.payload.uiObject.configEditor !== undefined) { + if (nodeOnFocus.payload.uiObject.configEditor.visible === true) { + return + } + } + if (nodeOnFocus.payload.uiObject.formulaEditor !== undefined) { + if (nodeOnFocus.payload.uiObject.formulaEditor.visible === true) { + return + } + } + if (nodeOnFocus.payload.uiObject.conditionEditor !== undefined) { + if (nodeOnFocus.payload.uiObject.conditionEditor.visible === true) { + return + } + } + if (nodeOnFocus.payload.uiObject.uiObjectTitle !== undefined) { + if (nodeOnFocus.payload.uiObject.uiObjectTitle.editMode === true) { + return + } + } + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true && event.shiftKey === true && event.keyCode === 123) { // Dev Tool when used with F12 + if (nodeOnFocus !== undefined) { + console.log(nodeOnFocus) + return + } + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true && event.shiftKey === true && event.keyCode === 122) { // Dev Tool when used with F11 + if (SHOW_ANIMATION_PERFORMACE === false) { + SHOW_ANIMATION_PERFORMACE = true + } else { + SHOW_ANIMATION_PERFORMACE = false + } + return + } + + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowUp') { + thisObject.cockpitSpace.toTop() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowDown') { + thisObject.cockpitSpace.toBottom() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowLeft') { + thisObject.cockpitSpace.moveUp() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowRight') { + thisObject.cockpitSpace.moveDown() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowLeft') { + canvas.chartingSpace.oneScreenLeft() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowRight') { + canvas.chartingSpace.oneScreenRight() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowUp') { + canvas.chartingSpace.oneScreenUp() + event.preventDefault() + return + } + + if (event.shiftKey === true && (event.ctrlKey === false && event.metaKey === false) && event.code === 'ArrowDown') { + canvas.chartingSpace.oneScreenDown() + event.preventDefault() + return + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowLeft') { + let displaceVector = canvas.floatingSpace.oneScreenLeft() + if (displaceVector !== undefined) { + dragVector.downX = dragVector.downX + displaceVector.x + dragVector.downY = dragVector.downY + displaceVector.y + checkDrag() + } + event.preventDefault() + return + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowRight') { + let displaceVector = canvas.floatingSpace.oneScreenRight() + if (displaceVector !== undefined) { + dragVector.downX = dragVector.downX + displaceVector.x + dragVector.downY = dragVector.downY + displaceVector.y + checkDrag() + } + event.preventDefault() + return + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowUp') { + let displaceVector = canvas.floatingSpace.oneScreenUp() + if (displaceVector !== undefined) { + dragVector.downX = dragVector.downX + displaceVector.x + dragVector.downY = dragVector.downY + displaceVector.y + checkDrag() + } + event.preventDefault() + return + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowDown') { + let displaceVector = canvas.floatingSpace.oneScreenDown() + if (displaceVector !== undefined) { + dragVector.downX = dragVector.downX + displaceVector.x + dragVector.downY = dragVector.downY + displaceVector.y + checkDrag() + } + event.preventDefault() + return + } + + if (event.code === 'Period') { + if (nodeOnFocus !== undefined) { + nodeOnFocus.payload.uiObject.setValue('Id: ' + nodeOnFocus.id) + return + } + } + + if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true) { + /* Shortcuts to nodes */ + if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 65 && event.keyCode <= 90)) { + /* From here we prevent the default behaviour. Putting it earlier prevents imput box and text area to receive keystrokes */ + event.preventDefault() + + let nodeUsingThisKey = canvas.designSpace.workspace.getNodeByShortcutKey(event.key) + + if (nodeOnFocus === undefined && nodeUsingThisKey !== undefined) { + /* Then we displace the whole workspace to center it at the node using this key */ + nodeUsingThisKey = canvas.floatingSpace.positionAtNode(nodeUsingThisKey) + return + } + + /* If there is a node in focus, we try to assign the key to it. */ + if (nodeUsingThisKey !== undefined && nodeOnFocus !== undefined) { + if (nodeUsingThisKey.id === nodeOnFocus.id) { + nodeOnFocus.payload.uiObject.shortcutKey = '' + nodeOnFocus.payload.uiObject.setValue('Shortcut Key Removed ') + return + } else { + if (lastShortcutKeyRejection !== event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) { + /* The first time we show a warning that this key is in use. */ + nodeOnFocus.payload.uiObject.setErrorMessage('Key already in use by ' + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) + lastShortcutKeyRejection = event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name + return + } else { + /* After the warning, we allow the key to be re-assigned */ + nodeUsingThisKey.payload.uiObject.shortcutKey = '' + nodeUsingThisKey === undefined + } + } + } + /* If there is not node using this key and a node in focus, we assign this key to this node */ + if (nodeUsingThisKey === undefined && nodeOnFocus !== undefined) { + nodeOnFocus.payload.uiObject.shortcutKey = event.key + nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + event.key) + } + return + } + } + + if (event.ctrlKey === true && event.altKey === true && nodeOnFocus !== undefined) { + if (nodeOnFocus.payload.uiObject.shortcutKey !== undefined && nodeOnFocus.payload.uiObject.shortcutKey !== '') { + nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + nodeOnFocus.payload.uiObject.shortcutKey) + } + } + } + + function onDragEnter(event) { + try { + event.preventDefault() + event.stopPropagation() + thisObject.cockpitSpace.toTop() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onDragEnter -> err = ' + err.stack) } + } + } + + function onDragLeave(event) { + try { + event.preventDefault() + event.stopPropagation() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onDragLeave -> err = ' + err.stack) } + } + } + + function onDragOver(event) { + try { + event.preventDefault() + event.stopPropagation() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onDragOver -> err = ' + err.stack) } + } + } + + function onDragDrop(event) { + try { + event.preventDefault() + event.stopPropagation() + + let files = event.dataTransfer.files + + handleFiles(files) + function handleFiles(files) { + ([...files]).forEach(loadFileData) + } + + function loadFileData(file) { + let reader = new FileReader() + reader.readAsText(file) + reader.onloadend = function () { + let mousePosition = { + x: event.x, + y: event.y + } + thisObject.designSpace.workspace.spawn(reader.result, mousePosition) + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onDragDrop -> err = ' + err.stack) } + } + } + + function onMouseDown(event) { + try { + thisObject.mouse.event = event + thisObject.mouse.position.x = event.pageX + thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN + switch (event.buttons) { + case 1: { + thisObject.mouse.action = 'clicking with left button' + break + } + case 2: { + thisObject.mouse.action = 'clicking with right button' + break + } + } + + let point = event + point.x = event.pageX + point.y = event.pageY - CURRENT_TOP_MARGIN + + dragVector.downX = point.x + dragVector.downY = point.y + + let container + + /* We check if the mouse is over an element of the Side Space / */ + container = thisObject.sideSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + if (container !== undefined && container.isDraggeable === false) { + return + } + + /* We check if the mouse is over an element of the Design Space / */ + container = thisObject.designSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + if (container !== undefined && container.isDraggeable === false) { + return + } + + /* We check if the mouse is over an element of the Top Space / */ + container = thisObject.topSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + /* We check if the mouse is over an element of the CockpitSpace / */ + container = thisObject.cockpitSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + if (container !== undefined && container.isClickeable === true) { + /* We dont want to mess up with the click */ + return + } + + /* We check if the mouse is over a panel/ */ + container = thisObject.panelsSpace.getContainer(point, GET_CONTAINER_PURPOSE.DRAGGING) + + if (container !== undefined && event.shiftKey === false) { + if (container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } else { + return + } + } + + if (container !== undefined && container.isClickeable === true) { + /* We dont want to mess up with the click */ + return + } + + /* we check if it is over any of the existing containers at the Charting Space. */ + container = thisObject.chartingSpace.getContainer(point, GET_CONTAINER_PURPOSE.DRAGGING) + + if (container !== undefined) { + if (container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } else { + if (container.isClickeable === false) { + if (event.buttons === 2) { + viewPortBeingDragged = true + } + } + return + } + } + + container = thisObject.floatingSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + floatingObjectDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + + if (event.candelDragging === true) { + containerBeingDragged = undefined + containerDragStarted = false + floatingObjectDragStarted = false + } + return + } + + if (container !== undefined && container.isClickeable === true) { + /* We dont want to mess up with the click */ + return + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onMouseDown -> err = ' + err.stack) } + } + } + + function onMouseClick(event) { + try { + if (ignoreNextClick === true) { + ignoreNextClick = false + return + } + + let point = event + point.x = event.pageX + point.y = event.pageY - CURRENT_TOP_MARGIN + + let container + + /* We check if the mouse is over an element of the Side Space / */ + container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + + /* We check if the mouse is over an element of the Design Space / */ + container = thisObject.designSpace.getContainer(point) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + + /* We check if the mouse is over an element of the Top Space / */ + container = thisObject.topSpace.getContainer(point) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + + /* We check if the mouse is over an element of the CockpitSpace / */ + container = thisObject.cockpitSpace.getContainer(point) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + + /* We check if the mouse is over a panel/ */ + container = thisObject.panelsSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + + /* If it is not, then we check if it is over any of the existing containers at the Charting Space. */ + container = thisObject.chartingSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + + /* We check if the mouse is over a floatingObject/ */ + container = thisObject.floatingSpace.getContainer(point) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onMouseClick -> err = ' + err.stack) } + } + } + + function onMouseOut(event) { + deactivateDragging(event) + + /* When the mouse leaves the canvas, our elements needs to react to the fact that the mouse is over a far away place */ + let thisEvent = { + pageX: VERY_LARGE_NUMBER, + pageY: VERY_LARGE_NUMBER + } + onMouseOver(thisEvent) + } + + function onMouseUp(event) { + deactivateDragging(event) + } + + function onMouseMove(event) { + try { + thisObject.mouse.event = event + thisObject.mouse.position.x = event.pageX + thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN + thisObject.mouse.action = 'moving' + + /* Processing the event */ + let point = event + point.x = event.pageX + point.y = event.pageY - CURRENT_TOP_MARGIN + + if (canvas.chartingSpace.viewport !== undefined) { + canvas.chartingSpace.viewport.mousePosition.x = point.x + canvas.chartingSpace.viewport.mousePosition.y = point.y + } + + if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) { + if (floatingObjectDragStarted === true) { + let targetContainer = thisObject.floatingSpace.getContainer(point) + if (targetContainer !== undefined) { + if (targetContainer.id !== containerBeingDragged.id) { + containerBeingDragged.eventHandler.raiseEvent('onDragFinished', point) + containerBeingDragged = undefined + containerDragStarted = false + floatingObjectDragStarted = false + browserCanvas.style.cursor = 'auto' + ignoreNextClick = true + return + } + } else { + containerBeingDragged.eventHandler.raiseEvent('onDragFinished', point) + containerDragStarted = false + containerBeingDragged = undefined + floatingObjectDragStarted = false + browserCanvas.style.cursor = 'auto' + ignoreNextClick = true + return + } + } + + dragVector.upX = point.x + dragVector.upY = point.y + + checkDrag(event) + } + onMouseOver(event) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onMouseMove -> err = ' + err.stack) } + } + } + + function onMouseOver(event) { + try { + let point = event + point.x = event.pageX + point.y = event.pageY - CURRENT_TOP_MARGIN + + if (containerDragStarted === true) { + containerBeingDragged.eventHandler.raiseEvent('onMouseOver', point) + return + } + + /* Then we check who is the current object underneeth the mounse. */ + + let container + + /* We check if the mouse is over an element of the Designe Space / */ + if (thisObject.sideSpace !== undefined) { + container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* We check if the mouse is over an element of the Designe Space / */ + if (thisObject.designSpace !== undefined) { + container = thisObject.designSpace.getContainer(point) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* We check if the mouse is over an element of the Top Space / */ + if (thisObject.topSpace !== undefined) { + container = thisObject.topSpace.getContainer(point) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* We check if the mouse is over an element of the CockpitSpace / */ + if (thisObject.cockpitSpace !== undefined) { + container = thisObject.cockpitSpace.getContainer(point) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* We check if the mouse is over a panel/ */ + if (thisObject.panelsSpace !== undefined) { + container = thisObject.panelsSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* If it is not, then we check if it is over any of the existing containers at the Charting Space. */ + if (thisObject.chartingSpace !== undefined) { + container = thisObject.chartingSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* We check if the mouse is over a floatingObject/ */ + if (thisObject.floatingSpace !== undefined) { + container = thisObject.floatingSpace.getContainer(point) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + function containerFound() { + if (lastContainerMouseOver !== undefined) { + if (container.id !== lastContainerMouseOver.id) { + lastContainerMouseOver.eventHandler.raiseEvent('onMouseNotOver', point) + } + } + container.eventHandler.raiseEvent('onMouseOver', point) + lastContainerMouseOver = container + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onMouseOver -> err = ' + err.stack) } + } + } + + function onMouseWheel(event) { + try { + thisObject.mouse.event = event + thisObject.mouse.position.x = event.pageX + thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN + thisObject.mouse.action = 'wheel' + + // cross-browser wheel delta + var event = window.event || event // old IE support + event.delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail)) + if (IS_MAC) { + event.delta = event.delta / MAC_AMOUNT_FACTOR + } + + /* We try first with panels. */ + + let point = { + x: event.pageX, + y: event.pageY - CURRENT_TOP_MARGIN + } + + event.mousePosition = point + let container + + /* Side Space */ + container = canvas.sideSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + + /* Panel Space */ + container = canvas.panelsSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + + /* We try the CockpitSpace. */ + container = canvas.cockpitSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + + /* Charting Space. */ + container = canvas.chartingSpace.getContainer({ x: point.x, y: point.y }, GET_CONTAINER_PURPOSE.MOUSE_WHEEL) + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + + if (container !== undefined) { + canvas.chartingSpace.viewport.onMouseWheel(event) + return false + } + + /* We try second with floating objects. */ + container = canvas.floatingSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + + return false + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] onMouseWheel -> err = ' + err.stack) } + } + } + + function deactivateDragging(event) { + try { + if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) { + thisObject.eventHandler.raiseEvent('Drag Finished', undefined) + } + + if ( + containerDragStarted || + floatingObjectDragStarted || + viewPortBeingDragged + ) { + ignoreNextClick = false + } + /* Turn off all the possible things that can be dragged. */ + containerDragStarted = false - containerBeingDragged = undefined floatingObjectDragStarted = false - browserCanvas.style.cursor = 'auto' - ignoreNextClick = true - return - } - } + viewPortBeingDragged = false - dragVector.upX = point.x - dragVector.upY = point.y - - checkDrag(event) - } - onMouseOver(event) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onMouseMove -> err = ' + err.stack) } - } - } - - function onMouseOver (event) { - try { - let point = event - point.x = event.pageX - point.y = event.pageY - CURRENT_TOP_MARGIN - - if (containerDragStarted === true) { - containerBeingDragged.eventHandler.raiseEvent('onMouseOver', point) - return - } - - /* Then we check who is the current object underneeth the mounse. */ - - let container - - /* We check if the mouse is over an element of the Designe Space / */ - if (thisObject.sideSpace !== undefined) { - container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - /* We check if the mouse is over an element of the Designe Space / */ - if (thisObject.designSpace !== undefined) { - container = thisObject.designSpace.getContainer(point) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - /* We check if the mouse is over an element of the Top Space / */ - if (thisObject.topSpace !== undefined) { - container = thisObject.topSpace.getContainer(point) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - /* We check if the mouse is over an element of the CockpitSpace / */ - if (thisObject.cockpitSpace !== undefined) { - container = thisObject.cockpitSpace.getContainer(point) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - /* We check if the mouse is over a panel/ */ - if (thisObject.panelsSpace !== undefined) { - container = thisObject.panelsSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - /* If it is not, then we check if it is over any of the existing containers at the Charting Space. */ - if (thisObject.chartingSpace !== undefined) { - container = thisObject.chartingSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - /* We check if the mouse is over a floatingObject/ */ - if (thisObject.floatingSpace !== undefined) { - container = thisObject.floatingSpace.getContainer(point) - - if (container !== undefined && container.detectMouseOver === true) { - containerFound() - return - } - } - - function containerFound () { - if (lastContainerMouseOver !== undefined) { - if (container.id !== lastContainerMouseOver.id) { - lastContainerMouseOver.eventHandler.raiseEvent('onMouseNotOver', point) - } - } - container.eventHandler.raiseEvent('onMouseOver', point) - lastContainerMouseOver = container - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onMouseOver -> err = ' + err.stack) } - } - } - - function onMouseWheel (event) { - try { - thisObject.mouse.event = event - thisObject.mouse.position.x = event.pageX - thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN - thisObject.mouse.action = 'wheel' - - // cross-browser wheel delta - var event = window.event || event // old IE support - event.delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail)) - if (IS_MAC) { - event.delta = event.delta / MAC_AMOUNT_FACTOR - } - - /* We try first with panels. */ - - let point = { - x: event.pageX, - y: event.pageY - CURRENT_TOP_MARGIN - } - - event.mousePosition = point - let container - - /* Side Space */ - container = canvas.sideSpace.getContainer({ x: point.x, y: point.y }) - - if (container !== undefined && container.isWheelable === true) { - container.eventHandler.raiseEvent('onMouseWheel', event) - return false // This instructs the browser not to take the event and scroll the page. - } - - /* Panel Space */ - container = canvas.panelsSpace.getContainer({ x: point.x, y: point.y }) - - if (container !== undefined && container.isWheelable === true) { - container.eventHandler.raiseEvent('onMouseWheel', event) - return false // This instructs the browser not to take the event and scroll the page. - } - - /* We try the CockpitSpace. */ - container = canvas.cockpitSpace.getContainer({ x: point.x, y: point.y }) - - if (container !== undefined && container.isWheelable === true) { - container.eventHandler.raiseEvent('onMouseWheel', event) - return false // This instructs the browser not to take the event and scroll the page. - } - - /* Charting Space. */ - container = canvas.chartingSpace.getContainer({ x: point.x, y: point.y }, GET_CONTAINER_PURPOSE.MOUSE_WHEEL) - if (container !== undefined && container.isWheelable === true) { - container.eventHandler.raiseEvent('onMouseWheel', event) - return false // This instructs the browser not to take the event and scroll the page. - } - - if (container !== undefined) { - canvas.chartingSpace.viewport.onMouseWheel(event) - return false - } - - /* We try second with floating objects. */ - container = canvas.floatingSpace.getContainer({ x: point.x, y: point.y }) - - if (container !== undefined && container.isWheelable === true) { - container.eventHandler.raiseEvent('onMouseWheel', event) - return false // This instructs the browser not to take the event and scroll the page. - } - - return false - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] onMouseWheel -> err = ' + err.stack) } - } - } - - function deactivateDragging (event) { - try { - if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) { - thisObject.eventHandler.raiseEvent('Drag Finished', undefined) - } - - if ( - containerDragStarted || - floatingObjectDragStarted || - viewPortBeingDragged - ) { - ignoreNextClick = false - } - /* Turn off all the possible things that can be dragged. */ - - containerDragStarted = false - floatingObjectDragStarted = false - viewPortBeingDragged = false - - if (containerBeingDragged !== undefined) { - containerBeingDragged.eventHandler.raiseEvent('onDragFinished', event) - containerBeingDragged = undefined - } - - browserCanvas.style.cursor = 'auto' - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] deactivateDragging -> err = ' + err.stack) } - } - } - - function checkDrag (event) { - try { - if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) { - if (event !== undefined) { - thisObject.mouse.event = event - thisObject.mouse.position.x = event.pageX - thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN - thisObject.mouse.action = 'dragging' - } - - browserCanvas.style.cursor = 'grabbing' - thisObject.eventHandler.raiseEvent('Dragging', undefined) - - if (viewPortBeingDragged) { - let displaceVector = { - x: dragVector.upX - dragVector.downX, - y: dragVector.upY - dragVector.downY - } - - canvas.chartingSpace.viewport.displace(displaceVector) - } - if (containerDragStarted) { - if (containerBeingDragged !== undefined) { - if (containerBeingDragged.space === 'Charting Space') { - let downCopy = { - x: dragVector.downX, - y: dragVector.downY - } - - let downNoZoom - downNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(downCopy) - - let upCopy = { - x: dragVector.upX, - y: dragVector.upY - } - - let upNoZoom - upNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(upCopy) - - displaceVector = { - x: upNoZoom.x - downNoZoom.x, - y: upNoZoom.y - downNoZoom.y - } - - let moveSucceed = containerBeingDragged.displace(displaceVector) - if (moveSucceed === false) { - deactivateDragging(event) - } - } else { - let displaceVector = { - x: dragVector.upX - dragVector.downX, - y: dragVector.upY - dragVector.downY - } - let moveSucceed = containerBeingDragged.displace(displaceVector) - if (moveSucceed === false) { - deactivateDragging(event) - } + if (containerBeingDragged !== undefined) { + containerBeingDragged.eventHandler.raiseEvent('onDragFinished', event) + containerBeingDragged = undefined } - } - } - /* Finally we set the starting point of the new dragVector at this current point. */ - dragVector.downX = dragVector.upX - dragVector.downY = dragVector.upY - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] checkDrag -> err = ' + err.stack) } + browserCanvas.style.cursor = 'auto' + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] deactivateDragging -> err = ' + err.stack) } + } + } + + function checkDrag(event) { + try { + if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) { + if (event !== undefined) { + thisObject.mouse.event = event + thisObject.mouse.position.x = event.pageX + thisObject.mouse.position.y = event.pageY - CURRENT_TOP_MARGIN + thisObject.mouse.action = 'dragging' + } + + browserCanvas.style.cursor = 'grabbing' + thisObject.eventHandler.raiseEvent('Dragging', undefined) + + if (viewPortBeingDragged) { + let displaceVector = { + x: dragVector.upX - dragVector.downX, + y: dragVector.upY - dragVector.downY + } + + canvas.chartingSpace.viewport.displace(displaceVector) + } + if (containerDragStarted) { + if (containerBeingDragged !== undefined) { + if (containerBeingDragged.space === 'Charting Space') { + let downCopy = { + x: dragVector.downX, + y: dragVector.downY + } + + let downNoZoom + downNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(downCopy) + + let upCopy = { + x: dragVector.upX, + y: dragVector.upY + } + + let upNoZoom + upNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(upCopy) + + displaceVector = { + x: upNoZoom.x - downNoZoom.x, + y: upNoZoom.y - downNoZoom.y + } + + let moveSucceed = containerBeingDragged.displace(displaceVector) + if (moveSucceed === false) { + deactivateDragging(event) + } + } else { + let displaceVector = { + x: dragVector.upX - dragVector.downX, + y: dragVector.upY - dragVector.downY + } + let moveSucceed = containerBeingDragged.displace(displaceVector) + if (moveSucceed === false) { + deactivateDragging(event) + } + } + } + } + + /* Finally we set the starting point of the new dragVector at this current point. */ + dragVector.downX = dragVector.upX + dragVector.downY = dragVector.upY + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] checkDrag -> err = ' + err.stack) } + } } - } } diff --git a/ChartingSpace/ChartUtilities.js b/ChartingSpace/ChartUtilities.js index cdc205ec2..ca778df72 100644 --- a/ChartingSpace/ChartUtilities.js +++ b/ChartingSpace/ChartUtilities.js @@ -1,139 +1,139 @@ -function getSideDays (timeFrame) { - let daysOnSides +function getSideDays(timeFrame) { + let daysOnSides - if (timeFrame < _1_HOUR_IN_MILISECONDS) { - daysOnSides = 1 - } + if (timeFrame < _1_HOUR_IN_MILISECONDS) { + daysOnSides = 1 + } - if (timeFrame === _1_HOUR_IN_MILISECONDS) { - daysOnSides = 9 - } + if (timeFrame === _1_HOUR_IN_MILISECONDS) { + daysOnSides = 9 + } - if (timeFrame === _2_HOURS_IN_MILISECONDS) { - daysOnSides = 10 - } + if (timeFrame === _2_HOURS_IN_MILISECONDS) { + daysOnSides = 10 + } - if (timeFrame === _3_HOURS_IN_MILISECONDS) { - daysOnSides = 12 - } + if (timeFrame === _3_HOURS_IN_MILISECONDS) { + daysOnSides = 12 + } - if (timeFrame === _4_HOURS_IN_MILISECONDS) { - daysOnSides = 20 - } + if (timeFrame === _4_HOURS_IN_MILISECONDS) { + daysOnSides = 20 + } - if (timeFrame === _6_HOURS_IN_MILISECONDS) { - daysOnSides = 35 - } + if (timeFrame === _6_HOURS_IN_MILISECONDS) { + daysOnSides = 35 + } - if (timeFrame === _8_HOURS_IN_MILISECONDS) { - daysOnSides = 44 - } + if (timeFrame === _8_HOURS_IN_MILISECONDS) { + daysOnSides = 44 + } - if (timeFrame === _12_HOURS_IN_MILISECONDS) { - daysOnSides = 56 - } + if (timeFrame === _12_HOURS_IN_MILISECONDS) { + daysOnSides = 56 + } - if (timeFrame === ONE_DAY_IN_MILISECONDS) { - daysOnSides = 154 - } + if (timeFrame === ONE_DAY_IN_MILISECONDS) { + daysOnSides = 154 + } - return daysOnSides + return daysOnSides } -function getCondenseFactor (timeFrame) { - switch (timeFrame) { - case _1_MINUTE_IN_MILISECONDS: return 1 - case _5_MINUTES_IN_MILISECONDS: return 5 - case _10_MINUTES_IN_MILISECONDS: return 10 - case _30_MINUTES_IN_MILISECONDS: return 50 - case _1_HOUR_IN_MILISECONDS: return 100 - } +function getCondenseFactor(timeFrame) { + switch (timeFrame) { + case _1_MINUTE_IN_MILISECONDS: return 1 + case _5_MINUTES_IN_MILISECONDS: return 5 + case _10_MINUTES_IN_MILISECONDS: return 10 + case _30_MINUTES_IN_MILISECONDS: return 50 + case _1_HOUR_IN_MILISECONDS: return 100 + } } -function getTransparenceFactor (timeFrame) { - switch (timeFrame) { - case _1_MINUTE_IN_MILISECONDS: return '0.12' - case _5_MINUTES_IN_MILISECONDS: return '0.10' - case _10_MINUTES_IN_MILISECONDS: return '0.08' - case _30_MINUTES_IN_MILISECONDS: return '0.06' - case _1_HOUR_IN_MILISECONDS: return '0.04' - } +function getTransparenceFactor(timeFrame) { + switch (timeFrame) { + case _1_MINUTE_IN_MILISECONDS: return '0.12' + case _5_MINUTES_IN_MILISECONDS: return '0.10' + case _10_MINUTES_IN_MILISECONDS: return '0.08' + case _30_MINUTES_IN_MILISECONDS: return '0.06' + case _1_HOUR_IN_MILISECONDS: return '0.04' + } } -function recalculatePeriod (zoomLevel) { - // console.log('NEW ZOOM LEVEL', zoomLevel) - if (zoomLevel > 400) { - return _1_MINUTE_IN_MILISECONDS - } +function recalculatePeriod(zoomLevel) { + // console.log('NEW ZOOM LEVEL', zoomLevel) + if (zoomLevel > 400) { + return _1_MINUTE_IN_MILISECONDS + } - if (zoomLevel > 360) { - return _2_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 360) { + return _2_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 330) { - return _3_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 330) { + return _3_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 300) { - return _4_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 300) { + return _4_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 270) { - return _5_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 270) { + return _5_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 250) { - return _10_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 250) { + return _10_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 230) { - return _15_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 230) { + return _15_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 210) { - return _20_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 210) { + return _20_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 190) { - return _30_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 190) { + return _30_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 170) { - return _40_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 170) { + return _40_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 150) { - return _45_MINUTES_IN_MILISECONDS - } + if (zoomLevel > 150) { + return _45_MINUTES_IN_MILISECONDS + } - if (zoomLevel > 130) { - return _1_HOUR_IN_MILISECONDS - } + if (zoomLevel > 130) { + return _1_HOUR_IN_MILISECONDS + } - if (zoomLevel > 110) { - return _2_HOURS_IN_MILISECONDS - } + if (zoomLevel > 110) { + return _2_HOURS_IN_MILISECONDS + } - if (zoomLevel > 80) { - return _3_HOURS_IN_MILISECONDS - } + if (zoomLevel > 80) { + return _3_HOURS_IN_MILISECONDS + } - if (zoomLevel > 50) { - return _4_HOURS_IN_MILISECONDS - } + if (zoomLevel > 50) { + return _4_HOURS_IN_MILISECONDS + } - if (zoomLevel > 35) { - return _6_HOURS_IN_MILISECONDS - } + if (zoomLevel > 35) { + return _6_HOURS_IN_MILISECONDS + } - if (zoomLevel > 20) { - return _8_HOURS_IN_MILISECONDS - } + if (zoomLevel > 20) { + return _8_HOURS_IN_MILISECONDS + } - if (zoomLevel > 10) { - return _12_HOURS_IN_MILISECONDS - } + if (zoomLevel > 10) { + return _12_HOURS_IN_MILISECONDS + } - return ONE_DAY_IN_MILISECONDS + return ONE_DAY_IN_MILISECONDS } diff --git a/ChartingSpace/CoordinateSystem.js b/ChartingSpace/CoordinateSystem.js index 830cef1ac..3a9d3fcf4 100644 --- a/ChartingSpace/CoordinateSystem.js +++ b/ChartingSpace/CoordinateSystem.js @@ -1,4 +1,4 @@ - /* +/* This Object object is responsible for defining the coordinate system in a TimeLine. @@ -7,320 +7,320 @@ The scale on the Y axis depends on the data that wants to be plotted. Usually we */ -function newCoordinateSystem () { - let thisObject = { - min: undefined, - max: undefined, - parentMin: undefined, - parentMax: undefined, - childrenMin: undefined, - childrenMax: undefined, - maxHeight: undefined, - maxWidth: undefined, - scale: undefined, - eventHandler: undefined, - autoMinXScale: true, - autoMaxXScale: true, - autoMinYScale: true, - autoMaxYScale: true, - HORIZONTAL_MARGIN_FACTOR: 0.80, - VERTICAL_MARGIN_FACTOR: 0.90, - HORIZONTAL_MARGIN_INVERSE_FACTOR: 0.20, - VERTICAL_MARGIN_INVERSE_FACTOR: 0.10, - physics: physics, - reportParentXValue: reportParentXValue, - reportParentYValue: reportParentYValue, - reportXValue: reportXValue, - reportYValue: reportYValue, - zoomX: zoomX, - zoomY: zoomY, - recalculateScale: recalculateScale, - transformThisPoint: transformThisPoint, - transformThisPoint2: transformThisPoint2, - unInverseTransform: unInverseTransform, - inverseTransformUncappedY: inverseTransformUncappedY, - initializeX: initializeX, - initializeY: initializeY, - initialize: initialize, - finalize: finalize - } - - thisObject.min = { - x: 0, - y: 0 - } - thisObject.max = { - x: 0, - y: 0 - } - thisObject.parentMin = { - x: 0, - y: 0 - } - thisObject.parentMax = { - x: 0, - y: 0 - } - thisObject.childrenMin = { - x: 0, - y: 0 - } - thisObject.childrenMax = { - x: 0, - y: 0 - } - - thisObject.scale = { - x: 0, - y: 0 - } - - thisObject.eventHandler = newEventHandler() - thisObject.eventHandler.name = 'Coordinate System' - - let newXMax = -VERY_LARGE_NUMBER - let newXMin = VERY_LARGE_NUMBER - - let newYMax = -VERY_LARGE_NUMBER - let newYMin = VERY_LARGE_NUMBER - - let parentMinChanged = false - let parentMaxChanged = false - - return thisObject - - function finalize () { - thisObject.eventHandler.finalize() - thisObject.eventHandler = undefined - } - - function initialize (minValue, maxValue, pMaxWidth, pMaxHeight) { - /* Defines the min and max value of rate that we are going to transport to the available screen at the center position. */ - thisObject.min.x = minValue.x - thisObject.max.x = maxValue.x - - thisObject.min.y = minValue.y - thisObject.max.y = maxValue.y - - thisObject.maxWidth = pMaxWidth - thisObject.maxHeight = pMaxHeight - - recalculateScale() - } - - function reportXValue (value) { - if (thisObject.autoMinXScale === true) { - if (value < newXMin && value !== 0) { - newXMin = value - } - } - if (thisObject.autoMaxXScale === true) { - if (value > newXMax && value !== 0) { - newXMax = value - } - } - } - - function reportYValue (value) { - if (thisObject.autoMinYScale === true) { - if (value < newYMin) { - newYMin = value - } - } - if (thisObject.autoMaxYScale === true) { - if (value > newYMax) { - newYMax = value - } - } - } - - function reportParentXValue (min, max) { - if (thisObject.autoMinXScale === true) { - if (thisObject.parentMin.x !== min) { - thisObject.parentMin.x = min - } - } - if (thisObject.autoMaxXScale === true) { - if (thisObject.parentMax.x !== max) { - thisObject.parentMax.x = max - } - } - } - - function reportParentYValue (min, max) { - if (thisObject.autoMinYScale === true) { - if (thisObject.parentMin.y !== min) { - thisObject.parentMin.y = min - } - } - if (thisObject.autoMaxYScale === true) { - if (thisObject.parentMax.y !== max) { - thisObject.parentMax.y = max - } - } - } - - function physics () { - let mustRecalculate = false - - if ((thisObject.autoMinXScale === true || thisObject.autoMaxXScale === true)) { - if (thisObject.autoMaxXScale === true && thisObject.childrenMax.x !== newXMax && newXMax !== -VERY_LARGE_NUMBER) { - thisObject.childrenMax.x = newXMax - } - - if (thisObject.autoMaxXScale === true) { - newXMax = -VERY_LARGE_NUMBER - } - - if (thisObject.autoMinXScale === true && thisObject.childrenMin.x !== newXMin && newXMin !== VERY_LARGE_NUMBER) { - thisObject.childrenMin.x = newXMin - newXMin = VERY_LARGE_NUMBER - } - - if (thisObject.autoMinXScale === true) { - newXMin = VERY_LARGE_NUMBER - } +function newCoordinateSystem() { + let thisObject = { + min: undefined, + max: undefined, + parentMin: undefined, + parentMax: undefined, + childrenMin: undefined, + childrenMax: undefined, + maxHeight: undefined, + maxWidth: undefined, + scale: undefined, + eventHandler: undefined, + autoMinXScale: true, + autoMaxXScale: true, + autoMinYScale: true, + autoMaxYScale: true, + HORIZONTAL_MARGIN_FACTOR: 0.80, + VERTICAL_MARGIN_FACTOR: 0.90, + HORIZONTAL_MARGIN_INVERSE_FACTOR: 0.20, + VERTICAL_MARGIN_INVERSE_FACTOR: 0.10, + physics: physics, + reportParentXValue: reportParentXValue, + reportParentYValue: reportParentYValue, + reportXValue: reportXValue, + reportYValue: reportYValue, + zoomX: zoomX, + zoomY: zoomY, + recalculateScale: recalculateScale, + transformThisPoint: transformThisPoint, + transformThisPoint2: transformThisPoint2, + unInverseTransform: unInverseTransform, + inverseTransformUncappedY: inverseTransformUncappedY, + initializeX: initializeX, + initializeY: initializeY, + initialize: initialize, + finalize: finalize } - if ((thisObject.autoMinYScale === true || thisObject.autoMaxYScale === true)) { - if (thisObject.autoMaxYScale === true && thisObject.childrenMax.y !== newYMax && newYMax !== -VERY_LARGE_NUMBER) { - thisObject.childrenMax.y = newYMax - } - - if (thisObject.autoMaxYScale === true) { - newYMax = -VERY_LARGE_NUMBER - } - - if (thisObject.autoMinYScale === true && thisObject.childrenMin.y !== newYMin && newYMin !== VERY_LARGE_NUMBER) { - thisObject.childrenMin.y = newYMin - newYMin = VERY_LARGE_NUMBER - } - - if (thisObject.autoMinYScale === true) { - newYMin = VERY_LARGE_NUMBER - } + thisObject.min = { + x: 0, + y: 0 + } + thisObject.max = { + x: 0, + y: 0 + } + thisObject.parentMin = { + x: 0, + y: 0 + } + thisObject.parentMax = { + x: 0, + y: 0 + } + thisObject.childrenMin = { + x: 0, + y: 0 + } + thisObject.childrenMax = { + x: 0, + y: 0 } - /* Here we will see if any of the children or parent values modify the current status quo */ - /* Min */ - let minX = Math.min(thisObject.childrenMin.x, thisObject.parentMin.x) - let minY = Math.min(thisObject.childrenMin.y, thisObject.parentMin.y) - let maxX = Math.max(thisObject.childrenMax.x, thisObject.parentMax.x) - let maxY = Math.max(thisObject.childrenMax.y, thisObject.parentMax.y) - - if (thisObject.parentMin.x === 0) { - minX = thisObject.childrenMin.x + thisObject.scale = { + x: 0, + y: 0 } - if (thisObject.parentMin.y === 0) { - minY = thisObject.childrenMin.y + thisObject.eventHandler = newEventHandler() + thisObject.eventHandler.name = 'Coordinate System' + + let newXMax = -VERY_LARGE_NUMBER + let newXMin = VERY_LARGE_NUMBER + + let newYMax = -VERY_LARGE_NUMBER + let newYMin = VERY_LARGE_NUMBER + + let parentMinChanged = false + let parentMaxChanged = false + + return thisObject + + function finalize() { + thisObject.eventHandler.finalize() + thisObject.eventHandler = undefined } - if (thisObject.parentMax.x === 0) { - maxX = thisObject.childrenMax.x + function initialize(minValue, maxValue, pMaxWidth, pMaxHeight) { + /* Defines the min and max value of rate that we are going to transport to the available screen at the center position. */ + thisObject.min.x = minValue.x + thisObject.max.x = maxValue.x + + thisObject.min.y = minValue.y + thisObject.max.y = maxValue.y + + thisObject.maxWidth = pMaxWidth + thisObject.maxHeight = pMaxHeight + + recalculateScale() } - if (thisObject.parentMax.y === 0) { - maxY = thisObject.childrenMax.y + function reportXValue(value) { + if (thisObject.autoMinXScale === true) { + if (value < newXMin && value !== 0) { + newXMin = value + } + } + if (thisObject.autoMaxXScale === true) { + if (value > newXMax && value !== 0) { + newXMax = value + } + } } - if (minX !== 0 && thisObject.min.x !== minX && thisObject.autoMinXScale === true) { - thisObject.min.x = minX - mustRecalculate = true + function reportYValue(value) { + if (thisObject.autoMinYScale === true) { + if (value < newYMin) { + newYMin = value + } + } + if (thisObject.autoMaxYScale === true) { + if (value > newYMax) { + newYMax = value + } + } } - if (minY !== 0 && thisObject.min.y !== minY && thisObject.autoMinYScale === true) { - thisObject.min.y = minY - mustRecalculate = true + function reportParentXValue(min, max) { + if (thisObject.autoMinXScale === true) { + if (thisObject.parentMin.x !== min) { + thisObject.parentMin.x = min + } + } + if (thisObject.autoMaxXScale === true) { + if (thisObject.parentMax.x !== max) { + thisObject.parentMax.x = max + } + } } - if (maxX !== 0 && thisObject.max.x !== maxX && thisObject.autoMaxXScale === true) { - thisObject.max.x = maxX - mustRecalculate = true + function reportParentYValue(min, max) { + if (thisObject.autoMinYScale === true) { + if (thisObject.parentMin.y !== min) { + thisObject.parentMin.y = min + } + } + if (thisObject.autoMaxYScale === true) { + if (thisObject.parentMax.y !== max) { + thisObject.parentMax.y = max + } + } } - if (maxY !== 0 && thisObject.max.y !== maxY && thisObject.autoMaxYScale === true) { - thisObject.max.y = maxY - mustRecalculate = true + function physics() { + let mustRecalculate = false + + if ((thisObject.autoMinXScale === true || thisObject.autoMaxXScale === true)) { + if (thisObject.autoMaxXScale === true && thisObject.childrenMax.x !== newXMax && newXMax !== -VERY_LARGE_NUMBER) { + thisObject.childrenMax.x = newXMax + } + + if (thisObject.autoMaxXScale === true) { + newXMax = -VERY_LARGE_NUMBER + } + + if (thisObject.autoMinXScale === true && thisObject.childrenMin.x !== newXMin && newXMin !== VERY_LARGE_NUMBER) { + thisObject.childrenMin.x = newXMin + newXMin = VERY_LARGE_NUMBER + } + + if (thisObject.autoMinXScale === true) { + newXMin = VERY_LARGE_NUMBER + } + } + + if ((thisObject.autoMinYScale === true || thisObject.autoMaxYScale === true)) { + if (thisObject.autoMaxYScale === true && thisObject.childrenMax.y !== newYMax && newYMax !== -VERY_LARGE_NUMBER) { + thisObject.childrenMax.y = newYMax + } + + if (thisObject.autoMaxYScale === true) { + newYMax = -VERY_LARGE_NUMBER + } + + if (thisObject.autoMinYScale === true && thisObject.childrenMin.y !== newYMin && newYMin !== VERY_LARGE_NUMBER) { + thisObject.childrenMin.y = newYMin + newYMin = VERY_LARGE_NUMBER + } + + if (thisObject.autoMinYScale === true) { + newYMin = VERY_LARGE_NUMBER + } + } + + /* Here we will see if any of the children or parent values modify the current status quo */ + /* Min */ + let minX = Math.min(thisObject.childrenMin.x, thisObject.parentMin.x) + let minY = Math.min(thisObject.childrenMin.y, thisObject.parentMin.y) + let maxX = Math.max(thisObject.childrenMax.x, thisObject.parentMax.x) + let maxY = Math.max(thisObject.childrenMax.y, thisObject.parentMax.y) + + if (thisObject.parentMin.x === 0) { + minX = thisObject.childrenMin.x + } + + if (thisObject.parentMin.y === 0) { + minY = thisObject.childrenMin.y + } + + if (thisObject.parentMax.x === 0) { + maxX = thisObject.childrenMax.x + } + + if (thisObject.parentMax.y === 0) { + maxY = thisObject.childrenMax.y + } + + if (minX !== 0 && thisObject.min.x !== minX && thisObject.autoMinXScale === true) { + thisObject.min.x = minX + mustRecalculate = true + } + + if (minY !== 0 && thisObject.min.y !== minY && thisObject.autoMinYScale === true) { + thisObject.min.y = minY + mustRecalculate = true + } + + if (maxX !== 0 && thisObject.max.x !== maxX && thisObject.autoMaxXScale === true) { + thisObject.max.x = maxX + mustRecalculate = true + } + + if (maxY !== 0 && thisObject.max.y !== maxY && thisObject.autoMaxYScale === true) { + thisObject.max.y = maxY + mustRecalculate = true + } + + if (mustRecalculate === true) { + recalculateScale() + } } - if (mustRecalculate === true) { - recalculateScale() + function recalculateScale(event) { + thisObject.scale.x = thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_FACTOR / (thisObject.max.x - thisObject.min.x) + thisObject.scale.y = thisObject.maxHeight * thisObject.VERTICAL_MARGIN_FACTOR / (thisObject.max.y - thisObject.min.y) + + thisObject.eventHandler.raiseEvent('Scale Changed', event) } - } - function recalculateScale (event) { - thisObject.scale.x = thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_FACTOR / (thisObject.max.x - thisObject.min.x) - thisObject.scale.y = thisObject.maxHeight * thisObject.VERTICAL_MARGIN_FACTOR / (thisObject.max.y - thisObject.min.y) + function zoomX(factor, mousePosition, container) { + let mouseAtCointainer = unTransformThisPoint(mousePosition, container) + let leftDistance = mouseAtCointainer.x + let rightDistance = container.frame.width - mouseAtCointainer.x + let diff = thisObject.max.x - thisObject.min.x + let min = thisObject.min.x + diff * factor * leftDistance / (container.frame.width / 2) + let max = thisObject.max.x - diff * factor * rightDistance / (container.frame.width / 2) - thisObject.eventHandler.raiseEvent('Scale Changed', event) - } - - function zoomX (factor, mousePosition, container) { - let mouseAtCointainer = unTransformThisPoint(mousePosition, container) - let leftDistance = mouseAtCointainer.x - let rightDistance = container.frame.width - mouseAtCointainer.x - let diff = thisObject.max.x - thisObject.min.x - let min = thisObject.min.x + diff * factor * leftDistance / (container.frame.width / 2) - let max = thisObject.max.x - diff * factor * rightDistance / (container.frame.width / 2) - - if (min < max) { - let mustRecalculate = false - if (thisObject.autoMinXScale === false) { - thisObject.min.x = min - mustRecalculate = true - } - if (thisObject.autoMaxXScale === false) { - thisObject.max.x = max - mustRecalculate = true - } - if (mustRecalculate === true) { - thisObject.recalculateScale() - } + if (min < max) { + let mustRecalculate = false + if (thisObject.autoMinXScale === false) { + thisObject.min.x = min + mustRecalculate = true + } + if (thisObject.autoMaxXScale === false) { + thisObject.max.x = max + mustRecalculate = true + } + if (mustRecalculate === true) { + thisObject.recalculateScale() + } + } } - } - function zoomY (factor, mousePosition, container) { - let mouseAtCointainer = unTransformThisPoint(mousePosition, container) - let topDistance = mouseAtCointainer.y - let bottomDistance = container.frame.height - mouseAtCointainer.y - let diff = thisObject.max.y - thisObject.min.y - let min = thisObject.min.y + diff * factor * bottomDistance / (container.frame.height / 2) - let max = thisObject.max.y - diff * factor * topDistance / (container.frame.height / 2) + function zoomY(factor, mousePosition, container) { + let mouseAtCointainer = unTransformThisPoint(mousePosition, container) + let topDistance = mouseAtCointainer.y + let bottomDistance = container.frame.height - mouseAtCointainer.y + let diff = thisObject.max.y - thisObject.min.y + let min = thisObject.min.y + diff * factor * bottomDistance / (container.frame.height / 2) + let max = thisObject.max.y - diff * factor * topDistance / (container.frame.height / 2) - if (min < max) { - let mustRecalculate = false - if (thisObject.autoMinYScale === false) { - thisObject.min.y = min - mustRecalculate = true - } - if (thisObject.autoMaxYScale === false) { - thisObject.max.y = max - mustRecalculate = true - } - if (mustRecalculate === true) { - thisObject.recalculateScale() - } + if (min < max) { + let mustRecalculate = false + if (thisObject.autoMinYScale === false) { + thisObject.min.y = min + mustRecalculate = true + } + if (thisObject.autoMaxYScale === false) { + thisObject.max.y = max + mustRecalculate = true + } + if (mustRecalculate === true) { + thisObject.recalculateScale() + } + } } - } - function initializeX (minValue, maxValue, maxWidth) { - thisObject.min.x = minValue.x // * 0.999; // 0.1% less - thisObject.max.x = maxValue.x // * 1.001; // 0.1% more + function initializeX(minValue, maxValue, maxWidth) { + thisObject.min.x = minValue.x // * 0.999; // 0.1% less + thisObject.max.x = maxValue.x // * 1.001; // 0.1% more - thisObject.scale.x = thisObject.maxWidth / (thisObject.max.x - thisObject.min.x) - } + thisObject.scale.x = thisObject.maxWidth / (thisObject.max.x - thisObject.min.x) + } - function initializeY (minValue, maxValue, pMaxHeight) { - thisObject.min.y = minValue.y // * 0.999; // 0.1% less - thisObject.max.y = maxValue.y // * 1.001; // 0.1% more + function initializeY(minValue, maxValue, pMaxHeight) { + thisObject.min.y = minValue.y // * 0.999; // 0.1% less + thisObject.max.y = maxValue.y // * 1.001; // 0.1% more - thisObject.scale.y = pMaxHeight / (thisObject.max.y - thisObject.min.y) + thisObject.scale.y = pMaxHeight / (thisObject.max.y - thisObject.min.y) - thisObject.maxHeight = pMaxHeight - } + thisObject.maxHeight = pMaxHeight + } - function transformThisPoint (point) { + function transformThisPoint(point) { /* This is the straigh fordward transformation this object provides. The input is a point on the data set that wants to be plotted in a timeline. @@ -334,38 +334,38 @@ function newCoordinateSystem () { */ - point = { - x: (point.x - thisObject.min.x) * thisObject.scale.x + thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, - y: thisObject.maxHeight - (point.y - thisObject.min.y) * thisObject.scale.y - thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + point = { + x: (point.x - thisObject.min.x) * thisObject.scale.x + thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, + y: thisObject.maxHeight - (point.y - thisObject.min.y) * thisObject.scale.y - thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + } + + return point } - return point - } + function transformThisPoint2(point) { + point = { + x: (point.x - thisObject.min.x) * thisObject.scale.x + thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, + y: (thisObject.maxHeight - point.y - thisObject.min.y) * thisObject.scale.y - thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + } - function transformThisPoint2 (point) { - point = { - x: (point.x - thisObject.min.x) * thisObject.scale.x + thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, - y: (thisObject.maxHeight - point.y - thisObject.min.y) * thisObject.scale.y - thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + return point } - return point - } + function unInverseTransform(point, inverseY) { + point = { + x: ((point.x - thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2) / thisObject.scale.x) + thisObject.min.x, + y: (inverseY * thisObject.VERTICAL_MARGIN_FACTOR - point.y + thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2) / thisObject.scale.y + thisObject.min.y + } - function unInverseTransform (point, inverseY) { - point = { - x: ((point.x - thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2) / thisObject.scale.x) + thisObject.min.x, - y: (inverseY * thisObject.VERTICAL_MARGIN_FACTOR - point.y + thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2) / thisObject.scale.y + thisObject.min.y + return point } - return point - } + function inverseTransformUncappedY(point, inverseY) { + point = { + x: (point.x - thisObject.min.x) * thisObject.scale.x + thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, + y: (inverseY * thisObject.VERTICAL_MARGIN_FACTOR - point.y) * thisObject.scale.y - thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + } - function inverseTransformUncappedY (point, inverseY) { - point = { - x: (point.x - thisObject.min.x) * thisObject.scale.x + thisObject.maxWidth * thisObject.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, - y: (inverseY * thisObject.VERTICAL_MARGIN_FACTOR - point.y) * thisObject.scale.y - thisObject.maxHeight * thisObject.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + return point } - - return point - } } diff --git a/ChartingSpace/EdgeEditor.js b/ChartingSpace/EdgeEditor.js index 134d0006f..2b0cf02e7 100644 --- a/ChartingSpace/EdgeEditor.js +++ b/ChartingSpace/EdgeEditor.js @@ -1,725 +1,725 @@ -function newEdgeEditor () { - const MODULE_NAME = 'Edge Editor' +function newEdgeEditor() { + const MODULE_NAME = 'Edge Editor' - let thisObject = { - container: undefined, - fitFunction: undefined, - isVisible: true, - isMouseOver: undefined, - resetAspectRatio: resetAspectRatio, - onKeyPressed: onKeyPressed, - physics: physics, - drawForeground: drawForeground, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - const EDGE_SIZE = 6 - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = true - thisObject.container.isClickeable = false - thisObject.container.isWheelable = false - thisObject.container.detectMouseOver = true - - let whatHappened - let whereIsMouseOver = 'outside' - - let coordinateSystem - let coordinateSystemWhenDragStarted - - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - let onDragStartedEventSubscriptionId - - let mouse = { - position: { - x: 0, - y: 0 - } - } - - mouseWhenDragStarted = { - position: { - x: 0, - y: 0 - } - } - - parentFrameWhenDragStarted = { - position: { - x: 0, - y: 0 - }, - width: 0, - height: 0 - } - - let doubleClickCounter = 0 - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onDragStartedEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - mouse = undefined - mouseWhenDragStarted = undefined - parentFrameWhenDragStarted = undefined - - coordinateSystem = undefined - - if (coordinateSystemWhenDragStarted !== undefined) { - coordinateSystemWhenDragStarted.finalize() + let thisObject = { + container: undefined, + fitFunction: undefined, + isVisible: true, + isMouseOver: undefined, + resetAspectRatio: resetAspectRatio, + onKeyPressed: onKeyPressed, + physics: physics, + drawForeground: drawForeground, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - coordinateSystemWhenDragStarted = undefined - } + const EDGE_SIZE = 6 - function initialize (pCoordinateSystem) { - coordinateSystem = pCoordinateSystem + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - onDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted) - } + thisObject.container.isDraggeable = true + thisObject.container.isClickeable = false + thisObject.container.isWheelable = false + thisObject.container.detectMouseOver = true - function onMouseOver (event) { - thisObject.isMouseOver = true - mouse = { - position: { - x: event.x, - y: event.y - } - } - } + let whatHappened + let whereIsMouseOver = 'outside' - function onMouseNotOver () { - thisObject.isMouseOver = false - } + let coordinateSystem + let coordinateSystemWhenDragStarted - function resetAspectRatio () { - /* Resize the Time Machine to match the current screen aspect ration */ + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + let onDragStartedEventSubscriptionId - thisObject.container.parentContainer.frame.width = browserCanvas.width / TIME_MACHINE_WIDTH - thisObject.container.parentContainer.frame.height = (COCKPIT_SPACE_POSITION - TOP_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT - coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height - coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width - coordinateSystem.recalculateScale() - thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) - } - - function onDoubleClick (event) { - doubleClickCounter = 0 - if (canvas.chartingSpace.viewport.zoomLevel === DOUBLE_CLICK_ZOOM_OUT_LEVEL) { - canvas.chartingSpace.viewport.displaceToContainer(thisObject.container.parentContainer) - canvas.chartingSpace.viewport.zoomAtCenter(DOUBLE_CLICK_ZOOM_IN_LEVEL) - return - } - if (canvas.chartingSpace.viewport.zoomLevel === DOUBLE_CLICK_ZOOM_IN_LEVEL) { - canvas.chartingSpace.viewport.zoomAtCenter(DOUBLE_CLICK_ZOOM_IN_IN_LEVEL) - return - } - } - - function onDragStarted (event) { - if (event.buttons === 1) { - if (doubleClickCounter > 0) { - onDoubleClick(event) - return - } else { - doubleClickCounter = 50 - } + let mouse = { + position: { + x: 0, + y: 0 + } } mouseWhenDragStarted = { - position: { - x: event.x, - y: event.y - } + position: { + x: 0, + y: 0 + } } parentFrameWhenDragStarted = { - position: { - x: thisObject.container.parentContainer.frame.position.x, - y: thisObject.container.parentContainer.frame.position.y - }, - width: thisObject.container.parentContainer.frame.width, - height: thisObject.container.parentContainer.frame.height + position: { + x: 0, + y: 0 + }, + width: 0, + height: 0 } - coordinateSystemWhenDragStarted = newCoordinateSystem() + let doubleClickCounter = 0 - let minValue = { - x: coordinateSystem.min.x, - y: coordinateSystem.min.y - } + return thisObject - let maxValue = { - x: coordinateSystem.max.x, - y: coordinateSystem.max.y - } + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onDragStartedEventSubscriptionId) - coordinateSystemWhenDragStarted.initialize(minValue, maxValue, coordinateSystem.maxWidth, coordinateSystem.maxHeight) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + mouse = undefined + mouseWhenDragStarted = undefined + parentFrameWhenDragStarted = undefined - switch (event.buttons) { - case 1: { - whatHappened = 'left mouse button' - if (event.shiftKey === true) { - whatHappened = 'left mouse button + SHIFT' + coordinateSystem = undefined + + if (coordinateSystemWhenDragStarted !== undefined) { + coordinateSystemWhenDragStarted.finalize() } - break - } - case 2: { - whatHappened = 'right mouse button' // this will never happen as of today - break - } - } - } - function onKeyPressed (event) { - const STEP = 10 - - if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowLeft') { - onDragStarted(event) - thisObject.container.frame.position.x = thisObject.container.frame.position.x + STEP - whatHappened = 'left or right arrow key pressed' - return + coordinateSystemWhenDragStarted = undefined } - if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowRight') { - if (ARE_WE_RECORDING_A_MARKET_PANORAMA === true) { - if (PANORAMA_WAS_PANNED === false) { - PANORAMA_WAS_PANNED = true - onDragStarted(event) - thisObject.container.frame.position.x = thisObject.container.frame.position.x - STEP * 2 - whatHappened = 'left or right arrow key pressed' + function initialize(pCoordinateSystem) { + coordinateSystem = pCoordinateSystem + + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + onDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted) + } + + function onMouseOver(event) { + thisObject.isMouseOver = true + mouse = { + position: { + x: event.x, + y: event.y + } } - } else { - onDragStarted(event) - thisObject.container.frame.position.x = thisObject.container.frame.position.x - STEP - whatHappened = 'left or right arrow key pressed' - } - return } - if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowUp') { - onDragStarted(event) - thisObject.container.frame.position.y = thisObject.container.frame.position.y + STEP - whatHappened = 'up or down arrow key pressed' - return + function onMouseNotOver() { + thisObject.isMouseOver = false } - if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowDown') { - onDragStarted(event) - thisObject.container.frame.position.y = thisObject.container.frame.position.y - STEP - whatHappened = 'up or down arrow key pressed' - return + function resetAspectRatio() { + /* Resize the Time Machine to match the current screen aspect ration */ + + thisObject.container.parentContainer.frame.width = browserCanvas.width / TIME_MACHINE_WIDTH + thisObject.container.parentContainer.frame.height = (COCKPIT_SPACE_POSITION - TOP_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT + coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height + coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width + coordinateSystem.recalculateScale() + thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) } - if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'A' || event.key === 'a')) { - resetAspectRatio() - return - } - } - - function getContainer (event, purpose) { - if (thisObject.container.frame.isThisPointHere(event, undefined, undefined, -EDGE_SIZE) === true && event.buttons !== 2) { - let point = { - x: event.x, - y: event.y - } - point = unTransformThisPoint(point, thisObject.container) - - if (point.x <= 0) { - whereIsMouseOver = 'left' - return thisObject.container - } - - if (point.x >= thisObject.container.frame.width) { - whereIsMouseOver = 'right' - return thisObject.container - } - - if (point.y <= 0) { - whereIsMouseOver = 'top' - return thisObject.container - } - - if (point.y >= thisObject.container.frame.height) { - whereIsMouseOver = 'bottom' - return thisObject.container - } - - whereIsMouseOver = 'center' - switch (purpose) { - case GET_CONTAINER_PURPOSE.MOUSE_OVER: - return // We will let the Time Machine to handle this situation. - break - case GET_CONTAINER_PURPOSE.DRAGGING: - return thisObject.container - break - } - } - } - - function physics () { - draggingPhysics() - doubleClickPhysics() - } - - function doubleClickPhysics () { - doubleClickCounter-- - if (doubleClickCounter < 0) { - doubleClickCounter = 0 - } - } - - function draggingPhysics () { - if (coordinateSystemWhenDragStarted === undefined) { return } - if (thisObject.container.frame.position.x === 0 && thisObject.container.frame.position.y === 0) { return } - - let mouseNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mouse.position) - let mouseWhenDragStartedNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mouseWhenDragStarted.position) - - let dragVectorWhenDragStarted = { - x: mouseNoZoom.x - mouseWhenDragStartedNoZoom.x, - y: mouseNoZoom.y - mouseWhenDragStartedNoZoom.y + function onDoubleClick(event) { + doubleClickCounter = 0 + if (canvas.chartingSpace.viewport.zoomLevel === DOUBLE_CLICK_ZOOM_OUT_LEVEL) { + canvas.chartingSpace.viewport.displaceToContainer(thisObject.container.parentContainer) + canvas.chartingSpace.viewport.zoomAtCenter(DOUBLE_CLICK_ZOOM_IN_LEVEL) + return + } + if (canvas.chartingSpace.viewport.zoomLevel === DOUBLE_CLICK_ZOOM_IN_LEVEL) { + canvas.chartingSpace.viewport.zoomAtCenter(DOUBLE_CLICK_ZOOM_IN_IN_LEVEL) + return + } } - let dragVector = { - x: thisObject.container.frame.position.x, - y: thisObject.container.frame.position.y + function onDragStarted(event) { + if (event.buttons === 1) { + if (doubleClickCounter > 0) { + onDoubleClick(event) + return + } else { + doubleClickCounter = 50 + } + } + + mouseWhenDragStarted = { + position: { + x: event.x, + y: event.y + } + } + + parentFrameWhenDragStarted = { + position: { + x: thisObject.container.parentContainer.frame.position.x, + y: thisObject.container.parentContainer.frame.position.y + }, + width: thisObject.container.parentContainer.frame.width, + height: thisObject.container.parentContainer.frame.height + } + + coordinateSystemWhenDragStarted = newCoordinateSystem() + + let minValue = { + x: coordinateSystem.min.x, + y: coordinateSystem.min.y + } + + let maxValue = { + x: coordinateSystem.max.x, + y: coordinateSystem.max.y + } + + coordinateSystemWhenDragStarted.initialize(minValue, maxValue, coordinateSystem.maxWidth, coordinateSystem.maxHeight) + + switch (event.buttons) { + case 1: { + whatHappened = 'left mouse button' + if (event.shiftKey === true) { + whatHappened = 'left mouse button + SHIFT' + } + break + } + case 2: { + whatHappened = 'right mouse button' // this will never happen as of today + break + } + } } - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 + function onKeyPressed(event) { + const STEP = 10 - const MIN_WIDTH = 200 - const MIN_HEIGHT = 100 + if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowLeft') { + onDragStarted(event) + thisObject.container.frame.position.x = thisObject.container.frame.position.x + STEP + whatHappened = 'left or right arrow key pressed' + return + } - switch (whereIsMouseOver) { - case 'center': { - switch (whatHappened) { - case 'left mouse button + SHIFT': { - /* This is equivalent to drag the whole Time Machine, so we will apply the translation received onto the Time Machine container. */ - thisObject.container.parentContainer.frame.position.x = parentFrameWhenDragStarted.position.x + dragVectorWhenDragStarted.x - thisObject.container.parentContainer.frame.position.y = parentFrameWhenDragStarted.position.y + dragVectorWhenDragStarted.y - snapPointToGrid(thisObject.container.parentContainer.frame.position) - thisObject.container.parentContainer.eventHandler.raiseEvent('onDisplace') - break - } - case 'left mouse button': { + if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowRight') { + if (ARE_WE_RECORDING_A_MARKET_PANORAMA === true) { + if (PANORAMA_WAS_PANNED === false) { + PANORAMA_WAS_PANNED = true + onDragStarted(event) + thisObject.container.frame.position.x = thisObject.container.frame.position.x - STEP * 2 + whatHappened = 'left or right arrow key pressed' + } + } else { + onDragStarted(event) + thisObject.container.frame.position.x = thisObject.container.frame.position.x - STEP + whatHappened = 'left or right arrow key pressed' + } + return + } + + if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowUp') { + onDragStarted(event) + thisObject.container.frame.position.y = thisObject.container.frame.position.y + STEP + whatHappened = 'up or down arrow key pressed' + return + } + + if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowDown') { + onDragStarted(event) + thisObject.container.frame.position.y = thisObject.container.frame.position.y - STEP + whatHappened = 'up or down arrow key pressed' + return + } + + if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'A' || event.key === 'a')) { + resetAspectRatio() + return + } + } + + function getContainer(event, purpose) { + if (thisObject.container.frame.isThisPointHere(event, undefined, undefined, -EDGE_SIZE) === true && event.buttons !== 2) { let point = { - x: (-dragVectorWhenDragStarted.x), - y: (-dragVectorWhenDragStarted.y) + x: event.x, + y: event.y + } + point = unTransformThisPoint(point, thisObject.container) + + if (point.x <= 0) { + whereIsMouseOver = 'left' + return thisObject.container } - let newMinDate = getDateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystemWhenDragStarted) - let newMaxRate = getRateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystemWhenDragStarted) - - let xDifferenceMaxMin = coordinateSystemWhenDragStarted.max.x - coordinateSystemWhenDragStarted.min.x - let yDifferenceMaxMin = coordinateSystemWhenDragStarted.max.y - coordinateSystemWhenDragStarted.min.y - coordinateSystem.min.x = newMinDate.valueOf() - coordinateSystem.max.x = newMinDate.valueOf() + xDifferenceMaxMin - coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin - coordinateSystem.max.y = newMaxRate - let event = { - type: 'center dragged', - dragVector: dragVector - } - coordinateSystem.recalculateScale(event) - } - break - case 'left or right arrow key pressed': { - let point = { - x: -dragVector.x + thisObject.container.frame.width * coordinateSystem.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, - y: 0 + if (point.x >= thisObject.container.frame.width) { + whereIsMouseOver = 'right' + return thisObject.container } - let newMinDate = getDateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystem) - let xDifferenceMaxMin = coordinateSystem.max.x - coordinateSystem.min.x - coordinateSystem.min.x = newMinDate.valueOf() - coordinateSystem.max.x = newMinDate.valueOf() + xDifferenceMaxMin - let event = { - type: 'center dragged', - dragVector: dragVector - } - coordinateSystem.recalculateScale(event) - } - break - case 'up or down arrow key pressed': { - let point = { - x: 0, - y: -dragVector.y + thisObject.container.frame.height * coordinateSystem.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + if (point.y <= 0) { + whereIsMouseOver = 'top' + return thisObject.container } - let newMaxRate = getRateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystem) - let yDifferenceMaxMin = coordinateSystem.max.y - coordinateSystem.min.y - coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin - coordinateSystem.max.y = newMaxRate - let event = { - type: 'center dragged', - dragVector: dragVector + if (point.y >= thisObject.container.frame.height) { + whereIsMouseOver = 'bottom' + return thisObject.container } - coordinateSystem.recalculateScale(event) - } - break - } - thisObject.container.parentContainer.eventHandler.raiseEvent('onMouseOver', mouse.position) - break - } - case 'top' : { - dragVectorWhenDragStarted.x = 0 - let newHight = parentFrameWhenDragStarted.height - dragVectorWhenDragStarted.y - if (newHight < MIN_HEIGHT && dragVectorWhenDragStarted.y > 0) { - dragVectorWhenDragStarted.y = parentFrameWhenDragStarted.height - MIN_HEIGHT - } - - thisObject.container.parentContainer.frame.position.y = parentFrameWhenDragStarted.position.y + dragVectorWhenDragStarted.y - snapPointToGrid(thisObject.container.parentContainer.frame.position) - thisObject.container.parentContainer.frame.height = parentFrameWhenDragStarted.height + (parentFrameWhenDragStarted.position.y - thisObject.container.parentContainer.frame.position.y) - - let point = { - x: 0, - y: (thisObject.container.parentContainer.frame.position.y - parentFrameWhenDragStarted.position.y) - } - - /* This is equivalent to getRateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ - point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.height) - let newMaxRate = point.y - - switch (whatHappened) { - case 'left mouse button': { - coordinateSystem.max.y = newMaxRate - coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height - let event = { - type: 'top dragged', - dragVector: dragVector + whereIsMouseOver = 'center' + switch (purpose) { + case GET_CONTAINER_PURPOSE.MOUSE_OVER: + return // We will let the Time Machine to handle this situation. + break + case GET_CONTAINER_PURPOSE.DRAGGING: + return thisObject.container + break } - coordinateSystem.recalculateScale(event) - break - } - case 'left mouse button + SHIFT': { - coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height - coordinateSystem.recalculateScale() - break - } } - thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) - break - } - case 'bottom' : { - dragVectorWhenDragStarted.x = 0 + } - let newHight = dragVectorWhenDragStarted.y + parentFrameWhenDragStarted.height - if (newHight < MIN_HEIGHT && dragVectorWhenDragStarted.y < 0) { - dragVectorWhenDragStarted.y = MIN_HEIGHT - parentFrameWhenDragStarted.height + function physics() { + draggingPhysics() + doubleClickPhysics() + } + + function doubleClickPhysics() { + doubleClickCounter-- + if (doubleClickCounter < 0) { + doubleClickCounter = 0 + } + } + + function draggingPhysics() { + if (coordinateSystemWhenDragStarted === undefined) { return } + if (thisObject.container.frame.position.x === 0 && thisObject.container.frame.position.y === 0) { return } + + let mouseNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mouse.position) + let mouseWhenDragStartedNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mouseWhenDragStarted.position) + + let dragVectorWhenDragStarted = { + x: mouseNoZoom.x - mouseWhenDragStartedNoZoom.x, + y: mouseNoZoom.y - mouseWhenDragStartedNoZoom.y } - let point = { - x: 0, - y: dragVectorWhenDragStarted.y + parentFrameWhenDragStarted.height + parentFrameWhenDragStarted.position.y + let dragVector = { + x: thisObject.container.frame.position.x, + y: thisObject.container.frame.position.y } - snapPointToGrid(point) - point.y = point.y - parentFrameWhenDragStarted.position.y - thisObject.container.parentContainer.frame.height = point.y + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 - /* This is equivalent to getRateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ - point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.height) - let newMinRate = point.y + const MIN_WIDTH = 200 + const MIN_HEIGHT = 100 - switch (whatHappened) { - case 'left mouse button': { - coordinateSystem.min.y = newMinRate - coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height - let event = { - type: 'bottom dragged', - dragVector: dragVector + switch (whereIsMouseOver) { + case 'center': { + switch (whatHappened) { + case 'left mouse button + SHIFT': { + /* This is equivalent to drag the whole Time Machine, so we will apply the translation received onto the Time Machine container. */ + thisObject.container.parentContainer.frame.position.x = parentFrameWhenDragStarted.position.x + dragVectorWhenDragStarted.x + thisObject.container.parentContainer.frame.position.y = parentFrameWhenDragStarted.position.y + dragVectorWhenDragStarted.y + snapPointToGrid(thisObject.container.parentContainer.frame.position) + thisObject.container.parentContainer.eventHandler.raiseEvent('onDisplace') + break + } + case 'left mouse button': { + let point = { + x: (-dragVectorWhenDragStarted.x), + y: (-dragVectorWhenDragStarted.y) + } + + let newMinDate = getDateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystemWhenDragStarted) + let newMaxRate = getRateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystemWhenDragStarted) + + let xDifferenceMaxMin = coordinateSystemWhenDragStarted.max.x - coordinateSystemWhenDragStarted.min.x + let yDifferenceMaxMin = coordinateSystemWhenDragStarted.max.y - coordinateSystemWhenDragStarted.min.y + coordinateSystem.min.x = newMinDate.valueOf() + coordinateSystem.max.x = newMinDate.valueOf() + xDifferenceMaxMin + coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin + coordinateSystem.max.y = newMaxRate + let event = { + type: 'center dragged', + dragVector: dragVector + } + coordinateSystem.recalculateScale(event) + } + break + case 'left or right arrow key pressed': { + let point = { + x: -dragVector.x + thisObject.container.frame.width * coordinateSystem.HORIZONTAL_MARGIN_INVERSE_FACTOR / 2, + y: 0 + } + + let newMinDate = getDateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystem) + let xDifferenceMaxMin = coordinateSystem.max.x - coordinateSystem.min.x + coordinateSystem.min.x = newMinDate.valueOf() + coordinateSystem.max.x = newMinDate.valueOf() + xDifferenceMaxMin + let event = { + type: 'center dragged', + dragVector: dragVector + } + coordinateSystem.recalculateScale(event) + } + break + case 'up or down arrow key pressed': { + let point = { + x: 0, + y: -dragVector.y + thisObject.container.frame.height * coordinateSystem.VERTICAL_MARGIN_INVERSE_FACTOR / 2 + } + + let newMaxRate = getRateFromPointAtContainer(point, thisObject.container.parentContainer, coordinateSystem) + let yDifferenceMaxMin = coordinateSystem.max.y - coordinateSystem.min.y + coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin + coordinateSystem.max.y = newMaxRate + let event = { + type: 'center dragged', + dragVector: dragVector + } + coordinateSystem.recalculateScale(event) + } + break + } + thisObject.container.parentContainer.eventHandler.raiseEvent('onMouseOver', mouse.position) + break } - coordinateSystem.recalculateScale(event) - break - } - case 'left mouse button + SHIFT': { - coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height - coordinateSystem.recalculateScale() - break - } - } - thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) - break - } - case 'left' : { - dragVectorWhenDragStarted.y = 0 + case 'top': { + dragVectorWhenDragStarted.x = 0 - let newWidth = parentFrameWhenDragStarted.width - dragVectorWhenDragStarted.x - if (newWidth < MIN_WIDTH && dragVectorWhenDragStarted.x > 0) { - dragVectorWhenDragStarted.x = parentFrameWhenDragStarted.width - MIN_WIDTH + let newHight = parentFrameWhenDragStarted.height - dragVectorWhenDragStarted.y + if (newHight < MIN_HEIGHT && dragVectorWhenDragStarted.y > 0) { + dragVectorWhenDragStarted.y = parentFrameWhenDragStarted.height - MIN_HEIGHT + } + + thisObject.container.parentContainer.frame.position.y = parentFrameWhenDragStarted.position.y + dragVectorWhenDragStarted.y + snapPointToGrid(thisObject.container.parentContainer.frame.position) + thisObject.container.parentContainer.frame.height = parentFrameWhenDragStarted.height + (parentFrameWhenDragStarted.position.y - thisObject.container.parentContainer.frame.position.y) + + let point = { + x: 0, + y: (thisObject.container.parentContainer.frame.position.y - parentFrameWhenDragStarted.position.y) + } + + /* This is equivalent to getRateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ + point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.height) + let newMaxRate = point.y + + switch (whatHappened) { + case 'left mouse button': { + coordinateSystem.max.y = newMaxRate + coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height + let event = { + type: 'top dragged', + dragVector: dragVector + } + coordinateSystem.recalculateScale(event) + break + } + case 'left mouse button + SHIFT': { + coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height + coordinateSystem.recalculateScale() + break + } + } + thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) + break + } + case 'bottom': { + dragVectorWhenDragStarted.x = 0 + + let newHight = dragVectorWhenDragStarted.y + parentFrameWhenDragStarted.height + if (newHight < MIN_HEIGHT && dragVectorWhenDragStarted.y < 0) { + dragVectorWhenDragStarted.y = MIN_HEIGHT - parentFrameWhenDragStarted.height + } + + let point = { + x: 0, + y: dragVectorWhenDragStarted.y + parentFrameWhenDragStarted.height + parentFrameWhenDragStarted.position.y + } + snapPointToGrid(point) + point.y = point.y - parentFrameWhenDragStarted.position.y + + thisObject.container.parentContainer.frame.height = point.y + + /* This is equivalent to getRateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ + point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.height) + let newMinRate = point.y + + switch (whatHappened) { + case 'left mouse button': { + coordinateSystem.min.y = newMinRate + coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height + let event = { + type: 'bottom dragged', + dragVector: dragVector + } + coordinateSystem.recalculateScale(event) + break + } + case 'left mouse button + SHIFT': { + coordinateSystem.maxHeight = thisObject.container.parentContainer.frame.height + coordinateSystem.recalculateScale() + break + } + } + thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) + break + } + case 'left': { + dragVectorWhenDragStarted.y = 0 + + let newWidth = parentFrameWhenDragStarted.width - dragVectorWhenDragStarted.x + if (newWidth < MIN_WIDTH && dragVectorWhenDragStarted.x > 0) { + dragVectorWhenDragStarted.x = parentFrameWhenDragStarted.width - MIN_WIDTH + } + + thisObject.container.parentContainer.frame.position.x = parentFrameWhenDragStarted.position.x + dragVectorWhenDragStarted.x + snapPointToGrid(thisObject.container.parentContainer.frame.position) + thisObject.container.parentContainer.frame.width = parentFrameWhenDragStarted.width + (parentFrameWhenDragStarted.position.x - thisObject.container.parentContainer.frame.position.x) + + let point = { + x: (thisObject.container.parentContainer.frame.position.x - parentFrameWhenDragStarted.position.x), + y: 0 + } + + /* This is equivalent to getDateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ + point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.width) + let newMinDate = point.x + + switch (whatHappened) { + case 'left mouse button': { + coordinateSystem.min.x = newMinDate.valueOf() + coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width + coordinateSystem.recalculateScale() + break + } + case 'left mouse button + SHIFT': { + coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width + coordinateSystem.recalculateScale() + break + } + } + thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) + break + } + case 'right': { + dragVectorWhenDragStarted.y = 0 + + let newWidth = dragVectorWhenDragStarted.x + parentFrameWhenDragStarted.width + if (newWidth < MIN_WIDTH && dragVectorWhenDragStarted.x < 0) { + dragVectorWhenDragStarted.x = MIN_WIDTH - parentFrameWhenDragStarted.width + } + + let point = { + x: dragVectorWhenDragStarted.x + parentFrameWhenDragStarted.width + parentFrameWhenDragStarted.position.x, + y: 0 + } + snapPointToGrid(point) + point.x = point.x - parentFrameWhenDragStarted.position.x + + thisObject.container.parentContainer.frame.width = point.x + + /* This is equivalent to getRateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ + point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.width) + let newMaxDate = point.x + + switch (whatHappened) { + case 'left mouse button': { + coordinateSystem.max.x = newMaxDate.valueOf() + coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width + coordinateSystem.recalculateScale() + break + } + case 'left mouse button + SHIFT': { + coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width + coordinateSystem.recalculateScale() + break + } + } + thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) + break + } } - thisObject.container.parentContainer.frame.position.x = parentFrameWhenDragStarted.position.x + dragVectorWhenDragStarted.x - snapPointToGrid(thisObject.container.parentContainer.frame.position) - thisObject.container.parentContainer.frame.width = parentFrameWhenDragStarted.width + (parentFrameWhenDragStarted.position.x - thisObject.container.parentContainer.frame.position.x) - - let point = { - x: (thisObject.container.parentContainer.frame.position.x - parentFrameWhenDragStarted.position.x), - y: 0 + function snapPointToGrid(point) { + point.x = snapScalarToGrid(point.x) + point.y = snapScalarToGrid(point.y) } - /* This is equivalent to getDateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ - point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.width) - let newMinDate = point.x - - switch (whatHappened) { - case 'left mouse button': { - coordinateSystem.min.x = newMinDate.valueOf() - coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width - coordinateSystem.recalculateScale() - break - } - case 'left mouse button + SHIFT': { - coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width - coordinateSystem.recalculateScale() - break - } + function snapScalarToGrid(scalar) { + let sign + if (scalar < 0) { + sign = -1 + } else { + sign = 1 + } + const GRID_SIZE = 10 + return Math.trunc(scalar / GRID_SIZE) * GRID_SIZE + GRID_SIZE / 2 * sign } - thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) - break - } - case 'right' : { - dragVectorWhenDragStarted.y = 0 + } - let newWidth = dragVectorWhenDragStarted.x + parentFrameWhenDragStarted.width - if (newWidth < MIN_WIDTH && dragVectorWhenDragStarted.x < 0) { - dragVectorWhenDragStarted.x = MIN_WIDTH - parentFrameWhenDragStarted.width + function drawForeground() { + let MARGIN = 1 + let edgeSize + let lineWidth + + if (whereIsMouseOver === 'outside' || thisObject.isMouseOver === false) { + edgeSize = 2 + lineWidth = 0.1 + } else { + edgeSize = EDGE_SIZE + lineWidth = 0.5 } - let point = { - x: dragVectorWhenDragStarted.x + parentFrameWhenDragStarted.width + parentFrameWhenDragStarted.position.x, - y: 0 + const OPACITY = 1 + + pointA1 = { + x: 0, + y: 0 } - snapPointToGrid(point) - point.x = point.x - parentFrameWhenDragStarted.position.x - thisObject.container.parentContainer.frame.width = point.x - - /* This is equivalent to getRateFromPointAtContainer, but as we do not have a container anymore because we already change it, we do it like this. */ - point = coordinateSystemWhenDragStarted.unInverseTransform(point, parentFrameWhenDragStarted.width) - let newMaxDate = point.x - - switch (whatHappened) { - case 'left mouse button': { - coordinateSystem.max.x = newMaxDate.valueOf() - coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width - coordinateSystem.recalculateScale() - break - } - case 'left mouse button + SHIFT': { - coordinateSystem.maxWidth = thisObject.container.parentContainer.frame.width - coordinateSystem.recalculateScale() - break - } + pointA2 = { + x: thisObject.container.frame.width, + y: 0 + } + + pointA3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + pointA4 = { + x: 0, + y: thisObject.container.frame.height + } + + pointB1 = { + x: 0, + y: 0 + } + + pointB2 = { + x: thisObject.container.frame.width, + y: 0 + } + + pointB3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + pointB4 = { + x: 0, + y: thisObject.container.frame.height + } + + pointA1 = transformThisPoint(pointA1, thisObject.container) + pointA2 = transformThisPoint(pointA2, thisObject.container) + pointA3 = transformThisPoint(pointA3, thisObject.container) + pointA4 = transformThisPoint(pointA4, thisObject.container) + + pointB1 = transformThisPoint(pointB1, thisObject.container) + pointB2 = transformThisPoint(pointB2, thisObject.container) + pointB3 = transformThisPoint(pointB3, thisObject.container) + pointB4 = transformThisPoint(pointB4, thisObject.container) + + pointA1 = { + x: pointA1.x - MARGIN, + y: pointA1.y - MARGIN + } + + pointA2 = { + x: pointA2.x + MARGIN, + y: pointA2.y - MARGIN + } + + pointA3 = { + x: pointA3.x + MARGIN, + y: pointA3.y + MARGIN + } + + pointA4 = { + x: pointA4.x - MARGIN, + y: pointA4.y + MARGIN + } + + pointB1 = { + x: pointB1.x - edgeSize, + y: pointB1.y - edgeSize + } + + pointB2 = { + x: pointB2.x + edgeSize, + y: pointB2.y - edgeSize + } + + pointB3 = { + x: pointB3.x + edgeSize, + y: pointB3.y + edgeSize + } + + pointB4 = { + x: pointB4.x - edgeSize, + y: pointB4.y + edgeSize + } + + pointA1 = canvas.chartingSpace.viewport.fitIntoViewport(pointA1) + pointA2 = canvas.chartingSpace.viewport.fitIntoViewport(pointA2) + pointA3 = canvas.chartingSpace.viewport.fitIntoViewport(pointA3) + pointA4 = canvas.chartingSpace.viewport.fitIntoViewport(pointA4) + + pointB1 = canvas.chartingSpace.viewport.fitIntoViewport(pointB1) + pointB2 = canvas.chartingSpace.viewport.fitIntoViewport(pointB2) + pointB3 = canvas.chartingSpace.viewport.fitIntoViewport(pointB3) + pointB4 = canvas.chartingSpace.viewport.fitIntoViewport(pointB4) + + browserCanvasContext.setLineDash([0, 0]) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(pointA1.x, pointA1.y) + browserCanvasContext.lineTo(pointA2.x, pointA2.y) + browserCanvasContext.lineTo(pointB2.x, pointB2.y) + browserCanvasContext.lineTo(pointB1.x, pointB1.y) + browserCanvasContext.lineTo(pointA1.x, pointA1.y) + browserCanvasContext.closePath() + + drawEdge('top') + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(pointA2.x, pointA2.y) + browserCanvasContext.lineTo(pointA3.x, pointA3.y) + browserCanvasContext.lineTo(pointB3.x, pointB3.y) + browserCanvasContext.lineTo(pointB2.x, pointB2.y) + browserCanvasContext.lineTo(pointA2.x, pointA2.y) + browserCanvasContext.closePath() + + drawEdge('right') + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(pointA3.x, pointA3.y) + browserCanvasContext.lineTo(pointA4.x, pointA4.y) + browserCanvasContext.lineTo(pointB4.x, pointB4.y) + browserCanvasContext.lineTo(pointB3.x, pointB3.y) + browserCanvasContext.lineTo(pointA3.x, pointA3.y) + browserCanvasContext.closePath() + + drawEdge('bottom') + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(pointA4.x, pointA4.y) + browserCanvasContext.lineTo(pointA1.x, pointA1.y) + browserCanvasContext.lineTo(pointB1.x, pointB1.y) + browserCanvasContext.lineTo(pointB4.x, pointB4.y) + browserCanvasContext.lineTo(pointA4.x, pointA4.y) + browserCanvasContext.closePath() + + drawEdge('left') + + function drawEdge(edgeType) { + if (whereIsMouseOver === edgeType && thisObject.isMouseOver === true) { + browserCanvasContext.lineWidth = lineWidth + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + } else { + browserCanvasContext.lineWidth = lineWidth + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' + } + browserCanvasContext.fill() + browserCanvasContext.stroke() } - thisObject.container.parentContainer.eventHandler.raiseEvent('Dimmensions Changed', event) - break - } } - - function snapPointToGrid (point) { - point.x = snapScalarToGrid(point.x) - point.y = snapScalarToGrid(point.y) - } - - function snapScalarToGrid (scalar) { - let sign - if (scalar < 0) { - sign = -1 - } else { - sign = 1 - } - const GRID_SIZE = 10 - return Math.trunc(scalar / GRID_SIZE) * GRID_SIZE + GRID_SIZE / 2 * sign - } - } - - function drawForeground () { - let MARGIN = 1 - let edgeSize - let lineWidth - - if (whereIsMouseOver === 'outside' || thisObject.isMouseOver === false) { - edgeSize = 2 - lineWidth = 0.1 - } else { - edgeSize = EDGE_SIZE - lineWidth = 0.5 - } - - const OPACITY = 1 - - pointA1 = { - x: 0, - y: 0 - } - - pointA2 = { - x: thisObject.container.frame.width, - y: 0 - } - - pointA3 = { - x: thisObject.container.frame.width, - y: thisObject.container.frame.height - } - - pointA4 = { - x: 0, - y: thisObject.container.frame.height - } - - pointB1 = { - x: 0, - y: 0 - } - - pointB2 = { - x: thisObject.container.frame.width, - y: 0 - } - - pointB3 = { - x: thisObject.container.frame.width, - y: thisObject.container.frame.height - } - - pointB4 = { - x: 0, - y: thisObject.container.frame.height - } - - pointA1 = transformThisPoint(pointA1, thisObject.container) - pointA2 = transformThisPoint(pointA2, thisObject.container) - pointA3 = transformThisPoint(pointA3, thisObject.container) - pointA4 = transformThisPoint(pointA4, thisObject.container) - - pointB1 = transformThisPoint(pointB1, thisObject.container) - pointB2 = transformThisPoint(pointB2, thisObject.container) - pointB3 = transformThisPoint(pointB3, thisObject.container) - pointB4 = transformThisPoint(pointB4, thisObject.container) - - pointA1 = { - x: pointA1.x - MARGIN, - y: pointA1.y - MARGIN - } - - pointA2 = { - x: pointA2.x + MARGIN, - y: pointA2.y - MARGIN - } - - pointA3 = { - x: pointA3.x + MARGIN, - y: pointA3.y + MARGIN - } - - pointA4 = { - x: pointA4.x - MARGIN, - y: pointA4.y + MARGIN - } - - pointB1 = { - x: pointB1.x - edgeSize, - y: pointB1.y - edgeSize - } - - pointB2 = { - x: pointB2.x + edgeSize, - y: pointB2.y - edgeSize - } - - pointB3 = { - x: pointB3.x + edgeSize, - y: pointB3.y + edgeSize - } - - pointB4 = { - x: pointB4.x - edgeSize, - y: pointB4.y + edgeSize - } - - pointA1 = canvas.chartingSpace.viewport.fitIntoViewport(pointA1) - pointA2 = canvas.chartingSpace.viewport.fitIntoViewport(pointA2) - pointA3 = canvas.chartingSpace.viewport.fitIntoViewport(pointA3) - pointA4 = canvas.chartingSpace.viewport.fitIntoViewport(pointA4) - - pointB1 = canvas.chartingSpace.viewport.fitIntoViewport(pointB1) - pointB2 = canvas.chartingSpace.viewport.fitIntoViewport(pointB2) - pointB3 = canvas.chartingSpace.viewport.fitIntoViewport(pointB3) - pointB4 = canvas.chartingSpace.viewport.fitIntoViewport(pointB4) - - browserCanvasContext.setLineDash([0, 0]) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(pointA1.x, pointA1.y) - browserCanvasContext.lineTo(pointA2.x, pointA2.y) - browserCanvasContext.lineTo(pointB2.x, pointB2.y) - browserCanvasContext.lineTo(pointB1.x, pointB1.y) - browserCanvasContext.lineTo(pointA1.x, pointA1.y) - browserCanvasContext.closePath() - - drawEdge('top') - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(pointA2.x, pointA2.y) - browserCanvasContext.lineTo(pointA3.x, pointA3.y) - browserCanvasContext.lineTo(pointB3.x, pointB3.y) - browserCanvasContext.lineTo(pointB2.x, pointB2.y) - browserCanvasContext.lineTo(pointA2.x, pointA2.y) - browserCanvasContext.closePath() - - drawEdge('right') - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(pointA3.x, pointA3.y) - browserCanvasContext.lineTo(pointA4.x, pointA4.y) - browserCanvasContext.lineTo(pointB4.x, pointB4.y) - browserCanvasContext.lineTo(pointB3.x, pointB3.y) - browserCanvasContext.lineTo(pointA3.x, pointA3.y) - browserCanvasContext.closePath() - - drawEdge('bottom') - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(pointA4.x, pointA4.y) - browserCanvasContext.lineTo(pointA1.x, pointA1.y) - browserCanvasContext.lineTo(pointB1.x, pointB1.y) - browserCanvasContext.lineTo(pointB4.x, pointB4.y) - browserCanvasContext.lineTo(pointA4.x, pointA4.y) - browserCanvasContext.closePath() - - drawEdge('left') - - function drawEdge (edgeType) { - if (whereIsMouseOver === edgeType && thisObject.isMouseOver === true) { - browserCanvasContext.lineWidth = lineWidth - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - } else { - browserCanvasContext.lineWidth = lineWidth - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' - } - browserCanvasContext.fill() - browserCanvasContext.stroke() - } - } } diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index 3b76c7698..458a2599b 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -1,459 +1,459 @@ -function newPlottersManager () { - const MODULE_NAME = 'Plotters Manager' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newPlottersManager() { + const MODULE_NAME = 'Plotters Manager' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let timeFrame = INITIAL_TIME_PERIOD - let datetime = NEW_SESSION_INITIAL_DATE + let timeFrame = INITIAL_TIME_PERIOD + let datetime = NEW_SESSION_INITIAL_DATE - let thisObject = { - fitFunction: undefined, - container: undefined, - payload: undefined, - connectors: [], - setDatetime: setDatetime, - setTimeFrame: setTimeFrame, - setCoordinateSystem: setCoordinateSystem, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.connectors = [] - - let initializationReady = false - let layersPanel - let onLayerStatusChangedEventSuscriptionId - let coordinateSystem - - setupContainer() - return thisObject - - function setupContainer () { - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - } - - function finalize () { - layersPanel.container.eventHandler.stopListening(onLayerStatusChangedEventSuscriptionId) - layersPanel = undefined - - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[i] - /* Then the panels. */ - for (let j = 0; j < connector.panels.length; j++) { - canvas.panelsSpace.destroyPanel(connector.panels[j]) - connector.panels[j] = undefined - } - connector.panels = undefined - - /* Finalize the plotters */ - if (connector.plotter.finalize !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId) - connector.plotter.finalize() - } - connector.plotter = undefined - - /* Finally the Storage Objects */ - finalizeStorage(connector.storage) - connector.storage = undefined - - connector = undefined + let thisObject = { + fitFunction: undefined, + container: undefined, + payload: undefined, + connectors: [], + setDatetime: setDatetime, + setTimeFrame: setTimeFrame, + setCoordinateSystem: setCoordinateSystem, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } + thisObject.connectors = [] - coordinateSystem = undefined - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - } + let initializationReady = false + let layersPanel + let onLayerStatusChangedEventSuscriptionId + let coordinateSystem - function finalizeStorage (storage) { - storage.eventHandler.stopListening(storage.onMarketFileLoadedLayerEventsSubscriptionId) - storage.eventHandler.stopListening(storage.onDailyFileLoadedLayerEventsSubscriptionId) - storage.eventHandler.stopListening(storage.onSingleFileLoadedLayerEventsSubscriptionId) - storage.eventHandler.stopListening(storage.onFileSequenceLoadedLayerEventsSubscriptionId) - storage.eventHandler.stopListening(storage.onDailyFileLoadedPlotterEventsSubscriptionId) - storage.finalize() - } + setupContainer() + return thisObject - function initialize (pLayersPanel) { - /* Remember this */ - layersPanel = pLayersPanel - - /* Listen to the event of change of status */ - onLayerStatusChangedEventSuscriptionId = layersPanel.container.eventHandler.listenToEvent('Layer Status Changed', onLayerStatusChanged) - } - - function initializePlotter (layer) { - try { - /* Before Initializing a Plotter, we need the Storage it will use, loaded with the files it will initially need. */ - let storage = newProductStorage(layer.payload.node.id) - - /* - Before Initializing the Storage, we will put the Layer to listen to the events the storage will raise every time a file is loaded, - so that the UI can somehow show this. There are different types of events. - */ - for (let i = 0; i < layer.definition.referenceParent.referenceParent.datasets.length; i++) { - let dataset = layer.definition.referenceParent.referenceParent.datasets[i] - - switch (dataset.config.type) { - case 'Market Files': { - storage.onMarketFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Market File Loaded', layer.onMarketFileLoaded) - } - break - case 'Daily Files': { - storage.onDailyFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', layer.onDailyFileLoaded) - } - break - case 'Single File': { - storage.onSingleFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Single File Loaded', layer.onSingleFileLoaded) - } - break - case 'File Sequence': { - storage.onFileSequenceLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('File Sequence Loaded', layer.onFileSequenceLoaded) - } - break - default: { - if (ERROR_LOG === true) { - logger.write('[ERROR] initializePlotter -> Dataset Type Incorrect or Undefined -> dataset.type = ' + dataset.type) - } - return - } - } - } - - let baseAsset = layer.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent.config.codeName - let quotedAsset = layer.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName - let market = { - baseAsset: baseAsset, - quotedAsset: quotedAsset - } - let productDefinition = layer.definition.referenceParent.referenceParent - let bot = layer.definition.referenceParent.referenceParent.parentNode - let dataMine = layer.definition.referenceParent.referenceParent.parentNode.parentNode - let exchange = layer.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode - let plotterModule = layer.definition.referenceParent.referenceParent.referenceParent - let session - let tradingSystem - let tradingEngine - - /* - A layer can be referencing a Data Product in two different branches of the Network hiriatchy. - In one of those braches we can get the Session node, at the other we Cannot. - */ - if (layer.definition.referenceParent.parentNode.parentNode !== undefined) { - if (layer.definition.referenceParent.parentNode.parentNode.type === 'Session Reference') { - if (layer.definition.referenceParent.parentNode.parentNode.referenceParent !== undefined) { - session = layer.definition.referenceParent.parentNode.parentNode.referenceParent - - /* From the session we might be able to reach the Trading System or the Trading Engine */ - if (session.tradingSystemReference !== undefined) { - tradingSystem = session.tradingSystemReference.referenceParent - } - if (session.tradingEngineReference !== undefined) { - tradingEngine = session.tradingEngineReference.referenceParent - } - } - } - } - - let host = layer.networkNode.config.host - let webPort = layer.networkNode.config.webPort - if (host === undefined) { host = 'localhost' } - if (webPort === undefined) { webPort = window.location.port } - - let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(layer.networkNode.id) - - storage.initialize( - dataMine, - bot, - session, - productDefinition, - exchange, - market, - datetime, - timeFrame, - host, - webPort, - eventsServerClient, - onProductStorageInitialized - ) - - function onProductStorageInitialized (err) { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - /* Now we have all the initial data loaded and ready to be delivered to the new instance of the plotter. */ - let plotter - - if (plotterModule.config.isLegacy !== true) { - plotter = newPlotter() - } else { - plotter = getNewPlotter(dataMine.config.codeName, plotterModule.parentNode.config.codeName, plotterModule.config.codeName) - } - - plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true) - plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2 - plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2 - plotter.fitFunction = thisObject.fitFunction - plotter.initialize(storage, datetime, timeFrame, coordinateSystem, onPlotterInizialized, productDefinition) - - function onPlotterInizialized () { - let connector = { - layer: layer, - plotter: plotter, - storage: storage - } - /* Let the Plotter listen to the event of Cursor Files loaded, so that it can react recalculating if needed. */ - plotter.onDailyFileLoadedPlotterEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', plotter.onDailyFileLoaded) - /* Lets load now this plotter panels. */ - connector.panels = [] - - if (productDefinition !== undefined) { - /* Here we setup the panels associated with this plotter */ - for (let i = 0; i < plotterModule.panels.length; i++) { - let panel = plotterModule.panels[i] - - let parameters = { - dataMine: dataMine.config.codeName, - plotterCodeName: plotterModule.parentNode.config.codeName, - moduleCodeName: plotterModule.config.codeName, - panelNode: panel - } - - let owner = thisObject.payload.node.payload.parentNode.id // Panels are owned by the time machine. - let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, owner, layer.session) - let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle) - - /* Connect Panel to the Plotter via an Event. */ - connector.plotter.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange) - connector.panels.push(plotterPanelHandle) - } - connector.layer.panels = connector.panels - - /* - Next we will check the different types of Plotting related to connecting to an existing node branch. - */ - if (plotterModule.nodesHighlights !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesHighlights = newNodesHighlights() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesHighlights.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesHighlights.initialize(tradingEngine) - break - } - connector.nodesHighlights.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesHighlights.onRecordChange) - } - if (plotterModule.nodesValues !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesValues = newNodesValues() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesValues.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesValues.initialize(tradingEngine) - break - } - connector.nodesValues.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesValues.onRecordChange) - } - if (plotterModule.nodesErrors !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesErrors = newNodesErrors() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesErrors.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesErrors.initialize(tradingEngine) - break - } - connector.nodesErrors.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesErrors.onRecordChange) - } - if (plotterModule.nodesRunning !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesRunning = newNodesRunning() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesRunning.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesRunning.initialize(tradingEngine) - break - } - connector.nodesRunning.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesRunning.onRecordChange) - } - if (plotterModule.nodesStatus !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesStatus = newNodesStatus() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesStatus.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesStatus.initialize(tradingEngine) - break - } - connector.nodesStatus.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesStatus.onRecordChange) - } - if (plotterModule.nodesProgress !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesProgress = newNodesProgress() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesProgress.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesProgress.initialize(tradingEngine) - break - } - connector.nodesProgress.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesProgress.onRecordChange) - } - if (plotterModule.nodesAnnouncements !== undefined && plotterModule.config.connectTo !== undefined) { - connector.nodesAnnounements = newNodesAnnouncements() - switch (plotterModule.config.connectTo) { - case 'Trading System': - connector.nodesAnnounements.initialize(tradingSystem) - break - case 'Trading Engine': - connector.nodesAnnounements.initialize(tradingEngine) - break - } - connector.nodesAnnounements.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesAnnounements.onRecordChange) - } - /* - Another type of plotting is with Record Values. This method uses the record definition to find the target node - and from there is looks into its children all based on the Record Definition configuration. - */ - if (plotterModule.recordValues !== undefined) { - connector.recordValues = newRecordValues() - connector.recordValues.initialize(tradingSystem, tradingEngine, productDefinition) - connector.recordValues.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.recordValues.onRecordChange) - } - } - thisObject.connectors.push(connector) - } - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> err = ' + err.stack) } + function setupContainer() { + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) } - } - function onLayerStatusChanged (layer) { - if (layer.status === LAYER_STATUS.LOADING) { - /* Lets see if we can find the Plotter of this card on our Active Plotters list, other wise we will initialize it */ - let found = false - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[i] - if (connector.layer.payload.node.id === layer.payload.node.id) { - found = true - } - } - if (found === false) { - initializePlotter(layer, onProductPlotterInitialized) - function onProductPlotterInitialized (err) { - /* There is no policy yet of what to do if this fails. */ - } - } - } - if (layer.status === LAYER_STATUS.OFF) { - /* If the plotter of this card is not on our Active Plotters list, then we remove it. */ - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[i] - if (connector.layer.payload.node.id === layer.payload.node.id) { - /* Then the panels. */ - for (let j = 0; j < connector.panels.length; j++) { - canvas.panelsSpace.destroyPanel(connector.panels[j]) - } + function finalize() { + layersPanel.container.eventHandler.stopListening(onLayerStatusChangedEventSuscriptionId) + layersPanel = undefined + + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[i] + /* Then the panels. */ + for (let j = 0; j < connector.panels.length; j++) { + canvas.panelsSpace.destroyPanel(connector.panels[j]) + connector.panels[j] = undefined + } + connector.panels = undefined + + /* Finalize the plotters */ + if (connector.plotter.finalize !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId) + connector.plotter.finalize() + } + connector.plotter = undefined + /* Finally the Storage Objects */ - finalizeNodesPlotting(connector) - if (connector.plotter.finalize !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId) - connector.plotter.container.finalize() - connector.plotter.finalize() - } - finalizeStorage(connector.storage) - thisObject.connectors.splice(i, 1) // Delete item from array. - return // We already found the product woth changes and processed it. + finalizeStorage(connector.storage) + connector.storage = undefined + + connector = undefined } - } - } - } + thisObject.connectors = [] + coordinateSystem = undefined - function finalizeNodesPlotting (connector) { - if (connector.nodesHighlights !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.nodesHighlights.onRecordChangeEventsSubscriptionId) - connector.nodesHighlights.finalize() + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined } - if (connector.nodesValues !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.nodesValues.onRecordChangeEventsSubscriptionId) - connector.nodesValues.finalize() - } - if (connector.nodesErrors !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.nodesErrors.onRecordChangeEventsSubscriptionId) - connector.nodesErrors.finalize() - } - if (connector.nodesStatus !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.nodesStatus.onRecordChangeEventsSubscriptionId) - connector.nodesStatus.finalize() - } - if (connector.nodesProgress !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.Progress.onRecordChangeEventsSubscriptionId) - connector.Progress.finalize() - } - if (connector.nodesRunning !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.nodesRunning.onRecordChangeEventsSubscriptionId) - connector.nodesRunning.finalize() - } - if (connector.recordValues !== undefined) { - connector.plotter.container.eventHandler.stopListening(connector.recordValues.onRecordChangeEventsSubscriptionId) - connector.recordValues.finalize() - } - } - function setTimeFrame (pTimeFrame) { - timeFrame = pTimeFrame - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[i] - connector.layer.setTimeFrame(timeFrame) - connector.storage.setTimeFrame(timeFrame) - connector.plotter.setTimeFrame(timeFrame) + function finalizeStorage(storage) { + storage.eventHandler.stopListening(storage.onMarketFileLoadedLayerEventsSubscriptionId) + storage.eventHandler.stopListening(storage.onDailyFileLoadedLayerEventsSubscriptionId) + storage.eventHandler.stopListening(storage.onSingleFileLoadedLayerEventsSubscriptionId) + storage.eventHandler.stopListening(storage.onFileSequenceLoadedLayerEventsSubscriptionId) + storage.eventHandler.stopListening(storage.onDailyFileLoadedPlotterEventsSubscriptionId) + storage.finalize() } - } - function setDatetime (pDatetime) { - datetime = pDatetime - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[i] - connector.layer.setDatetime(pDatetime) - connector.storage.setDatetime(pDatetime) - connector.plotter.setDatetime(pDatetime) + function initialize(pLayersPanel) { + /* Remember this */ + layersPanel = pLayersPanel + + /* Listen to the event of change of status */ + onLayerStatusChangedEventSuscriptionId = layersPanel.container.eventHandler.listenToEvent('Layer Status Changed', onLayerStatusChanged) } - } - function setCoordinateSystem (pCoordinateSystem) { - coordinateSystem = pCoordinateSystem - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[i] - connector.plotter.setCoordinateSystem(coordinateSystem) + function initializePlotter(layer) { + try { + /* Before Initializing a Plotter, we need the Storage it will use, loaded with the files it will initially need. */ + let storage = newProductStorage(layer.payload.node.id) + + /* + Before Initializing the Storage, we will put the Layer to listen to the events the storage will raise every time a file is loaded, + so that the UI can somehow show this. There are different types of events. + */ + for (let i = 0; i < layer.definition.referenceParent.referenceParent.datasets.length; i++) { + let dataset = layer.definition.referenceParent.referenceParent.datasets[i] + + switch (dataset.config.type) { + case 'Market Files': { + storage.onMarketFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Market File Loaded', layer.onMarketFileLoaded) + } + break + case 'Daily Files': { + storage.onDailyFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', layer.onDailyFileLoaded) + } + break + case 'Single File': { + storage.onSingleFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Single File Loaded', layer.onSingleFileLoaded) + } + break + case 'File Sequence': { + storage.onFileSequenceLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('File Sequence Loaded', layer.onFileSequenceLoaded) + } + break + default: { + if (ERROR_LOG === true) { + logger.write('[ERROR] initializePlotter -> Dataset Type Incorrect or Undefined -> dataset.type = ' + dataset.type) + } + return + } + } + } + + let baseAsset = layer.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + let quotedAsset = layer.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let market = { + baseAsset: baseAsset, + quotedAsset: quotedAsset + } + let productDefinition = layer.definition.referenceParent.referenceParent + let bot = layer.definition.referenceParent.referenceParent.parentNode + let dataMine = layer.definition.referenceParent.referenceParent.parentNode.parentNode + let exchange = layer.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode + let plotterModule = layer.definition.referenceParent.referenceParent.referenceParent + let session + let tradingSystem + let tradingEngine + + /* + A layer can be referencing a Data Product in two different branches of the Network hiriatchy. + In one of those braches we can get the Session node, at the other we Cannot. + */ + if (layer.definition.referenceParent.parentNode.parentNode !== undefined) { + if (layer.definition.referenceParent.parentNode.parentNode.type === 'Session Reference') { + if (layer.definition.referenceParent.parentNode.parentNode.referenceParent !== undefined) { + session = layer.definition.referenceParent.parentNode.parentNode.referenceParent + + /* From the session we might be able to reach the Trading System or the Trading Engine */ + if (session.tradingSystemReference !== undefined) { + tradingSystem = session.tradingSystemReference.referenceParent + } + if (session.tradingEngineReference !== undefined) { + tradingEngine = session.tradingEngineReference.referenceParent + } + } + } + } + + let host = layer.networkNode.config.host + let webPort = layer.networkNode.config.webPort + if (host === undefined) { host = 'localhost' } + if (webPort === undefined) { webPort = window.location.port } + + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(layer.networkNode.id) + + storage.initialize( + dataMine, + bot, + session, + productDefinition, + exchange, + market, + datetime, + timeFrame, + host, + webPort, + eventsServerClient, + onProductStorageInitialized + ) + + function onProductStorageInitialized(err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + /* Now we have all the initial data loaded and ready to be delivered to the new instance of the plotter. */ + let plotter + + if (plotterModule.config.isLegacy !== true) { + plotter = newPlotter() + } else { + plotter = getNewPlotter(dataMine.config.codeName, plotterModule.parentNode.config.codeName, plotterModule.config.codeName) + } + + plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true) + plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2 + plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2 + plotter.fitFunction = thisObject.fitFunction + plotter.initialize(storage, datetime, timeFrame, coordinateSystem, onPlotterInizialized, productDefinition) + + function onPlotterInizialized() { + let connector = { + layer: layer, + plotter: plotter, + storage: storage + } + /* Let the Plotter listen to the event of Cursor Files loaded, so that it can react recalculating if needed. */ + plotter.onDailyFileLoadedPlotterEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', plotter.onDailyFileLoaded) + /* Lets load now this plotter panels. */ + connector.panels = [] + + if (productDefinition !== undefined) { + /* Here we setup the panels associated with this plotter */ + for (let i = 0; i < plotterModule.panels.length; i++) { + let panel = plotterModule.panels[i] + + let parameters = { + dataMine: dataMine.config.codeName, + plotterCodeName: plotterModule.parentNode.config.codeName, + moduleCodeName: plotterModule.config.codeName, + panelNode: panel + } + + let owner = thisObject.payload.node.payload.parentNode.id // Panels are owned by the time machine. + let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, owner, layer.session) + let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle) + + /* Connect Panel to the Plotter via an Event. */ + connector.plotter.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange) + connector.panels.push(plotterPanelHandle) + } + connector.layer.panels = connector.panels + + /* + Next we will check the different types of Plotting related to connecting to an existing node branch. + */ + if (plotterModule.nodesHighlights !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesHighlights = newNodesHighlights() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesHighlights.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesHighlights.initialize(tradingEngine) + break + } + connector.nodesHighlights.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesHighlights.onRecordChange) + } + if (plotterModule.nodesValues !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesValues = newNodesValues() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesValues.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesValues.initialize(tradingEngine) + break + } + connector.nodesValues.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesValues.onRecordChange) + } + if (plotterModule.nodesErrors !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesErrors = newNodesErrors() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesErrors.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesErrors.initialize(tradingEngine) + break + } + connector.nodesErrors.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesErrors.onRecordChange) + } + if (plotterModule.nodesRunning !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesRunning = newNodesRunning() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesRunning.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesRunning.initialize(tradingEngine) + break + } + connector.nodesRunning.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesRunning.onRecordChange) + } + if (plotterModule.nodesStatus !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesStatus = newNodesStatus() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesStatus.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesStatus.initialize(tradingEngine) + break + } + connector.nodesStatus.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesStatus.onRecordChange) + } + if (plotterModule.nodesProgress !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesProgress = newNodesProgress() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesProgress.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesProgress.initialize(tradingEngine) + break + } + connector.nodesProgress.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesProgress.onRecordChange) + } + if (plotterModule.nodesAnnouncements !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesAnnounements = newNodesAnnouncements() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesAnnounements.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesAnnounements.initialize(tradingEngine) + break + } + connector.nodesAnnounements.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesAnnounements.onRecordChange) + } + /* + Another type of plotting is with Record Values. This method uses the record definition to find the target node + and from there is looks into its children all based on the Record Definition configuration. + */ + if (plotterModule.recordValues !== undefined) { + connector.recordValues = newRecordValues() + connector.recordValues.initialize(tradingSystem, tradingEngine, productDefinition) + connector.recordValues.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.recordValues.onRecordChange) + } + } + thisObject.connectors.push(connector) + } + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> err = ' + err.stack) } + } } - } - function getContainer (point) { - } + function onLayerStatusChanged(layer) { + if (layer.status === LAYER_STATUS.LOADING) { + /* Lets see if we can find the Plotter of this card on our Active Plotters list, other wise we will initialize it */ + let found = false + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[i] + if (connector.layer.payload.node.id === layer.payload.node.id) { + found = true + } + } + if (found === false) { + initializePlotter(layer, onProductPlotterInitialized) + function onProductPlotterInitialized(err) { + /* There is no policy yet of what to do if this fails. */ + } + } + } + if (layer.status === LAYER_STATUS.OFF) { + /* If the plotter of this card is not on our Active Plotters list, then we remove it. */ + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[i] + if (connector.layer.payload.node.id === layer.payload.node.id) { + /* Then the panels. */ + for (let j = 0; j < connector.panels.length; j++) { + canvas.panelsSpace.destroyPanel(connector.panels[j]) + } + /* Finally the Storage Objects */ + finalizeNodesPlotting(connector) + if (connector.plotter.finalize !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId) + connector.plotter.container.finalize() + connector.plotter.finalize() + } + finalizeStorage(connector.storage) + thisObject.connectors.splice(i, 1) // Delete item from array. + return // We already found the product woth changes and processed it. + } + } + } + } - function draw () { - if (thisObject.connectors === undefined) { return } // We need to wait + function finalizeNodesPlotting(connector) { + if (connector.nodesHighlights !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesHighlights.onRecordChangeEventsSubscriptionId) + connector.nodesHighlights.finalize() + } + if (connector.nodesValues !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesValues.onRecordChangeEventsSubscriptionId) + connector.nodesValues.finalize() + } + if (connector.nodesErrors !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesErrors.onRecordChangeEventsSubscriptionId) + connector.nodesErrors.finalize() + } + if (connector.nodesStatus !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesStatus.onRecordChangeEventsSubscriptionId) + connector.nodesStatus.finalize() + } + if (connector.nodesProgress !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.Progress.onRecordChangeEventsSubscriptionId) + connector.Progress.finalize() + } + if (connector.nodesRunning !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesRunning.onRecordChangeEventsSubscriptionId) + connector.nodesRunning.finalize() + } + if (connector.recordValues !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.recordValues.onRecordChangeEventsSubscriptionId) + connector.recordValues.finalize() + } + } + + function setTimeFrame(pTimeFrame) { + timeFrame = pTimeFrame + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[i] + connector.layer.setTimeFrame(timeFrame) + connector.storage.setTimeFrame(timeFrame) + connector.plotter.setTimeFrame(timeFrame) + } + } + + function setDatetime(pDatetime) { + datetime = pDatetime + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[i] + connector.layer.setDatetime(pDatetime) + connector.storage.setDatetime(pDatetime) + connector.plotter.setDatetime(pDatetime) + } + } + + function setCoordinateSystem(pCoordinateSystem) { + coordinateSystem = pCoordinateSystem + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[i] + connector.plotter.setCoordinateSystem(coordinateSystem) + } + } + + function getContainer(point) { + } + + function draw() { + if (thisObject.connectors === undefined) { return } // We need to wait /* First the Product Plotters. */ - let maxElementsPlotted = 0 - for (let i = 0; i < thisObject.connectors.length; i++) { - let connector = thisObject.connectors[thisObject.connectors.length - i - 1] - let elementsPlotted = connector.plotter.draw() - if (elementsPlotted !== undefined) { - if (elementsPlotted > maxElementsPlotted) { - maxElementsPlotted = elementsPlotted + let maxElementsPlotted = 0 + for (let i = 0; i < thisObject.connectors.length; i++) { + let connector = thisObject.connectors[thisObject.connectors.length - i - 1] + let elementsPlotted = connector.plotter.draw() + if (elementsPlotted !== undefined) { + if (elementsPlotted > maxElementsPlotted) { + maxElementsPlotted = elementsPlotted + } + } } - } + return maxElementsPlotted } - return maxElementsPlotted - } } diff --git a/ChartingSpace/TimeMachine.js b/ChartingSpace/TimeMachine.js index ab252f437..9257df6a8 100644 --- a/ChartingSpace/TimeMachine.js +++ b/ChartingSpace/TimeMachine.js @@ -9,814 +9,814 @@ each one with it own timelineCharts, and each one positioned at an especific poi */ -function newTimeMachine () { - const MODULE_NAME = 'Time Machine' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newTimeMachine() { + const MODULE_NAME = 'Time Machine' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let timeFrame = INITIAL_TIME_PERIOD + let timeFrame = INITIAL_TIME_PERIOD - let thisObject = { - container: undefined, - timeScale: undefined, - rateScale: undefined, - payload: undefined, - edgeEditor: undefined, - onFocus: undefined, - onKeyPressed: onKeyPressed, - timelineCharts: [], - fitFunction: fitFunction, - physics: physics, - draw: draw, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } - - let timeMachineCoordinateSystem = newCoordinateSystem() - timeMachineCoordinateSystem.name = 'TIME MACHINE' - - let mouse = { - position: { - x: 0, - y: 0 - } - } - - let tabAnimation = 0 - let tabAnimationStatus = 'Close' - let tabAnimationCounter = 0 - let wasOnFocus = false - let drawScales = false - let syncWithDesignerLoop = 0 - let timelineChartsMap = new Map() - - let onMouseOverEventSuscriptionId - let onMouseNotOverEventSuscriptionId - let timeScaleMouseOverEventSuscriptionId - let rateScaleMouseOverEventSuscriptionId - let timeFrameScaleEventSuscriptionId - let timeFrameScaleMouseOverEventSuscriptionId - let onScaleChangedEventSubscriptionId - - setupContainer() - return thisObject - - function setupContainer () { - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.fitFunction = thisObject.fitFunction - thisObject.container.isDraggeable = false - thisObject.container.insideViewport = true - thisObject.container.detectMouseOver = true - - thisObject.container.frame.width = browserCanvas.width / TIME_MACHINE_WIDTH - thisObject.container.frame.height = (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT - } - - function finalize () { - timeMachineCoordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId) - - if (thisObject.timeScale !== undefined) { - finalizeTimeScale() + let thisObject = { + container: undefined, + timeScale: undefined, + rateScale: undefined, + payload: undefined, + edgeEditor: undefined, + onFocus: undefined, + onKeyPressed: onKeyPressed, + timelineCharts: [], + fitFunction: fitFunction, + physics: physics, + draw: draw, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize } - if (thisObject.rateScale !== undefined) { - finalizeRateScale() + let timeMachineCoordinateSystem = newCoordinateSystem() + timeMachineCoordinateSystem.name = 'TIME MACHINE' + + let mouse = { + position: { + x: 0, + y: 0 + } } - if (thisObject.timeFrameScale !== undefined) { - finalizeTimeFrameScale() + let tabAnimation = 0 + let tabAnimationStatus = 'Close' + let tabAnimationCounter = 0 + let wasOnFocus = false + let drawScales = false + let syncWithDesignerLoop = 0 + let timelineChartsMap = new Map() + + let onMouseOverEventSuscriptionId + let onMouseNotOverEventSuscriptionId + let timeScaleMouseOverEventSuscriptionId + let rateScaleMouseOverEventSuscriptionId + let timeFrameScaleEventSuscriptionId + let timeFrameScaleMouseOverEventSuscriptionId + let onScaleChangedEventSubscriptionId + + setupContainer() + return thisObject + + function setupContainer() { + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.fitFunction = thisObject.fitFunction + thisObject.container.isDraggeable = false + thisObject.container.insideViewport = true + thisObject.container.detectMouseOver = true + + thisObject.container.frame.width = browserCanvas.width / TIME_MACHINE_WIDTH + thisObject.container.frame.height = (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT } - thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSuscriptionId) + function finalize() { + timeMachineCoordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId) - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[i] - timelineChart.container.eventHandler.stopListening(timelineChart.onChildrenMouseOverEventSuscriptionId) - timelineChart.finalize() - } + if (thisObject.timeScale !== undefined) { + finalizeTimeScale() + } - thisObject.timelineCharts = undefined - thisObject.fitFunction = undefined - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.edgeEditor = undefined + if (thisObject.rateScale !== undefined) { + finalizeRateScale() + } - mouse = undefined - timelineChartsMap = undefined + if (thisObject.timeFrameScale !== undefined) { + finalizeTimeFrameScale() + } - timeMachineCoordinateSystem.finalize() - timeMachineCoordinateSystem = undefined - } + thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSuscriptionId) - function finalizeTimeScale () { - if (thisObject.timeScale === undefined) { return } - - thisObject.timeScale.container.eventHandler.stopListening(timeScaleMouseOverEventSuscriptionId) - thisObject.timeScale.finalize() - thisObject.timeScale = undefined - } - - function finalizeRateScale () { - if (thisObject.rateScale === undefined) { return } - - thisObject.rateScale.container.eventHandler.stopListening(rateScaleMouseOverEventSuscriptionId) - thisObject.rateScale.finalize() - thisObject.rateScale = undefined - } - - function finalizeTimeFrameScale () { - if (thisObject.timeFrameScale === undefined) { return } - - thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleEventSuscriptionId) - thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleMouseOverEventSuscriptionId) - thisObject.timeFrameScale.finalize() - thisObject.timeFrameScale = undefined - } - - function initialize (callBackFunction) { - timeFrame = INITIAL_TIME_PERIOD - loadFrame(thisObject.payload, thisObject.container.frame) - saveFrame(thisObject.payload, thisObject.container.frame) - - recalculateCoordinateSystem() - recalculateCurrentDatetime() - - onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - onScaleChangedEventSubscriptionId = timeMachineCoordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) - - thisObject.edgeEditor = newEdgeEditor() - thisObject.edgeEditor.initialize(timeMachineCoordinateSystem) - thisObject.edgeEditor.container.connectToParent(thisObject.container, true, true, false, true, true, true) - - callBackFunction() - } - - function onKeyPressed (event) { - thisObject.edgeEditor.onKeyPressed(event) - } - - function onMouseOver (event) { - drawScales = true - - mouse.position.x = event.x - mouse.position.y = event.y - - if (thisObject.timeScale !== undefined) { - thisObject.timeScale.onMouseOverSomeTimeMachineContainer(event) - } - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.onMouseOverSomeTimeMachineContainer(event) - } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.onMouseOverSomeTimeMachineContainer(event) - } - } - - function onMouseNotOver (event) { - drawScales = false - - if (thisObject.timeScale !== undefined) { - thisObject.timeScale.visible = false - } - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.visible = false - } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.visible = false - } - } - - function initializeTimeScale () { - thisObject.timeScale = newTimeScale() - thisObject.timeScale.fitFunction = thisObject.fitFunction - thisObject.timeScale.payload = thisObject.payload.node.timeScale.payload - - timeScaleMouseOverEventSuscriptionId = thisObject.timeScale.container.eventHandler.listenToEvent('onMouseOverScale', timeScaleMouseOver) - thisObject.timeScale.initialize(timeMachineCoordinateSystem, thisObject.container) - - function timeScaleMouseOver (event) { - thisObject.container.eventHandler.raiseEvent('onMouseOver', event) - } - } - - function initializeRateScale () { - thisObject.rateScale = newRateScale() - thisObject.rateScale.fitFunction = thisObject.fitFunction - thisObject.rateScale.payload = thisObject.payload.node.rateScale.payload - - rateScaleMouseOverEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('onMouseOverScale', rateScaleMouseOver) - thisObject.rateScale.initialize(timeMachineCoordinateSystem, thisObject.container, thisObject.container) - - function rateScaleMouseOver (event) { - thisObject.container.eventHandler.raiseEvent('onMouseOver', event) - } - } - - function initializeTimeFrameScale () { - thisObject.timeFrameScale = newTimeFrameScale() - thisObject.timeFrameScale.fitFunction = thisObject.fitFunction - thisObject.timeFrameScale.payload = thisObject.payload.node.timeFrameScale.payload - - timeFrameScaleEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('Time Frame Value Changed', timeFrameScaleValueChanged) - timeFrameScaleMouseOverEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('onMouseOverScale', timeFrameScaleMouseOver) - thisObject.timeFrameScale.initialize(thisObject.container) - - function timeFrameScaleValueChanged (event) { - let currentTimeFrame = timeFrame - timeFrame = event.timeFrame - if (timeFrame !== currentTimeFrame) { for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[i] - timelineChart.upstreamTimeFrame = timeFrame - if (timelineChart.timeFrameScale === undefined) { - timelineChart.setTimeFrame(timeFrame) - } + let timelineChart = thisObject.timelineCharts[i] + timelineChart.container.eventHandler.stopListening(timelineChart.onChildrenMouseOverEventSuscriptionId) + timelineChart.finalize() } - } - } - function timeFrameScaleMouseOver (event) { - thisObject.container.eventHandler.raiseEvent('onMouseOver', event) - } - } - function getContainer (point, purpose) { - let container + thisObject.timelineCharts = undefined + thisObject.fitFunction = undefined + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.edgeEditor = undefined - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { - container = thisObject.rateScale.getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - return container - } else { - if (purpose === GET_CONTAINER_PURPOSE.DRAGGING && container.isClickeable === true) { - return container - } + mouse = undefined + timelineChartsMap = undefined + + timeMachineCoordinateSystem.finalize() + timeMachineCoordinateSystem = undefined + } + + function finalizeTimeScale() { + if (thisObject.timeScale === undefined) { return } + + thisObject.timeScale.container.eventHandler.stopListening(timeScaleMouseOverEventSuscriptionId) + thisObject.timeScale.finalize() + thisObject.timeScale = undefined + } + + function finalizeRateScale() { + if (thisObject.rateScale === undefined) { return } + + thisObject.rateScale.container.eventHandler.stopListening(rateScaleMouseOverEventSuscriptionId) + thisObject.rateScale.finalize() + thisObject.rateScale = undefined + } + + function finalizeTimeFrameScale() { + if (thisObject.timeFrameScale === undefined) { return } + + thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleEventSuscriptionId) + thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleMouseOverEventSuscriptionId) + thisObject.timeFrameScale.finalize() + thisObject.timeFrameScale = undefined + } + + function initialize(callBackFunction) { + timeFrame = INITIAL_TIME_PERIOD + loadFrame(thisObject.payload, thisObject.container.frame) + saveFrame(thisObject.payload, thisObject.container.frame) + + recalculateCoordinateSystem() + recalculateCurrentDatetime() + + onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + onScaleChangedEventSubscriptionId = timeMachineCoordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) + + thisObject.edgeEditor = newEdgeEditor() + thisObject.edgeEditor.initialize(timeMachineCoordinateSystem) + thisObject.edgeEditor.container.connectToParent(thisObject.container, true, true, false, true, true, true) + + callBackFunction() + } + + function onKeyPressed(event) { + thisObject.edgeEditor.onKeyPressed(event) + } + + function onMouseOver(event) { + drawScales = true + + mouse.position.x = event.x + mouse.position.y = event.y + + if (thisObject.timeScale !== undefined) { + thisObject.timeScale.onMouseOverSomeTimeMachineContainer(event) } - } - } - - if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { - container = thisObject.timeScale.getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - return container - } else { - if (purpose === GET_CONTAINER_PURPOSE.DRAGGING && container.isClickeable === true) { - return container - } + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.onMouseOverSomeTimeMachineContainer(event) } - } - } - - if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { - container = thisObject.timeFrameScale.getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - return container + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.onMouseOverSomeTimeMachineContainer(event) } - } } - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - container = thisObject.timelineCharts[i].getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - if (thisObject.container.frame.isThisPointHere(point) === true) { - return container - } - } else { - if (purpose === GET_CONTAINER_PURPOSE.DRAGGING && container.isClickeable === true) { - if (thisObject.container.frame.isThisPointHere(point) === true) { - return container + function onMouseNotOver(event) { + drawScales = false + + if (thisObject.timeScale !== undefined) { + thisObject.timeScale.visible = false + } + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.visible = false + } + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.visible = false + } + } + + function initializeTimeScale() { + thisObject.timeScale = newTimeScale() + thisObject.timeScale.fitFunction = thisObject.fitFunction + thisObject.timeScale.payload = thisObject.payload.node.timeScale.payload + + timeScaleMouseOverEventSuscriptionId = thisObject.timeScale.container.eventHandler.listenToEvent('onMouseOverScale', timeScaleMouseOver) + thisObject.timeScale.initialize(timeMachineCoordinateSystem, thisObject.container) + + function timeScaleMouseOver(event) { + thisObject.container.eventHandler.raiseEvent('onMouseOver', event) + } + } + + function initializeRateScale() { + thisObject.rateScale = newRateScale() + thisObject.rateScale.fitFunction = thisObject.fitFunction + thisObject.rateScale.payload = thisObject.payload.node.rateScale.payload + + rateScaleMouseOverEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('onMouseOverScale', rateScaleMouseOver) + thisObject.rateScale.initialize(timeMachineCoordinateSystem, thisObject.container, thisObject.container) + + function rateScaleMouseOver(event) { + thisObject.container.eventHandler.raiseEvent('onMouseOver', event) + } + } + + function initializeTimeFrameScale() { + thisObject.timeFrameScale = newTimeFrameScale() + thisObject.timeFrameScale.fitFunction = thisObject.fitFunction + thisObject.timeFrameScale.payload = thisObject.payload.node.timeFrameScale.payload + + timeFrameScaleEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('Time Frame Value Changed', timeFrameScaleValueChanged) + timeFrameScaleMouseOverEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('onMouseOverScale', timeFrameScaleMouseOver) + thisObject.timeFrameScale.initialize(thisObject.container) + + function timeFrameScaleValueChanged(event) { + let currentTimeFrame = timeFrame + timeFrame = event.timeFrame + if (timeFrame !== currentTimeFrame) { + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[i] + timelineChart.upstreamTimeFrame = timeFrame + if (timelineChart.timeFrameScale === undefined) { + timelineChart.setTimeFrame(timeFrame) + } + } } - } } - } - } - - container = thisObject.edgeEditor.getContainer(point, purpose) - if (container !== undefined) { - return container - } else { - if (thisObject.container.isForThisPurpose(purpose)) { - if (thisObject.container.frame.isThisPointHere(point) === true) { - return thisObject.container + function timeFrameScaleMouseOver(event) { + thisObject.container.eventHandler.raiseEvent('onMouseOver', event) } - } - } - } - - function onScaleChanged () { - recalculateCurrentDatetime() - } - - function recalculateCurrentDatetime () { - let center = { - x: thisObject.container.frame.width / 2, - y: thisObject.container.frame.height / 2 } - datetime = new Date(getDateFromPointAtContainer(center, thisObject.container, timeMachineCoordinateSystem)) + function getContainer(point, purpose) { + let container - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[i] - timelineChart.setDatetime(datetime) - } - } - - function fitFunction (point, fullVisible, margin, topMargin, bottomMargin) { - /* We prevent a point to be out of the container AND out of the Charting Space in general */ - - let returnPoint = { - x: point.x, - y: point.y - } - - let upCorner = { - x: 0, - y: 0 - } - - let bottonCorner = { - x: thisObject.container.frame.width, - y: thisObject.container.frame.height - } - - upCorner = transformThisPoint(upCorner, thisObject.container) - bottonCorner = transformThisPoint(bottonCorner, thisObject.container) - - /* Checking against the container limits. */ - if (margin === undefined) { margin = 0 } - if (topMargin === undefined) { topMargin = 0 } - if (bottomMargin === undefined) { bottomMargin = 0 } - - if (returnPoint.x - margin < upCorner.x) { returnPoint.x = upCorner.x + margin } - if (returnPoint.x + margin > bottonCorner.x) { returnPoint.x = bottonCorner.x - margin } - if (returnPoint.y - margin - topMargin < upCorner.y) { returnPoint.y = upCorner.y + margin + topMargin } - if (returnPoint.y + margin + bottomMargin > bottonCorner.y) { returnPoint.y = bottonCorner.y - margin - bottomMargin } - - returnPoint = canvas.chartingSpace.fitFunction(returnPoint, fullVisible) - - return returnPoint - } - - function physics () { - thisObject.edgeEditor.physics() - timeMachineCoordinateSystem.physics() - - saveFrame(thisObject.payload, thisObject.container.frame) - if (thisObject.container.frame.isInViewPort()) { - childrenPhysics() - syncWithDesigner() - } - panelPhysics() - onFocusPhysics() - tabAnimationPhysics() - } - - function tabAnimationPhysics () { - const MAX_COUNTER_VALUE = 40 - const STEP = 10 - - if (wasOnFocus === true && thisObject.onFocus === false) { - tabAnimationStatus = 'Closing' - } - if (wasOnFocus === false && thisObject.onFocus === true) { - tabAnimationStatus = 'Opening' - } - - if (tabAnimationStatus === 'Closing') { - tabAnimationCounter = tabAnimationCounter - STEP - if (tabAnimationCounter <= 0) { - tabAnimationCounter = 0 - tabAnimationStatus = 'Closed' - } - } - if (tabAnimationStatus === 'Opening') { - tabAnimationCounter = tabAnimationCounter + STEP - if (tabAnimationCounter >= MAX_COUNTER_VALUE) { - tabAnimationCounter = MAX_COUNTER_VALUE - tabAnimationStatus = 'Open' - } - } - } - - function onFocusPhysics () { - wasOnFocus = thisObject.onFocus - if (thisObject.edgeEditor.isMouseOver === true) { - thisObject.onFocus = true - } else { - thisObject.onFocus = false - } - } - - function panelPhysics () { - if ( - thisObject.container.frame.isInViewPort() && - canvas.chartingSpace.viewport.zoomLevel >= ZOOM_OUT_THRESHOLD_FOR_NOT_HIDDING_PANELS) { - canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Layers Panel') - canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Plotter Panel') - return - } - - if ( - thisObject.container.frame.isCenterInViewPort() && - canvas.chartingSpace.viewport.zoomLevel >= ZOOM_OUT_THRESHOLD_FOR_HIDDING_PANELS - ) { - canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Layers Panel') - canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Plotter Panel') - } else { - canvas.panelsSpace.hide(thisObject.payload.node.id, 'Layers Panel') - canvas.panelsSpace.hide(thisObject.payload.node.id, 'Plotter Panel') - } - } - - function syncWithDesigner () { - syncWithDesignerTimelineCharts() - syncWithDesignerScales() - } - - function syncWithDesignerScales () { - if (thisObject.payload.node === undefined) { - finalizeTimeScale() - finalizeRateScale() - finalizeTimeFrameScale() - return - } - if (thisObject.payload.node.timeScale === undefined && thisObject.timeScale !== undefined) { - finalizeTimeScale() - } - if (thisObject.payload.node.timeScale !== undefined && thisObject.timeScale === undefined) { - initializeTimeScale() - } - if (thisObject.payload.node.rateScale === undefined && thisObject.rateScale !== undefined) { - finalizeRateScale() - } - if (thisObject.payload.node.rateScale !== undefined && thisObject.rateScale === undefined) { - initializeRateScale() - } - if (thisObject.payload.node.timeFrameScale === undefined && thisObject.timeFrameScale !== undefined) { - finalizeTimeFrameScale() - } - if (thisObject.payload.node.timeFrameScale !== undefined && thisObject.timeFrameScale === undefined) { - initializeTimeFrameScale() - } - } - - function syncWithDesignerTimelineCharts () { - syncWithDesignerLoop = syncWithDesignerLoop + 0.00000000001 - - for (let j = 0; j < thisObject.payload.node.timelineCharts.length; j++) { - let node = thisObject.payload.node.timelineCharts[j] - let timelineChart = timelineChartsMap.get(node.id) - if (timelineChart === undefined) { - /* The timeline timelineChart node is new, thus we need to initialize a new timelineChart */ - initializeTimelineChart(node, syncWithDesignerLoop) - } else { - /* The time machine already exists, we tag it as existing at the current loop. */ - timelineChart.syncWithDesignerLoop = syncWithDesignerLoop - } - } - - /* We check all the timeMachines we have to see if we need to remove any of them */ - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[i] - if (timelineChart.syncWithDesignerLoop < syncWithDesignerLoop) { - /* Must be removed */ - timelineChart.container.eventHandler.stopListening(timelineChart.onChildrenMouseOverEventSuscriptionId) - timelineChart.finalize() - timelineChartsMap.delete(timelineChart.nodeId) - thisObject.timelineCharts.splice(i, 1) - /* We remove one at the time */ - return - } - } - - function initializeTimelineChart (node, syncWithDesignerLoop) { - let timelineChart = newTimelineChart() - timelineChart.syncWithDesignerLoop = syncWithDesignerLoop - timelineChart.payload = node.payload - timelineChart.nodeId = node.id - timelineChartsMap.set(node.id, timelineChart) - timelineChart.payload.uiObject.setValue('Loading...') - - /* Setting up the new timeline timelineChart. */ - timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true) - timelineChart.container.fitFunction = thisObject.container.fitFunction - timelineChart.fitFunction = thisObject.fitFunction - timelineChart.container.frame.width = thisObject.container.frame.width - timelineChart.container.frame.height = thisObject.container.frame.height - timelineChart.container.frame.position.x = 0 - timelineChart.container.frame.position.y = 0 - timelineChart.initialize(timeMachineCoordinateSystem, timeFrame) - - /* we will store the event suscription id as a property of the timelineChart, to avoid keeping it an a separate array */ - timelineChart.onChildrenMouseOverEventSuscriptionId = timelineChart.container.eventHandler.listenToEvent('onChildrenMouseOver', onChildrenMouseOver) - - thisObject.timelineCharts.push(timelineChart) - timelineChart.payload.uiObject.setValue('') - - function onChildrenMouseOver (event) { - thisObject.container.eventHandler.raiseEvent('onMouseOver', event) - } - } - } - - function childrenPhysics () { - if (thisObject.timeScale !== undefined) { - thisObject.timeScale.physics() - } - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.physics() - } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.physics() - } - - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[i] - timelineChart.physics() - } - } - - function drawBackground () { - drawChartsBackground() - if (thisObject.container.frame.isInViewPort()) { - if (drawScales === true) { - if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.drawBackground() } - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawBackground() } - } - - let maxElementsPlotted = 0 - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1] - let elementsPlotted = timelineChart.drawBackground() - if (elementsPlotted !== undefined) { - if (elementsPlotted > maxElementsPlotted) { - maxElementsPlotted = elementsPlotted - } + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { + container = thisObject.rateScale.getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + return container + } else { + if (purpose === GET_CONTAINER_PURPOSE.DRAGGING && container.isClickeable === true) { + return container + } + } + } + } + + if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { + container = thisObject.timeScale.getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + return container + } else { + if (purpose === GET_CONTAINER_PURPOSE.DRAGGING && container.isClickeable === true) { + return container + } + } + } + } + + if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { + container = thisObject.timeFrameScale.getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + return container + } + } + } + + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + container = thisObject.timelineCharts[i].getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + if (thisObject.container.frame.isThisPointHere(point) === true) { + return container + } + } else { + if (purpose === GET_CONTAINER_PURPOSE.DRAGGING && container.isClickeable === true) { + if (thisObject.container.frame.isThisPointHere(point) === true) { + return container + } + } + } + } + } + + container = thisObject.edgeEditor.getContainer(point, purpose) + if (container !== undefined) { + return container + } else { + if (thisObject.container.isForThisPurpose(purpose)) { + if (thisObject.container.frame.isThisPointHere(point) === true) { + return thisObject.container + } + } } - } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.adjustTimeFrame(maxElementsPlotted) - } } - } - function drawChartsBackground () { - drawContainerBackground(thisObject.container, UI_COLOR.WHITE, 0.5, thisObject.fitFunction) - } + function onScaleChanged() { + recalculateCurrentDatetime() + } - function draw () { - if (thisObject.payload === undefined) { return } - if (thisObject.payload.node === undefined) { return } - if (thisObject.container.frame.isInViewPort()) { - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1] - timelineChart.draw() - } + function recalculateCurrentDatetime() { + let center = { + x: thisObject.container.frame.width / 2, + y: thisObject.container.frame.height / 2 + } - if (drawScales === true) { - if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.draw() } - if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.draw() } - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.draw() } - } - } else { - if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_TIME_MACHINES_ICONIZED) { + datetime = new Date(getDateFromPointAtContainer(center, thisObject.container, timeMachineCoordinateSystem)) + + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[i] + timelineChart.setDatetime(datetime) + } + } + + function fitFunction(point, fullVisible, margin, topMargin, bottomMargin) { + /* We prevent a point to be out of the container AND out of the Charting Space in general */ + + let returnPoint = { + x: point.x, + y: point.y + } + + let upCorner = { + x: 0, + y: 0 + } + + let bottonCorner = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + upCorner = transformThisPoint(upCorner, thisObject.container) + bottonCorner = transformThisPoint(bottonCorner, thisObject.container) + + /* Checking against the container limits. */ + if (margin === undefined) { margin = 0 } + if (topMargin === undefined) { topMargin = 0 } + if (bottomMargin === undefined) { bottomMargin = 0 } + + if (returnPoint.x - margin < upCorner.x) { returnPoint.x = upCorner.x + margin } + if (returnPoint.x + margin > bottonCorner.x) { returnPoint.x = bottonCorner.x - margin } + if (returnPoint.y - margin - topMargin < upCorner.y) { returnPoint.y = upCorner.y + margin + topMargin } + if (returnPoint.y + margin + bottomMargin > bottonCorner.y) { returnPoint.y = bottonCorner.y - margin - bottomMargin } + + returnPoint = canvas.chartingSpace.fitFunction(returnPoint, fullVisible) + + return returnPoint + } + + function physics() { + thisObject.edgeEditor.physics() + timeMachineCoordinateSystem.physics() + + saveFrame(thisObject.payload, thisObject.container.frame) + if (thisObject.container.frame.isInViewPort()) { + childrenPhysics() + syncWithDesigner() + } + panelPhysics() + onFocusPhysics() + tabAnimationPhysics() + } + + function tabAnimationPhysics() { + const MAX_COUNTER_VALUE = 40 + const STEP = 10 + + if (wasOnFocus === true && thisObject.onFocus === false) { + tabAnimationStatus = 'Closing' + } + if (wasOnFocus === false && thisObject.onFocus === true) { + tabAnimationStatus = 'Opening' + } + + if (tabAnimationStatus === 'Closing') { + tabAnimationCounter = tabAnimationCounter - STEP + if (tabAnimationCounter <= 0) { + tabAnimationCounter = 0 + tabAnimationStatus = 'Closed' + } + } + if (tabAnimationStatus === 'Opening') { + tabAnimationCounter = tabAnimationCounter + STEP + if (tabAnimationCounter >= MAX_COUNTER_VALUE) { + tabAnimationCounter = MAX_COUNTER_VALUE + tabAnimationStatus = 'Open' + } + } + } + + function onFocusPhysics() { + wasOnFocus = thisObject.onFocus + if (thisObject.edgeEditor.isMouseOver === true) { + thisObject.onFocus = true + } else { + thisObject.onFocus = false + } + } + + function panelPhysics() { + if ( + thisObject.container.frame.isInViewPort() && + canvas.chartingSpace.viewport.zoomLevel >= ZOOM_OUT_THRESHOLD_FOR_NOT_HIDDING_PANELS) { + canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Layers Panel') + canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Plotter Panel') + return + } + + if ( + thisObject.container.frame.isCenterInViewPort() && + canvas.chartingSpace.viewport.zoomLevel >= ZOOM_OUT_THRESHOLD_FOR_HIDDING_PANELS + ) { + canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Layers Panel') + canvas.panelsSpace.unHide(thisObject.payload.node.id, 'Plotter Panel') + } else { + canvas.panelsSpace.hide(thisObject.payload.node.id, 'Layers Panel') + canvas.panelsSpace.hide(thisObject.payload.node.id, 'Plotter Panel') + } + } + + function syncWithDesigner() { + syncWithDesignerTimelineCharts() + syncWithDesignerScales() + } + + function syncWithDesignerScales() { + if (thisObject.payload.node === undefined) { + finalizeTimeScale() + finalizeRateScale() + finalizeTimeFrameScale() + return + } + if (thisObject.payload.node.timeScale === undefined && thisObject.timeScale !== undefined) { + finalizeTimeScale() + } + if (thisObject.payload.node.timeScale !== undefined && thisObject.timeScale === undefined) { + initializeTimeScale() + } + if (thisObject.payload.node.rateScale === undefined && thisObject.rateScale !== undefined) { + finalizeRateScale() + } + if (thisObject.payload.node.rateScale !== undefined && thisObject.rateScale === undefined) { + initializeRateScale() + } + if (thisObject.payload.node.timeFrameScale === undefined && thisObject.timeFrameScale !== undefined) { + finalizeTimeFrameScale() + } + if (thisObject.payload.node.timeFrameScale !== undefined && thisObject.timeFrameScale === undefined) { + initializeTimeFrameScale() + } + } + + function syncWithDesignerTimelineCharts() { + syncWithDesignerLoop = syncWithDesignerLoop + 0.00000000001 + + for (let j = 0; j < thisObject.payload.node.timelineCharts.length; j++) { + let node = thisObject.payload.node.timelineCharts[j] + let timelineChart = timelineChartsMap.get(node.id) + if (timelineChart === undefined) { + /* The timeline timelineChart node is new, thus we need to initialize a new timelineChart */ + initializeTimelineChart(node, syncWithDesignerLoop) + } else { + /* The time machine already exists, we tag it as existing at the current loop. */ + timelineChart.syncWithDesignerLoop = syncWithDesignerLoop + } + } + + /* We check all the timeMachines we have to see if we need to remove any of them */ + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[i] + if (timelineChart.syncWithDesignerLoop < syncWithDesignerLoop) { + /* Must be removed */ + timelineChart.container.eventHandler.stopListening(timelineChart.onChildrenMouseOverEventSuscriptionId) + timelineChart.finalize() + timelineChartsMap.delete(timelineChart.nodeId) + thisObject.timelineCharts.splice(i, 1) + /* We remove one at the time */ + return + } + } + + function initializeTimelineChart(node, syncWithDesignerLoop) { + let timelineChart = newTimelineChart() + timelineChart.syncWithDesignerLoop = syncWithDesignerLoop + timelineChart.payload = node.payload + timelineChart.nodeId = node.id + timelineChartsMap.set(node.id, timelineChart) + timelineChart.payload.uiObject.setValue('Loading...') + + /* Setting up the new timeline timelineChart. */ + timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true) + timelineChart.container.fitFunction = thisObject.container.fitFunction + timelineChart.fitFunction = thisObject.fitFunction + timelineChart.container.frame.width = thisObject.container.frame.width + timelineChart.container.frame.height = thisObject.container.frame.height + timelineChart.container.frame.position.x = 0 + timelineChart.container.frame.position.y = 0 + timelineChart.initialize(timeMachineCoordinateSystem, timeFrame) + + /* we will store the event suscription id as a property of the timelineChart, to avoid keeping it an a separate array */ + timelineChart.onChildrenMouseOverEventSuscriptionId = timelineChart.container.eventHandler.listenToEvent('onChildrenMouseOver', onChildrenMouseOver) + + thisObject.timelineCharts.push(timelineChart) + timelineChart.payload.uiObject.setValue('') + + function onChildrenMouseOver(event) { + thisObject.container.eventHandler.raiseEvent('onMouseOver', event) + } + } + } + + function childrenPhysics() { + if (thisObject.timeScale !== undefined) { + thisObject.timeScale.physics() + } + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.physics() + } + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.physics() + } + + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[i] + timelineChart.physics() + } + } + + function drawBackground() { + drawChartsBackground() + if (thisObject.container.frame.isInViewPort()) { + if (drawScales === true) { + if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.drawBackground() } + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawBackground() } + } + + let maxElementsPlotted = 0 + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1] + let elementsPlotted = timelineChart.drawBackground() + if (elementsPlotted !== undefined) { + if (elementsPlotted > maxElementsPlotted) { + maxElementsPlotted = elementsPlotted + } + } + } + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.adjustTimeFrame(maxElementsPlotted) + } + } + } + + function drawChartsBackground() { + drawContainerBackground(thisObject.container, UI_COLOR.WHITE, 0.5, thisObject.fitFunction) + } + + function draw() { + if (thisObject.payload === undefined) { return } + if (thisObject.payload.node === undefined) { return } + if (thisObject.container.frame.isInViewPort()) { + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1] + timelineChart.draw() + } + + if (drawScales === true) { + if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.draw() } + if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.draw() } + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.draw() } + } + } else { + if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_TIME_MACHINES_ICONIZED) { + let icon = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + let imageSize = 40 + let imagePosition = { + x: thisObject.container.frame.width / 2, + y: thisObject.container.frame.height / 2 + } + + imagePosition = transformThisPoint(imagePosition, thisObject.container) + imagePosition = thisObject.fitFunction(imagePosition, true) + + browserCanvasContext.drawImage( + icon, + imagePosition.x - imageSize / 2, + imagePosition.y - imageSize / 2, + imageSize, + imageSize) + } + } + } + } + } + + function drawForeground() { + if (thisObject.container.frame.isInViewPort()) { + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1] + timelineChart.drawForeground() + } + + if (drawScales === true) { + if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.drawForeground() } + if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.drawForeground() } + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawForeground() } + } + + drawLabel() + thisObject.edgeEditor.drawForeground() + } + } + + function drawLabel() { + if (thisObject.payload.node === undefined) { return } + if (thisObject.payload === undefined) { return } + /* Draw Title Above the Container */ + let position = { + x: 0, + y: 0 + } + let imageSize = 13 + let fontSize = 15 + let opacity = 1 let icon = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) + + position = transformThisPoint(position, thisObject.container) + + let label = thisObject.payload.node.name + let description = loadPropertyFromNodeConfig(thisObject.payload, 'description') + + if (description !== undefined) { + label = description + } + printLabel(label, position.x + 20, position.y - 10, opacity, fontSize) + if (icon !== undefined) { - if (icon.canDrawIcon === true) { - let imageSize = 40 - let imagePosition = { - x: thisObject.container.frame.width / 2, - y: thisObject.container.frame.height / 2 + if (icon.canDrawIcon === true) { + browserCanvasContext.drawImage( + icon, position.x + 5, + position.y - 22, + imageSize, + imageSize) + } + } + + imageSize = 13 + fontSize = 15 + let exchangeMarkets = new Map() + + for (let i = 0; i < thisObject.timelineCharts.length; i++) { + let timelinechart = thisObject.timelineCharts[i] + if (timelinechart.layersManager !== undefined) { + for (let j = 0; j < timelinechart.layersManager.layers.length; j++) { + let layer = timelinechart.layersManager.layers[j] + + exchangeMarket = { + exchangeName: layer.exchange.name, + marketName: layer.market, + exchangeIcon: layer.exchangeIcon, + baseAssetIcon: layer.baseAssetIcon, + quotedAssetIcon: layer.quotedAssetIcon + } + exchangeMarkets.set(exchangeMarket.exchangeName + '-' + exchangeMarket.marketName, exchangeMarket) + } + } + } + + drawTab(0, 0, exchangeMarkets.size * tabAnimationCounter, 90, thisObject.container) + + const INTER_EXCHANGE_SPACE = 60 + const INTER_MARKET_SPACE = -100 + + if (tabAnimationStatus === 'Open') { + drawMarketNames() + } + + function drawMarketNames() { + exchangeMarkets.forEach((exchangeMarket, i) => { + browserCanvasContext.save() + browserCanvasContext.translate(position.x, position.y) + browserCanvasContext.rotate(-Math.PI / 2) + + let xOffSet = -80 + + icon = exchangeMarket.exchangeIcon + + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + browserCanvasContext.drawImage( + icon, + -20 + xOffSet, + -43, + imageSize, + imageSize) + } + } + + printLabel(exchangeMarket.exchangeName, -5 + xOffSet, -30, opacity, fontSize, UI_COLOR.GREY) + + position.x = position.x + INTER_EXCHANGE_SPACE + + icon = exchangeMarket.baseAssetIcon + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + browserCanvasContext.drawImage( + icon, + -20 + xOffSet, + -22, + imageSize, + imageSize) + } + } + + printLabel(exchangeMarket.marketName, -5 + xOffSet, -10, opacity, fontSize, UI_COLOR.GREY) + + icon = exchangeMarket.quotedAssetIcon + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + browserCanvasContext.drawImage( + icon, + +50 + xOffSet, + -22, + imageSize, + imageSize) + } + } + + position.x = position.x + INTER_MARKET_SPACE + + browserCanvasContext.restore() + }) + } + + function drawTab(x, y, width, height, container) { + const GRADIENT = 0 + const X_OFFSET = -3 + const Y_OFFSET = 13 + const TAB_CORNERS_RADIUS = 5 + + let point = { + x: x, + y: y + } + point = transformThisPoint(point, container) + + let point1 = { + x: point.x + X_OFFSET, + y: point.y + Y_OFFSET } - imagePosition = transformThisPoint(imagePosition, thisObject.container) - imagePosition = thisObject.fitFunction(imagePosition, true) + let point2 = { + x: point.x + X_OFFSET, + y: point.y + height + Y_OFFSET + } - browserCanvasContext.drawImage( - icon, - imagePosition.x - imageSize / 2, - imagePosition.y - imageSize / 2, - imageSize, - imageSize) - } + let point3 = { + x: point.x - width + X_OFFSET, + y: point.y + height - GRADIENT + Y_OFFSET + } + + let point4 = { + x: point.x - width + X_OFFSET, + y: point.y + GRADIENT + Y_OFFSET + } + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.arc(point3.x, point3.y - TAB_CORNERS_RADIUS, TAB_CORNERS_RADIUS, 0.5 * Math.PI, 1.0 * Math.PI) + // browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.arc(point4.x, point4.y + TAB_CORNERS_RADIUS, TAB_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI) + browserCanvasContext.closePath() + browserCanvasContext.lineWidth = 1 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + '' + browserCanvasContext.stroke() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + '' + browserCanvasContext.fill() } - } - } - } - - function drawForeground () { - if (thisObject.container.frame.isInViewPort()) { - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1] - timelineChart.drawForeground() - } - - if (drawScales === true) { - if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.drawForeground() } - if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.drawForeground() } - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawForeground() } - } - - drawLabel() - thisObject.edgeEditor.drawForeground() - } - } - - function drawLabel () { - if (thisObject.payload.node === undefined) { return } - if (thisObject.payload === undefined) { return } - /* Draw Title Above the Container */ - let position = { - x: 0, - y: 0 - } - let imageSize = 13 - let fontSize = 15 - let opacity = 1 - let icon = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) - - position = transformThisPoint(position, thisObject.container) - - let label = thisObject.payload.node.name - let description = loadPropertyFromNodeConfig(thisObject.payload, 'description') - - if (description !== undefined) { - label = description - } - printLabel(label, position.x + 20, position.y - 10, opacity, fontSize) - - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - browserCanvasContext.drawImage( - icon, position.x + 5, - position.y - 22, - imageSize, - imageSize) - } } - imageSize = 13 - fontSize = 15 - let exchangeMarkets = new Map() - - for (let i = 0; i < thisObject.timelineCharts.length; i++) { - let timelinechart = thisObject.timelineCharts[i] - if (timelinechart.layersManager !== undefined) { - for (let j = 0; j < timelinechart.layersManager.layers.length; j++) { - let layer = timelinechart.layersManager.layers[j] - - exchangeMarket = { - exchangeName: layer.exchange.name, - marketName: layer.market, - exchangeIcon: layer.exchangeIcon, - baseAssetIcon: layer.baseAssetIcon, - quotedAssetIcon: layer.quotedAssetIcon - } - exchangeMarkets.set(exchangeMarket.exchangeName + '-' + exchangeMarket.marketName, exchangeMarket) - } - } - } - - drawTab(0, 0, exchangeMarkets.size * tabAnimationCounter, 90, thisObject.container) - - const INTER_EXCHANGE_SPACE = 60 - const INTER_MARKET_SPACE = -100 - - if (tabAnimationStatus === 'Open') { - drawMarketNames() - } - - function drawMarketNames () { - exchangeMarkets.forEach((exchangeMarket, i) => { - browserCanvasContext.save() - browserCanvasContext.translate(position.x, position.y) - browserCanvasContext.rotate(-Math.PI / 2) - - let xOffSet = -80 - - icon = exchangeMarket.exchangeIcon - - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - browserCanvasContext.drawImage( - icon, - -20 + xOffSet, - -43, - imageSize, - imageSize) - } + function recalculateCoordinateSystem() { + let minValue = { + x: MIN_PLOTABLE_DATE.valueOf(), + y: 0 } - printLabel(exchangeMarket.exchangeName, -5 + xOffSet, -30, opacity, fontSize, UI_COLOR.GREY) - - position.x = position.x + INTER_EXCHANGE_SPACE - - icon = exchangeMarket.baseAssetIcon - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - browserCanvasContext.drawImage( - icon, - -20 + xOffSet, - -22, - imageSize, - imageSize) - } + let maxValue = { + x: MAX_PLOTABLE_DATE.valueOf(), + y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 } - printLabel(exchangeMarket.marketName, -5 + xOffSet, -10, opacity, fontSize, UI_COLOR.GREY) - - icon = exchangeMarket.quotedAssetIcon - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - browserCanvasContext.drawImage( - icon, - +50 + xOffSet, - -22, - imageSize, - imageSize) - } - } - - position.x = position.x + INTER_MARKET_SPACE - - browserCanvasContext.restore() - }) + timeMachineCoordinateSystem.initialize( + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ) } - - function drawTab (x, y, width, height, container) { - const GRADIENT = 0 - const X_OFFSET = -3 - const Y_OFFSET = 13 - const TAB_CORNERS_RADIUS = 5 - - let point = { - x: x, - y: y - } - point = transformThisPoint(point, container) - - let point1 = { - x: point.x + X_OFFSET, - y: point.y + Y_OFFSET - } - - let point2 = { - x: point.x + X_OFFSET, - y: point.y + height + Y_OFFSET - } - - let point3 = { - x: point.x - width + X_OFFSET, - y: point.y + height - GRADIENT + Y_OFFSET - } - - let point4 = { - x: point.x - width + X_OFFSET, - y: point.y + GRADIENT + Y_OFFSET - } - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.arc(point3.x, point3.y - TAB_CORNERS_RADIUS, TAB_CORNERS_RADIUS, 0.5 * Math.PI, 1.0 * Math.PI) - // browserCanvasContext.lineTo(point4.x, point4.y) - browserCanvasContext.arc(point4.x, point4.y + TAB_CORNERS_RADIUS, TAB_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI) - browserCanvasContext.closePath() - browserCanvasContext.lineWidth = 1 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + '' - browserCanvasContext.stroke() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + '' - browserCanvasContext.fill() - } - } - - function recalculateCoordinateSystem () { - let minValue = { - x: MIN_PLOTABLE_DATE.valueOf(), - y: 0 - } - - let maxValue = { - x: MAX_PLOTABLE_DATE.valueOf(), - y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 - } - - timeMachineCoordinateSystem.initialize( - minValue, - maxValue, - thisObject.container.frame.width, - thisObject.container.frame.height - ) - } } diff --git a/ChartingSpace/TimelineChart.js b/ChartingSpace/TimelineChart.js index d270d7b9f..fffa40ad0 100644 --- a/ChartingSpace/TimelineChart.js +++ b/ChartingSpace/TimelineChart.js @@ -1,424 +1,424 @@ -function newTimelineChart () { - const MODULE_NAME = 'Timeline Chart' - const INFO_LOG = false - const INTENSIVE_LOG = false - const ERROR_LOG = true - let logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newTimelineChart() { + const MODULE_NAME = 'Timeline Chart' + const INFO_LOG = false + const INTENSIVE_LOG = false + const ERROR_LOG = true + let logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let timeFrame = INITIAL_TIME_PERIOD - let datetime = NEW_SESSION_INITIAL_DATE + let timeFrame = INITIAL_TIME_PERIOD + let datetime = NEW_SESSION_INITIAL_DATE - let thisObject = { - container: undefined, - fitFunction: undefined, - rateScale: undefined, - timeFrameScale: undefined, - payload: undefined, - layersManager: undefined, - plotterManager: undefined, - upstreamTimeFrame: undefined, - setDatetime: setDatetime, - setTimeFrame: setTimeFrame, - physics: physics, - draw: draw, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - let timeMachineCoordinateSystem - let timelineChartCoordinateSystem = newCoordinateSystem() - timelineChartCoordinateSystem.name = 'TIMELINE CHART' - - let coordinateSystem - - let layersPanel - let layersPanelHandle - - let onMouseOverEventSuscriptionId - let onMouseNotOverEventSuscriptionId - let rateScaleUpstreamEventSuscriptionId - let rateScaleMouseOverEventSuscriptionId - let timeFrameScaleEventSuscriptionId - let timeFrameScaleMouseOverEventSuscriptionId - let scaleChangedEventSubscriptionId - - let drawScales = false - let mouse = { - position: { - x: 0, - y: 0 - } - } - - setupContainer() - return thisObject - - function setupContainer () { - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.detectMouseOver = true - } - - function finalize () { - timeMachineCoordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId) - - if (thisObject.layersManager !== undefined) { - finalizeLayersManager() + let thisObject = { + container: undefined, + fitFunction: undefined, + rateScale: undefined, + timeFrameScale: undefined, + payload: undefined, + layersManager: undefined, + plotterManager: undefined, + upstreamTimeFrame: undefined, + setDatetime: setDatetime, + setTimeFrame: setTimeFrame, + physics: physics, + draw: draw, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - if (thisObject.rateScale !== undefined) { - finalizeRateScale() - } + let timeMachineCoordinateSystem + let timelineChartCoordinateSystem = newCoordinateSystem() + timelineChartCoordinateSystem.name = 'TIMELINE CHART' - if (thisObject.timeFrameScale !== undefined) { - finalizeTimeFrameScale() - } + let coordinateSystem - thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSuscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined + let layersPanel + let layersPanelHandle - mouse = undefined - logger = undefined + let onMouseOverEventSuscriptionId + let onMouseNotOverEventSuscriptionId + let rateScaleUpstreamEventSuscriptionId + let rateScaleMouseOverEventSuscriptionId + let timeFrameScaleEventSuscriptionId + let timeFrameScaleMouseOverEventSuscriptionId + let scaleChangedEventSubscriptionId - timeMachineCoordinateSystem = undefined - timelineChartCoordinateSystem.finalize() - timelineChartCoordinateSystem = undefined - coordinateSystem = undefined - layersPanel = undefined - layersPanelHandle = undefined - } - - function finalizeLayersManager () { - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.finalize() - } - thisObject.plotterManager = undefined - thisObject.layersManager = undefined - - canvas.panelsSpace.destroyPanel(layersPanelHandle) - } - - function finalizeTimeFrameScale () { - if (thisObject.timeFrameScale === undefined) { return } - - thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleEventSuscriptionId) - thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleMouseOverEventSuscriptionId) - thisObject.timeFrameScale.finalize() - thisObject.timeFrameScale = undefined - if (thisObject.upstreamTimeFrame !== undefined) { - timeFrame = thisObject.upstreamTimeFrame - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.setTimeFrame(timeFrame) - } - } - } - - function finalizeRateScale () { - if (thisObject.rateScale === undefined) { return } - - thisObject.rateScale.container.eventHandler.stopListening(rateScaleMouseOverEventSuscriptionId) - thisObject.container.parentContainer.eventHandler.stopListening(rateScaleUpstreamEventSuscriptionId) - thisObject.rateScale.finalize() - thisObject.rateScale = undefined - - /* Resets the local container with the dimessions of its parent, the Time Machine */ - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - thisObject.container.frame.height = thisObject.container.parentContainer.frame.height - thisObject.container.frame.width = thisObject.container.parentContainer.frame.width - } - - function initialize (pTimeMachineCoordinateSystem, pTimeFrame) { - /* We load the logow we will need for the background. */ - - timeMachineCoordinateSystem = pTimeMachineCoordinateSystem - coordinateSystem = timeMachineCoordinateSystem - initializeCoordinateSystem() - - timeFrame = pTimeFrame - - onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - scaleChangedEventSubscriptionId = timeMachineCoordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) - } - - function initializeCoordinateSystem () { - let minValue = { - x: timeMachineCoordinateSystem.min.x, - y: 0 - } - - let maxValue = { - x: timeMachineCoordinateSystem.max.x, - y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 - } - - if (thisObject.rateScale !== undefined) { - minValue.y = thisObject.rateScale.minValue - maxValue.y = thisObject.rateScale.maxValue - } - - timelineChartCoordinateSystem.initialize( - minValue, - maxValue, - thisObject.container.frame.width, - thisObject.container.frame.height - ) - } - - function initializeLayersManager () { - let owner = thisObject.payload.node.payload.parentNode.id // The real owner is the Time Machine - layersPanelHandle = canvas.panelsSpace.createNewPanel('Layers Panel', undefined, owner) - thisObject.layersManager = canvas.panelsSpace.getPanel(layersPanelHandle) - thisObject.layersManager.payload = thisObject.payload.node.layersManager.payload - thisObject.layersManager.initialize() - - /* Initialize the Plotter Manager */ - thisObject.plotterManager = newPlottersManager() - - thisObject.plotterManager.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true) - - thisObject.plotterManager.container.frame.position.x = 0 - thisObject.plotterManager.container.frame.position.y = 0 - - thisObject.plotterManager.fitFunction = thisObject.fitFunction - thisObject.plotterManager.payload = thisObject.payload - thisObject.plotterManager.initialize(thisObject.layersManager) - thisObject.plotterManager.setTimeFrame(timeFrame) - thisObject.plotterManager.setDatetime(datetime) - thisObject.plotterManager.setCoordinateSystem(coordinateSystem) - } - - function initializeRateScale () { - thisObject.rateScale = newRateScale() - thisObject.rateScale.fitFunction = thisObject.fitFunction - thisObject.rateScale.payload = thisObject.payload.node.rateScale.payload - - rateScaleMouseOverEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('onMouseOverScale', rateScaleMouseOver) - thisObject.rateScale.initialize(timelineChartCoordinateSystem, thisObject.container.parentContainer, thisObject.container) - - function rateScaleMouseOver (event) { - thisObject.container.eventHandler.raiseEvent('onChildrenMouseOver', event) - } - } - - function initializeTimeFrameScale () { - thisObject.timeFrameScale = newTimeFrameScale() - thisObject.timeFrameScale.fitFunction = thisObject.fitFunction - thisObject.timeFrameScale.payload = thisObject.payload.node.timeFrameScale.payload - - timeFrameScaleEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('Time Frame Value Changed', timeFrameScaleValueChanged) - timeFrameScaleMouseOverEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('onMouseOverScale', timeFrameScaleMouseOver) - thisObject.timeFrameScale.initialize(thisObject.container.parentContainer) - - function timeFrameScaleValueChanged (event) { - let currentTimeFrame = timeFrame - timeFrame = event.timeFrame - if (timeFrame !== currentTimeFrame) { - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.setTimeFrame(timeFrame) + let drawScales = false + let mouse = { + position: { + x: 0, + y: 0 } - } } - function timeFrameScaleMouseOver (event) { - thisObject.container.eventHandler.raiseEvent('onChildrenMouseOver', event) - } - } + setupContainer() + return thisObject - function onScaleChanged (event) { - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.onUpstreamScaleChanged(event) - } - timelineChartCoordinateSystem.min.x = timeMachineCoordinateSystem.min.x - timelineChartCoordinateSystem.max.x = timeMachineCoordinateSystem.max.x - timelineChartCoordinateSystem.maxHeight = timeMachineCoordinateSystem.maxHeight - timelineChartCoordinateSystem.maxWidth = timeMachineCoordinateSystem.maxWidth - timelineChartCoordinateSystem.autoMinXScale = timeMachineCoordinateSystem.autoMinXScale - timelineChartCoordinateSystem.autoMaxXScale = timeMachineCoordinateSystem.autoMaxXScale - timelineChartCoordinateSystem.recalculateScale() - } - - function setTimeFrame (pTimeFrame) { - timeFrame = pTimeFrame - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.setTimeFrame(timeFrame) - } - } - - function setDatetime (pDatetime) { - datetime = pDatetime - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.setDatetime(datetime) - } - } - - function onMouseOver (event) { - /* This event gets to the timelinechart container because it inherits it from the time machine container, which is the one raising Mouse Over and Mouse not Over Events to its children. */ - drawScales = true - - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.onMouseOverSomeTimeMachineContainer(event) + function setupContainer() { + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.detectMouseOver = true } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.onMouseOverSomeTimeMachineContainer(event) - } + function finalize() { + timeMachineCoordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId) - mouse.position.x = event.x - mouse.position.y = event.y - } - - function onMouseNotOver (event) { - /* This event is inherited from the Time Machine */ - drawScales = false - - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.visible = false - } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.visible = false - } - } - - function getContainer (point, purpose) { - let container - - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { - container = thisObject.rateScale.getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - return container + if (thisObject.layersManager !== undefined) { + finalizeLayersManager() } - } - } - if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { - container = thisObject.timeFrameScale.getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - return container + if (thisObject.rateScale !== undefined) { + finalizeRateScale() } - } - } - return container - } - - function physics () { - thisObjectPhysics() - childrenPhysics() - syncWithDesignerScales() - syncWithDesignerLayersManager() - } - - function thisObjectPhysics () { - /* Only if the plotter manager has some layer turned on, we will pass the min and max upstream. */ - if (thisObject.plotterManager !== undefined && thisObject.plotterManager.connectors.length > 0) { - timelineChartCoordinateSystem.reportParentXValue(timeMachineCoordinateSystem.min.x, timeMachineCoordinateSystem.max.x) - timelineChartCoordinateSystem.physics() - - timeMachineCoordinateSystem.reportXValue(timelineChartCoordinateSystem.childrenMin.x) - timeMachineCoordinateSystem.reportXValue(timelineChartCoordinateSystem.childrenMax.x) - } - } - - function syncWithDesignerLayersManager () { - if (thisObject.payload.node === undefined) { - finalizeLayersManager() - return - } - - if (thisObject.payload.node.layersManager === undefined && thisObject.layersManager !== undefined) { - finalizeLayersManager() - } - if (thisObject.payload.node.layersManager !== undefined && thisObject.layersManager === undefined) { - initializeLayersManager() - } - } - - function syncWithDesignerScales () { - if (thisObject.payload.node === undefined) { - finalizeRateScale() - finalizeTimeFrameScale() - return - } - if (thisObject.payload.node.rateScale === undefined && thisObject.rateScale !== undefined) { - finalizeRateScale() - coordinateSystem = timeMachineCoordinateSystem - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.setCoordinateSystem(coordinateSystem) - } - } - if (thisObject.payload.node.rateScale !== undefined && thisObject.rateScale === undefined) { - initializeRateScale() - coordinateSystem = timelineChartCoordinateSystem - if (thisObject.plotterManager !== undefined) { - thisObject.plotterManager.setCoordinateSystem(coordinateSystem) - } - } - if (thisObject.payload.node.timeFrameScale === undefined && thisObject.timeFrameScale !== undefined) { - finalizeTimeFrameScale() - } - if (thisObject.payload.node.timeFrameScale !== undefined && thisObject.timeFrameScale === undefined) { - initializeTimeFrameScale() - } - } - - function childrenPhysics () { - if (thisObject.rateScale !== undefined) { - thisObject.rateScale.layersOn = thisObject.plotterManager.connectors.length - thisObject.rateScale.physics() - } - if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.layersOn = thisObject.plotterManager.connectors.length - thisObject.timeFrameScale.physics() - } - } - - function drawBackground () { - if (thisObject.container.frame.isInViewPort()) { - if (drawScales === true) { - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawBackground() } - } - drawChartsBackground() - if (thisObject.plotterManager !== undefined) { - let elementsPlotted = thisObject.plotterManager.draw() if (thisObject.timeFrameScale !== undefined) { - thisObject.timeFrameScale.adjustTimeFrame(elementsPlotted) - } else { - return elementsPlotted + finalizeTimeFrameScale() } - } - } - } - function draw () { - if (thisObject.container.frame.isInViewPort()) { - if (drawScales === true) { - if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.draw() } - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.draw() } - } - } - } + thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSuscriptionId) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined - function drawForeground () { - if (thisObject.container.frame.isInViewPort()) { - if (drawScales === true) { - if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.drawForeground() } - if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawForeground() } - } - } - } + mouse = undefined + logger = undefined - function drawChartsBackground () { - drawContainerBackground(thisObject.container, UI_COLOR.WHITE, 0, thisObject.fitFunction) - } + timeMachineCoordinateSystem = undefined + timelineChartCoordinateSystem.finalize() + timelineChartCoordinateSystem = undefined + coordinateSystem = undefined + layersPanel = undefined + layersPanelHandle = undefined + } + + function finalizeLayersManager() { + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.finalize() + } + thisObject.plotterManager = undefined + thisObject.layersManager = undefined + + canvas.panelsSpace.destroyPanel(layersPanelHandle) + } + + function finalizeTimeFrameScale() { + if (thisObject.timeFrameScale === undefined) { return } + + thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleEventSuscriptionId) + thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleMouseOverEventSuscriptionId) + thisObject.timeFrameScale.finalize() + thisObject.timeFrameScale = undefined + if (thisObject.upstreamTimeFrame !== undefined) { + timeFrame = thisObject.upstreamTimeFrame + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.setTimeFrame(timeFrame) + } + } + } + + function finalizeRateScale() { + if (thisObject.rateScale === undefined) { return } + + thisObject.rateScale.container.eventHandler.stopListening(rateScaleMouseOverEventSuscriptionId) + thisObject.container.parentContainer.eventHandler.stopListening(rateScaleUpstreamEventSuscriptionId) + thisObject.rateScale.finalize() + thisObject.rateScale = undefined + + /* Resets the local container with the dimessions of its parent, the Time Machine */ + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + thisObject.container.frame.height = thisObject.container.parentContainer.frame.height + thisObject.container.frame.width = thisObject.container.parentContainer.frame.width + } + + function initialize(pTimeMachineCoordinateSystem, pTimeFrame) { + /* We load the logow we will need for the background. */ + + timeMachineCoordinateSystem = pTimeMachineCoordinateSystem + coordinateSystem = timeMachineCoordinateSystem + initializeCoordinateSystem() + + timeFrame = pTimeFrame + + onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + scaleChangedEventSubscriptionId = timeMachineCoordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) + } + + function initializeCoordinateSystem() { + let minValue = { + x: timeMachineCoordinateSystem.min.x, + y: 0 + } + + let maxValue = { + x: timeMachineCoordinateSystem.max.x, + y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 + } + + if (thisObject.rateScale !== undefined) { + minValue.y = thisObject.rateScale.minValue + maxValue.y = thisObject.rateScale.maxValue + } + + timelineChartCoordinateSystem.initialize( + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ) + } + + function initializeLayersManager() { + let owner = thisObject.payload.node.payload.parentNode.id // The real owner is the Time Machine + layersPanelHandle = canvas.panelsSpace.createNewPanel('Layers Panel', undefined, owner) + thisObject.layersManager = canvas.panelsSpace.getPanel(layersPanelHandle) + thisObject.layersManager.payload = thisObject.payload.node.layersManager.payload + thisObject.layersManager.initialize() + + /* Initialize the Plotter Manager */ + thisObject.plotterManager = newPlottersManager() + + thisObject.plotterManager.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true) + + thisObject.plotterManager.container.frame.position.x = 0 + thisObject.plotterManager.container.frame.position.y = 0 + + thisObject.plotterManager.fitFunction = thisObject.fitFunction + thisObject.plotterManager.payload = thisObject.payload + thisObject.plotterManager.initialize(thisObject.layersManager) + thisObject.plotterManager.setTimeFrame(timeFrame) + thisObject.plotterManager.setDatetime(datetime) + thisObject.plotterManager.setCoordinateSystem(coordinateSystem) + } + + function initializeRateScale() { + thisObject.rateScale = newRateScale() + thisObject.rateScale.fitFunction = thisObject.fitFunction + thisObject.rateScale.payload = thisObject.payload.node.rateScale.payload + + rateScaleMouseOverEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('onMouseOverScale', rateScaleMouseOver) + thisObject.rateScale.initialize(timelineChartCoordinateSystem, thisObject.container.parentContainer, thisObject.container) + + function rateScaleMouseOver(event) { + thisObject.container.eventHandler.raiseEvent('onChildrenMouseOver', event) + } + } + + function initializeTimeFrameScale() { + thisObject.timeFrameScale = newTimeFrameScale() + thisObject.timeFrameScale.fitFunction = thisObject.fitFunction + thisObject.timeFrameScale.payload = thisObject.payload.node.timeFrameScale.payload + + timeFrameScaleEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('Time Frame Value Changed', timeFrameScaleValueChanged) + timeFrameScaleMouseOverEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('onMouseOverScale', timeFrameScaleMouseOver) + thisObject.timeFrameScale.initialize(thisObject.container.parentContainer) + + function timeFrameScaleValueChanged(event) { + let currentTimeFrame = timeFrame + timeFrame = event.timeFrame + if (timeFrame !== currentTimeFrame) { + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.setTimeFrame(timeFrame) + } + } + } + + function timeFrameScaleMouseOver(event) { + thisObject.container.eventHandler.raiseEvent('onChildrenMouseOver', event) + } + } + + function onScaleChanged(event) { + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.onUpstreamScaleChanged(event) + } + timelineChartCoordinateSystem.min.x = timeMachineCoordinateSystem.min.x + timelineChartCoordinateSystem.max.x = timeMachineCoordinateSystem.max.x + timelineChartCoordinateSystem.maxHeight = timeMachineCoordinateSystem.maxHeight + timelineChartCoordinateSystem.maxWidth = timeMachineCoordinateSystem.maxWidth + timelineChartCoordinateSystem.autoMinXScale = timeMachineCoordinateSystem.autoMinXScale + timelineChartCoordinateSystem.autoMaxXScale = timeMachineCoordinateSystem.autoMaxXScale + timelineChartCoordinateSystem.recalculateScale() + } + + function setTimeFrame(pTimeFrame) { + timeFrame = pTimeFrame + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.setTimeFrame(timeFrame) + } + } + + function setDatetime(pDatetime) { + datetime = pDatetime + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.setDatetime(datetime) + } + } + + function onMouseOver(event) { + /* This event gets to the timelinechart container because it inherits it from the time machine container, which is the one raising Mouse Over and Mouse not Over Events to its children. */ + drawScales = true + + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.onMouseOverSomeTimeMachineContainer(event) + } + + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.onMouseOverSomeTimeMachineContainer(event) + } + + mouse.position.x = event.x + mouse.position.y = event.y + } + + function onMouseNotOver(event) { + /* This event is inherited from the Time Machine */ + drawScales = false + + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.visible = false + } + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.visible = false + } + } + + function getContainer(point, purpose) { + let container + + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { + container = thisObject.rateScale.getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + return container + } + } + } + + if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { + container = thisObject.timeFrameScale.getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + return container + } + } + } + + return container + } + + function physics() { + thisObjectPhysics() + childrenPhysics() + syncWithDesignerScales() + syncWithDesignerLayersManager() + } + + function thisObjectPhysics() { + /* Only if the plotter manager has some layer turned on, we will pass the min and max upstream. */ + if (thisObject.plotterManager !== undefined && thisObject.plotterManager.connectors.length > 0) { + timelineChartCoordinateSystem.reportParentXValue(timeMachineCoordinateSystem.min.x, timeMachineCoordinateSystem.max.x) + timelineChartCoordinateSystem.physics() + + timeMachineCoordinateSystem.reportXValue(timelineChartCoordinateSystem.childrenMin.x) + timeMachineCoordinateSystem.reportXValue(timelineChartCoordinateSystem.childrenMax.x) + } + } + + function syncWithDesignerLayersManager() { + if (thisObject.payload.node === undefined) { + finalizeLayersManager() + return + } + + if (thisObject.payload.node.layersManager === undefined && thisObject.layersManager !== undefined) { + finalizeLayersManager() + } + if (thisObject.payload.node.layersManager !== undefined && thisObject.layersManager === undefined) { + initializeLayersManager() + } + } + + function syncWithDesignerScales() { + if (thisObject.payload.node === undefined) { + finalizeRateScale() + finalizeTimeFrameScale() + return + } + if (thisObject.payload.node.rateScale === undefined && thisObject.rateScale !== undefined) { + finalizeRateScale() + coordinateSystem = timeMachineCoordinateSystem + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.setCoordinateSystem(coordinateSystem) + } + } + if (thisObject.payload.node.rateScale !== undefined && thisObject.rateScale === undefined) { + initializeRateScale() + coordinateSystem = timelineChartCoordinateSystem + if (thisObject.plotterManager !== undefined) { + thisObject.plotterManager.setCoordinateSystem(coordinateSystem) + } + } + if (thisObject.payload.node.timeFrameScale === undefined && thisObject.timeFrameScale !== undefined) { + finalizeTimeFrameScale() + } + if (thisObject.payload.node.timeFrameScale !== undefined && thisObject.timeFrameScale === undefined) { + initializeTimeFrameScale() + } + } + + function childrenPhysics() { + if (thisObject.rateScale !== undefined) { + thisObject.rateScale.layersOn = thisObject.plotterManager.connectors.length + thisObject.rateScale.physics() + } + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.layersOn = thisObject.plotterManager.connectors.length + thisObject.timeFrameScale.physics() + } + } + + function drawBackground() { + if (thisObject.container.frame.isInViewPort()) { + if (drawScales === true) { + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawBackground() } + } + drawChartsBackground() + if (thisObject.plotterManager !== undefined) { + let elementsPlotted = thisObject.plotterManager.draw() + if (thisObject.timeFrameScale !== undefined) { + thisObject.timeFrameScale.adjustTimeFrame(elementsPlotted) + } else { + return elementsPlotted + } + } + } + } + + function draw() { + if (thisObject.container.frame.isInViewPort()) { + if (drawScales === true) { + if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.draw() } + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.draw() } + } + } + } + + function drawForeground() { + if (thisObject.container.frame.isInViewPort()) { + if (drawScales === true) { + if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.drawForeground() } + if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawForeground() } + } + } + } + + function drawChartsBackground() { + drawContainerBackground(thisObject.container, UI_COLOR.WHITE, 0, thisObject.fitFunction) + } } diff --git a/ChartingSpace/Viewport.js b/ChartingSpace/Viewport.js index 5bd837de8..57d787c6d 100644 --- a/ChartingSpace/Viewport.js +++ b/ChartingSpace/Viewport.js @@ -1,421 +1,421 @@ -function newViewport () { - const MODULE_NAME = 'Viewport' +function newViewport() { + const MODULE_NAME = 'Viewport' - const MIN_ZOOM_LEVEL = 0 - const MAX_ZOOM_LEVEL = 500 + const MIN_ZOOM_LEVEL = 0 + const MAX_ZOOM_LEVEL = 500 - let ANIMATION_INCREMENT = 0.25 - let ANIMATION_STEPS = 5 + let ANIMATION_INCREMENT = 0.25 + let ANIMATION_STEPS = 5 - let TOP_MARGIN = 40 + TOP_SPACE_HEIGHT - let BOTTOM_MARGIN = 42 + COCKPIT_SPACE_HEIGHT - let LEFT_MARGIN = 0 - let RIGHT_MARGIN = 0 - let MARGINS = { - TOP: TOP_MARGIN, - BOTTOM: BOTTOM_MARGIN, - LEFT: LEFT_MARGIN, - RIGHT: RIGHT_MARGIN - } + let TOP_MARGIN = 40 + TOP_SPACE_HEIGHT + let BOTTOM_MARGIN = 42 + COCKPIT_SPACE_HEIGHT + let LEFT_MARGIN = 0 + let RIGHT_MARGIN = 0 + let MARGINS = { + TOP: TOP_MARGIN, + BOTTOM: BOTTOM_MARGIN, + LEFT: LEFT_MARGIN, + RIGHT: RIGHT_MARGIN + } - let thisObject = { - visible: false, - visibleArea: undefined, - width: undefined, - height: undefined, - eventHandler: undefined, - zoomTargetLevel: undefined, - zoomLevel: undefined, - mousePosition: undefined, - margins: MARGINS, - payload: undefined, - zoomAtCenter: zoomAtCenter, - changeZoom: changeZoom, - onMouseWheel: onMouseWheel, - transformThisPoint: transformThisPoint, - unTransformThisPoint: unTransformThisPoint, - isThisPointVisible: isThisPointVisible, - isThisPointInViewport: isThisPointInViewport, - fitIntoVisibleArea: fitIntoVisibleArea, - fitIntoViewport: fitIntoViewport, - displace: displace, - displaceToContainer: displaceToContainer, - physics: physics, - raiseEvents: raiseEvents, - resize: resize, - initialize: initialize, - finalize: finalize - } - let increment = 0.035 - let position = { - x: 0, - y: 0 - } + let thisObject = { + visible: false, + visibleArea: undefined, + width: undefined, + height: undefined, + eventHandler: undefined, + zoomTargetLevel: undefined, + zoomLevel: undefined, + mousePosition: undefined, + margins: MARGINS, + payload: undefined, + zoomAtCenter: zoomAtCenter, + changeZoom: changeZoom, + onMouseWheel: onMouseWheel, + transformThisPoint: transformThisPoint, + unTransformThisPoint: unTransformThisPoint, + isThisPointVisible: isThisPointVisible, + isThisPointInViewport: isThisPointInViewport, + fitIntoVisibleArea: fitIntoVisibleArea, + fitIntoViewport: fitIntoViewport, + displace: displace, + displaceToContainer: displaceToContainer, + physics: physics, + raiseEvents: raiseEvents, + resize: resize, + initialize: initialize, + finalize: finalize + } + let increment = 0.035 + let position = { + x: 0, + y: 0 + } - thisObject.mousePosition = { - x: 0, - y: 0 - } - thisObject.eventHandler = newEventHandler() + thisObject.mousePosition = { + x: 0, + y: 0 + } + thisObject.eventHandler = newEventHandler() -/* Initial default value */ - thisObject.zoomLevel = MIN_ZOOM_LEVEL - thisObject.zoomTargetLevel = Math.round(MIN_ZOOM_LEVEL) - INITIAL_TIME_PERIOD = recalculatePeriod(thisObject.zoomLevel) + /* Initial default value */ + thisObject.zoomLevel = MIN_ZOOM_LEVEL + thisObject.zoomTargetLevel = Math.round(MIN_ZOOM_LEVEL) + INITIAL_TIME_PERIOD = recalculatePeriod(thisObject.zoomLevel) - let overrideMousePositionCounter = 0 + let overrideMousePositionCounter = 0 - return thisObject + return thisObject - function finalize () { - thisObject.eventHandler.finalize() - thisObject.payload = undefined - thisObject = undefined - } + function finalize() { + thisObject.eventHandler.finalize() + thisObject.payload = undefined + thisObject = undefined + } - function initialize () { - if (thisObject.payload !== undefined) { - /* Read the position from the frame structure */ + function initialize() { + if (thisObject.payload !== undefined) { + /* Read the position from the frame structure */ - let frame = { - position: { - x: 0, - y: 0 + let frame = { + position: { + x: 0, + y: 0 + } + } + loadFrame(thisObject.payload, frame) + if (!isNaN(frame.position.x)) { + position.x = frame.position.x + } + if (!isNaN(frame.position.y)) { + position.y = frame.position.y + } } - } - loadFrame(thisObject.payload, frame) - if (!isNaN(frame.position.x)) { - position.x = frame.position.x - } - if (!isNaN(frame.position.y)) { - position.y = frame.position.y - } + + resize() + readObjectState() } - resize() - readObjectState() - } + function resize() { + TOP_MARGIN = 40 + TOP_SPACE_HEIGHT + BOTTOM_MARGIN = 42 + browserCanvas.height - COCKPIT_SPACE_POSITION + LEFT_MARGIN = 0 + RIGHT_MARGIN = 0 + MARGINS = { + TOP: TOP_MARGIN, + BOTTOM: BOTTOM_MARGIN, + LEFT: LEFT_MARGIN, + RIGHT: RIGHT_MARGIN + } - function resize () { - TOP_MARGIN = 40 + TOP_SPACE_HEIGHT - BOTTOM_MARGIN = 42 + browserCanvas.height - COCKPIT_SPACE_POSITION - LEFT_MARGIN = 0 - RIGHT_MARGIN = 0 - MARGINS = { - TOP: TOP_MARGIN, - BOTTOM: BOTTOM_MARGIN, - LEFT: LEFT_MARGIN, - RIGHT: RIGHT_MARGIN + thisObject.visibleArea = { + topLeft: { x: LEFT_MARGIN, y: TOP_MARGIN }, + topRight: { x: browserCanvas.width - RIGHT_MARGIN, y: TOP_MARGIN }, + bottomRight: { x: browserCanvas.width - RIGHT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN }, + bottomLeft: { x: LEFT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN } + } + + thisObject.width = thisObject.visibleArea.topRight.x - thisObject.visibleArea.topLeft.x + thisObject.height = thisObject.visibleArea.bottomRight.y - thisObject.visibleArea.topLeft.y + + thisObject.center = { + x: LEFT_MARGIN + thisObject.width / 2, + y: TOP_MARGIN + thisObject.height / 2 + } } - thisObject.visibleArea = { - topLeft: { x: LEFT_MARGIN, y: TOP_MARGIN }, - topRight: { x: browserCanvas.width - RIGHT_MARGIN, y: TOP_MARGIN }, - bottomRight: { x: browserCanvas.width - RIGHT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN}, - bottomLeft: { x: LEFT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN} + function raiseEvents() { + if (thisObject.visible === false) { return } + let event = { + newPosition: position + } + + thisObject.eventHandler.raiseEvent('Position Changed', event) } - thisObject.width = thisObject.visibleArea.topRight.x - thisObject.visibleArea.topLeft.x - thisObject.height = thisObject.visibleArea.bottomRight.y - thisObject.visibleArea.topLeft.y - - thisObject.center = { - x: LEFT_MARGIN + thisObject.width / 2, - y: TOP_MARGIN + thisObject.height / 2 - } - } - - function raiseEvents () { - if (thisObject.visible === false) { return } - let event = { - newPosition: position + function displaceToContainer(container) { + let targetPoint = { + x: -container.frame.position.x - container.frame.width / 2, + y: -container.frame.position.y - container.frame.height / 2 + } + position.x = targetPoint.x + browserCanvas.width / 2 + position.y = targetPoint.y + (COCKPIT_SPACE_POSITION - TOP_SPACE_HEIGHT) / 2 + TOP_SPACE_HEIGHT } - thisObject.eventHandler.raiseEvent('Position Changed', event) - } - - function displaceToContainer (container) { - let targetPoint = { - x: -container.frame.position.x - container.frame.width / 2, - y: -container.frame.position.y - container.frame.height / 2 - } - position.x = targetPoint.x + browserCanvas.width / 2 - position.y = targetPoint.y + (COCKPIT_SPACE_POSITION - TOP_SPACE_HEIGHT) / 2 + TOP_SPACE_HEIGHT - } - - function zoomAtCenter (level) { - thisObject.zoomTargetLevel = Math.round(level) - overrideMousePositionCounter = 50 - ANIMATION_INCREMENT = 0.5 - } - - function mousePositionPhysics () { - if (overrideMousePositionCounter > 0) { - thisObject.mousePosition.x = browserCanvas.width / 2 - thisObject.mousePosition.y = (COCKPIT_SPACE_POSITION - TOP_SPACE_HEIGHT) / 2 + TOP_SPACE_HEIGHT - - overrideMousePositionCounter-- - if (overrideMousePositionCounter < 0) { - overrideMousePositionCounter = 0 - } - } - } - - function physics () { - if (thisObject.visible === false) { return } - mousePositionPhysics() - animationPhysics() - positioningPhysics() - readObjectState() - } - - function positioningPhysics () { - if (thisObject.visible === false) { return } - if (thisObject.payload === undefined) { return } - /* Save the position at the frame lavel */ - let frame = {} - frame.position = position - saveFrame(thisObject.payload, frame) - } - - function animationPhysics () { - if (thisObject.zoomLevel < thisObject.zoomTargetLevel) { - if (thisObject.zoomTargetLevel - thisObject.zoomLevel < ANIMATION_INCREMENT) { - ANIMATION_INCREMENT = Math.round(Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) * 100) / 100 - } - thisObject.zoomLevel = Math.round((thisObject.zoomLevel + ANIMATION_INCREMENT) * 100) / 100 - changeZoom(thisObject.zoomLevel - ANIMATION_INCREMENT, thisObject.zoomLevel) + function zoomAtCenter(level) { + thisObject.zoomTargetLevel = Math.round(level) + overrideMousePositionCounter = 50 + ANIMATION_INCREMENT = 0.5 } - if (thisObject.zoomLevel > thisObject.zoomTargetLevel) { - if (thisObject.zoomLevel - thisObject.zoomTargetLevel < ANIMATION_INCREMENT) { - ANIMATION_INCREMENT = Math.round(Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) * 100) / 100 - } - thisObject.zoomLevel = Math.round((thisObject.zoomLevel - ANIMATION_INCREMENT) * 100) / 100 - changeZoom(thisObject.zoomLevel + ANIMATION_INCREMENT, thisObject.zoomLevel) - } - } + function mousePositionPhysics() { + if (overrideMousePositionCounter > 0) { + thisObject.mousePosition.x = browserCanvas.width / 2 + thisObject.mousePosition.y = (COCKPIT_SPACE_POSITION - TOP_SPACE_HEIGHT) / 2 + TOP_SPACE_HEIGHT - function onMouseWheel (event) { - if (thisObject.visible === false) { return } - if ((event.ctrlKey === true || event.metaKey === true)) { return } - let morePower = 1 - - if (IS_MAC) { - event.delta = event.delta * MAC_AMOUNT_FACTOR + overrideMousePositionCounter-- + if (overrideMousePositionCounter < 0) { + overrideMousePositionCounter = 0 + } + } } - let amount = event.delta - - if (event.buttons === 4) { morePower = 2 } // Mouse wheel pressed. - /* We adjust the sensitivity for Mac Users */ - - if (thisObject.zoomTargetLevel > 10) { - amount = amount * 2 - } - if (thisObject.zoomTargetLevel > 25) { - amount = amount * 3 - } - if (thisObject.zoomTargetLevel > 50) { - amount = amount * 3.5 + function physics() { + if (thisObject.visible === false) { return } + mousePositionPhysics() + animationPhysics() + positioningPhysics() + readObjectState() } - if (thisObject.zoomTargetLevel + amount * morePower > MAX_ZOOM_LEVEL) { - return false - } - if (thisObject.zoomTargetLevel + amount * morePower < MIN_ZOOM_LEVEL) { - return false - } - thisObject.zoomTargetLevel = Math.round(thisObject.zoomTargetLevel + amount * morePower) - - ANIMATION_INCREMENT = Math.round(Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) / ANIMATION_STEPS * 100) / 100 - - let newEvent = { - newLevel: thisObject.zoomTargetLevel, - newPosition: position, - type: undefined, - shiftKey: event.shiftKey + function positioningPhysics() { + if (thisObject.visible === false) { return } + if (thisObject.payload === undefined) { return } + /* Save the position at the frame lavel */ + let frame = {} + frame.position = position + saveFrame(thisObject.payload, frame) } - if (amount > 0) { - newEvent.type = 'Zoom In' - } else { - newEvent.type = 'Zoom Out' + function animationPhysics() { + if (thisObject.zoomLevel < thisObject.zoomTargetLevel) { + if (thisObject.zoomTargetLevel - thisObject.zoomLevel < ANIMATION_INCREMENT) { + ANIMATION_INCREMENT = Math.round(Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) * 100) / 100 + } + thisObject.zoomLevel = Math.round((thisObject.zoomLevel + ANIMATION_INCREMENT) * 100) / 100 + changeZoom(thisObject.zoomLevel - ANIMATION_INCREMENT, thisObject.zoomLevel) + } + + if (thisObject.zoomLevel > thisObject.zoomTargetLevel) { + if (thisObject.zoomLevel - thisObject.zoomTargetLevel < ANIMATION_INCREMENT) { + ANIMATION_INCREMENT = Math.round(Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) * 100) / 100 + } + thisObject.zoomLevel = Math.round((thisObject.zoomLevel - ANIMATION_INCREMENT) * 100) / 100 + changeZoom(thisObject.zoomLevel + ANIMATION_INCREMENT, thisObject.zoomLevel) + } } - thisObject.eventHandler.raiseEvent('Zoom Changed', newEvent) - return true - } + function onMouseWheel(event) { + if (thisObject.visible === false) { return } + if ((event.ctrlKey === true || event.metaKey === true)) { return } + let morePower = 1 - function fitIntoVisibleArea (point) { - let pointCopy = { - x: point.x, - y: point.y + if (IS_MAC) { + event.delta = event.delta * MAC_AMOUNT_FACTOR + } + + let amount = event.delta + + if (event.buttons === 4) { morePower = 2 } // Mouse wheel pressed. + /* We adjust the sensitivity for Mac Users */ + + if (thisObject.zoomTargetLevel > 10) { + amount = amount * 2 + } + if (thisObject.zoomTargetLevel > 25) { + amount = amount * 3 + } + if (thisObject.zoomTargetLevel > 50) { + amount = amount * 3.5 + } + + if (thisObject.zoomTargetLevel + amount * morePower > MAX_ZOOM_LEVEL) { + return false + } + if (thisObject.zoomTargetLevel + amount * morePower < MIN_ZOOM_LEVEL) { + return false + } + thisObject.zoomTargetLevel = Math.round(thisObject.zoomTargetLevel + amount * morePower) + + ANIMATION_INCREMENT = Math.round(Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) / ANIMATION_STEPS * 100) / 100 + + let newEvent = { + newLevel: thisObject.zoomTargetLevel, + newPosition: position, + type: undefined, + shiftKey: event.shiftKey + } + + if (amount > 0) { + newEvent.type = 'Zoom In' + } else { + newEvent.type = 'Zoom Out' + } + + thisObject.eventHandler.raiseEvent('Zoom Changed', newEvent) + return true } - /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ - if (pointCopy.x > thisObject.visibleArea.bottomRight.x + 1) { - pointCopy.x = thisObject.visibleArea.bottomRight.x + 1 + function fitIntoVisibleArea(point) { + let pointCopy = { + x: point.x, + y: point.y + } + + /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ + if (pointCopy.x > thisObject.visibleArea.bottomRight.x + 1) { + pointCopy.x = thisObject.visibleArea.bottomRight.x + 1 + } + + if (pointCopy.x < thisObject.visibleArea.topLeft.x - 1) { + pointCopy.x = thisObject.visibleArea.topLeft.x - 1 + } + + if (pointCopy.y > thisObject.visibleArea.bottomRight.y + 1) { + pointCopy.y = thisObject.visibleArea.bottomRight.y + 1 + } + + if (pointCopy.y < thisObject.visibleArea.topLeft.y - 1) { + pointCopy.y = thisObject.visibleArea.topLeft.y - 1 + } + + return pointCopy } - if (pointCopy.x < thisObject.visibleArea.topLeft.x - 1) { - pointCopy.x = thisObject.visibleArea.topLeft.x - 1 + function fitIntoViewport(point) { + let pointCopy = { + x: point.x, + y: point.y + } + if (pointCopy.y > COCKPIT_SPACE_POSITION) { + pointCopy.y = COCKPIT_SPACE_POSITION + } + return pointCopy } - if (pointCopy.y > thisObject.visibleArea.bottomRight.y + 1) { - pointCopy.y = thisObject.visibleArea.bottomRight.y + 1 - } + function displace(displaceVector, recalculate) { + if (thisObject.visible === false) { return } + position.x = position.x + displaceVector.x + position.y = position.y + displaceVector.y - if (pointCopy.y < thisObject.visibleArea.topLeft.y - 1) { - pointCopy.y = thisObject.visibleArea.topLeft.y - 1 - } - - return pointCopy - } - - function fitIntoViewport (point) { - let pointCopy = { - x: point.x, - y: point.y - } - if (pointCopy.y > COCKPIT_SPACE_POSITION) { - pointCopy.y = COCKPIT_SPACE_POSITION - } - return pointCopy - } - - function displace (displaceVector, recalculate) { - if (thisObject.visible === false) { return } - position.x = position.x + displaceVector.x - position.y = position.y + displaceVector.y - - saveObjectState() - - let event = { - newPosition: position, - recalculate: recalculate - } - - thisObject.eventHandler.raiseEvent('Position Changed', event) - } - - function changeZoom (oldLevel, newLevel) { - if (thisObject.visible === false) { return } - let oldMouse = unTransformThisPoint(thisObject.mousePosition, oldLevel) - let newMouse = transformThisPoint(oldMouse, newLevel) - - position.x = position.x - newMouse.x + thisObject.mousePosition.x - position.y = position.y - newMouse.y + thisObject.mousePosition.y - - saveObjectState() - - thisObject.eventHandler.raiseEvent('Zoom Changed') - } - - function transformThisPoint (point, level) { - if (thisObject.visible === false) { return } - let transformedPoint = { - x: 0, - y: 0 - } - - if (level === undefined) { - transformedPoint.x = point.x * (1 + thisObject.zoomLevel) + position.x - transformedPoint.y = point.y * (1 + thisObject.zoomLevel) + position.y - } else { - transformedPoint.x = point.x * (1 + level) + position.x - transformedPoint.y = point.y * (1 + level) + position.y - } - - return transformedPoint - } - - function unTransformThisPoint (point, level) { - let pointWithoutZoom = { - x: 0, - y: 0 - } - if (level === undefined) { - pointWithoutZoom.x = (point.x - position.x) / (1 + thisObject.zoomLevel) - pointWithoutZoom.y = (point.y - position.y) / (1 + thisObject.zoomLevel) - } else { - pointWithoutZoom.x = (point.x - position.x) / (1 + level) - pointWithoutZoom.y = (point.y - position.y) / (1 + level) - } - - return pointWithoutZoom - } - - function isThisPointVisible (point) { - if (thisObject.visible === false) { return } - if (point.x < thisObject.visibleArea.topLeft.x || point.x > thisObject.visibleArea.bottomRight.x || point.y < thisObject.visibleArea.topLeft.y || point.y > thisObject.visibleArea.bottomRight.y) { - return false - } else { - return true - } - } - - function isThisPointInViewport (point) { - if (thisObject.visible === false) { return } - if (point.y > COCKPIT_SPACE_POSITION) { - return false - } else { - return true - } - } - - function saveObjectState () { - if (thisObject.payload === undefined) { return } - - /* Save the zoom at the node config, so that the user can change it if he wishes to. */ - try { - let config = JSON.parse(thisObject.payload.node.config) - config.zoom = (thisObject.zoomTargetLevel - MIN_ZOOM_LEVEL) / (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) * 100 - config.zoom = config.zoom.toFixed(2) - thisObject.payload.node.config = JSON.stringify(config) - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } - } - - function readObjectState () { - if (thisObject.payload === undefined) { return } - - /* Read the zoom level from the node config */ - try { - let config = JSON.parse(thisObject.payload.node.config) - - if (isNaN(config.zoom) || config.zoom === null || config.zoom === undefined) { saveObjectState() - return - } - config.zoom = config.zoom / 100 * (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) + MIN_ZOOM_LEVEL - if (config.zoom < MIN_ZOOM_LEVEL) { config.zoom = MIN_ZOOM_LEVEL } - if (config.zoom > MAX_ZOOM_LEVEL) { config.zoom = MAX_ZOOM_LEVEL } - if (config.zoom.toFixed(2) !== thisObject.zoomTargetLevel.toFixed(2)) { - newZoomLevel(config.zoom) - } else { + let event = { + newPosition: position, + recalculate: recalculate + } + + thisObject.eventHandler.raiseEvent('Position Changed', event) + } + + function changeZoom(oldLevel, newLevel) { + if (thisObject.visible === false) { return } + let oldMouse = unTransformThisPoint(thisObject.mousePosition, oldLevel) + let newMouse = transformThisPoint(oldMouse, newLevel) + + position.x = position.x - newMouse.x + thisObject.mousePosition.x + position.y = position.y - newMouse.y + thisObject.mousePosition.y + saveObjectState() - } - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. + + thisObject.eventHandler.raiseEvent('Zoom Changed') } - function newZoomLevel (level) { - thisObject.zoomLevel = Math.round(level) - thisObject.zoomTargetLevel = Math.round(level) - INITIAL_TIME_PERIOD = recalculatePeriod(level) - saveObjectState() - ANIMATION_INCREMENT = 0 + function transformThisPoint(point, level) { + if (thisObject.visible === false) { return } + let transformedPoint = { + x: 0, + y: 0 + } - let event = { - newLevel: thisObject.zoomTargetLevel, - newPosition: position, - type: undefined - } - thisObject.eventHandler.raiseEvent('Zoom Changed', event) - return true + if (level === undefined) { + transformedPoint.x = point.x * (1 + thisObject.zoomLevel) + position.x + transformedPoint.y = point.y * (1 + thisObject.zoomLevel) + position.y + } else { + transformedPoint.x = point.x * (1 + level) + position.x + transformedPoint.y = point.y * (1 + level) + position.y + } + + return transformedPoint + } + + function unTransformThisPoint(point, level) { + let pointWithoutZoom = { + x: 0, + y: 0 + } + if (level === undefined) { + pointWithoutZoom.x = (point.x - position.x) / (1 + thisObject.zoomLevel) + pointWithoutZoom.y = (point.y - position.y) / (1 + thisObject.zoomLevel) + } else { + pointWithoutZoom.x = (point.x - position.x) / (1 + level) + pointWithoutZoom.y = (point.y - position.y) / (1 + level) + } + + return pointWithoutZoom + } + + function isThisPointVisible(point) { + if (thisObject.visible === false) { return } + if (point.x < thisObject.visibleArea.topLeft.x || point.x > thisObject.visibleArea.bottomRight.x || point.y < thisObject.visibleArea.topLeft.y || point.y > thisObject.visibleArea.bottomRight.y) { + return false + } else { + return true + } + } + + function isThisPointInViewport(point) { + if (thisObject.visible === false) { return } + if (point.y > COCKPIT_SPACE_POSITION) { + return false + } else { + return true + } + } + + function saveObjectState() { + if (thisObject.payload === undefined) { return } + + /* Save the zoom at the node config, so that the user can change it if he wishes to. */ + try { + let config = JSON.parse(thisObject.payload.node.config) + config.zoom = (thisObject.zoomTargetLevel - MIN_ZOOM_LEVEL) / (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) * 100 + config.zoom = config.zoom.toFixed(2) + thisObject.payload.node.config = JSON.stringify(config) + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } + } + + function readObjectState() { + if (thisObject.payload === undefined) { return } + + /* Read the zoom level from the node config */ + try { + let config = JSON.parse(thisObject.payload.node.config) + + if (isNaN(config.zoom) || config.zoom === null || config.zoom === undefined) { + saveObjectState() + return + } + config.zoom = config.zoom / 100 * (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) + MIN_ZOOM_LEVEL + if (config.zoom < MIN_ZOOM_LEVEL) { config.zoom = MIN_ZOOM_LEVEL } + if (config.zoom > MAX_ZOOM_LEVEL) { config.zoom = MAX_ZOOM_LEVEL } + + if (config.zoom.toFixed(2) !== thisObject.zoomTargetLevel.toFixed(2)) { + newZoomLevel(config.zoom) + } else { + saveObjectState() + } + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } + + function newZoomLevel(level) { + thisObject.zoomLevel = Math.round(level) + thisObject.zoomTargetLevel = Math.round(level) + INITIAL_TIME_PERIOD = recalculatePeriod(level) + saveObjectState() + ANIMATION_INCREMENT = 0 + + let event = { + newLevel: thisObject.zoomTargetLevel, + newPosition: position, + type: undefined + } + thisObject.eventHandler.raiseEvent('Zoom Changed', event) + return true + } } - } } diff --git a/CockpitSpace/AssetBalances.js b/CockpitSpace/AssetBalances.js index 166a68880..afcb65668 100644 --- a/CockpitSpace/AssetBalances.js +++ b/CockpitSpace/AssetBalances.js @@ -1,123 +1,123 @@ -function newAssetalances () { - const MODULE_NAME = 'Asset Balances' +function newAssetalances() { + const MODULE_NAME = 'Asset Balances' - let thisObject = { - visible: true, - container: undefined, - paramsArray: undefined, - setParamsArray: setParamsArray, - physics: physics, - draw: draw, - speedometers: [], - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - - return thisObject - - function finalize () { - for (let i = 0; i < thisObject.speedometers.length; i++) { - let speedometer = thisObject.speedometers[i] - speedometer.finalize() + let thisObject = { + visible: true, + container: undefined, + paramsArray: undefined, + setParamsArray: setParamsArray, + physics: physics, + draw: draw, + speedometers: [], + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - thisObject.container.finalize() - thisObject.container = undefined - thisObject.paramsArray = undefined - } - function initialize () { - for (let i = 0; i < 2; i++) { - let speedometer = newSpeedometer() + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - speedometer.initialize() - speedometer.container.connectToParent(thisObject.container) - speedometer.container.frame.position.x = thisObject.container.frame.width / 2 - speedometer.container.frame.position.y = thisObject.container.frame.height * (2 + i * 2) / 5 - thisObject.speedometers.push(speedometer) - } - } + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = false - function getContainer (point, purpose) { - if (thisObject.visible !== true) { return } + return thisObject - let container - for (let i = 0; i < thisObject.speedometers.length; i++) { - container = thisObject.speedometers[i].getContainer(point, purpose) - if (container !== undefined) { - if (container.isForThisPurpose(purpose)) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return container - } + function finalize() { + for (let i = 0; i < thisObject.speedometers.length; i++) { + let speedometer = thisObject.speedometers[i] + speedometer.finalize() } - } + thisObject.container.finalize() + thisObject.container = undefined + thisObject.paramsArray = undefined } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } + function initialize() { + for (let i = 0; i < 2; i++) { + let speedometer = newSpeedometer() - function setParamsArray (paramsArray) { - thisObject.paramsArray = paramsArray - for (let i = 0; i < thisObject.speedometers.length; i++) { - let speedometer = thisObject.speedometers[i] - speedometer.params = paramsArray[i] - } - } - - function physics () { - - } - - function draw () { - if (thisObject.visible !== true) { return } - - for (let i = 0; i < thisObject.speedometers.length; i++) { - let speedometer = thisObject.speedometers[i] - speedometer.draw() + speedometer.initialize() + speedometer.container.connectToParent(thisObject.container) + speedometer.container.frame.position.x = thisObject.container.frame.width / 2 + speedometer.container.frame.position.y = thisObject.container.frame.height * (2 + i * 2) / 5 + thisObject.speedometers.push(speedometer) + } } - drawQuotedAssetalances() - } + function getContainer(point, purpose) { + if (thisObject.visible !== true) { return } - function drawQuotedAssetalances () { - if (thisObject.paramsArray === undefined) { return } + let container + for (let i = 0; i < thisObject.speedometers.length; i++) { + container = thisObject.speedometers[i].getContainer(point, purpose) + if (container !== undefined) { + if (container.isForThisPurpose(purpose)) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return container + } + } + } + } - let fontSize - let label - let xOffset - let yOffset - - const OPACITY = 1 - - /* We put the params.VALUE in the middle */ - - fontSize = 15 - - browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY - - label = 'ASSET BALANCES' - - xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO - yOffset = -45 + 9 - - labelPoint = { - x: 0 - xOffset + (thisObject.paramsArray[1].LEFT_OFFSET - thisObject.paramsArray[0].LEFT_OFFSET) / 2 + thisObject.paramsArray[0].LEFT_OFFSET - 20, - y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2 - yOffset + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } } - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } + function setParamsArray(paramsArray) { + thisObject.paramsArray = paramsArray + for (let i = 0; i < thisObject.speedometers.length; i++) { + let speedometer = thisObject.speedometers[i] + speedometer.params = paramsArray[i] + } + } + + function physics() { + + } + + function draw() { + if (thisObject.visible !== true) { return } + + for (let i = 0; i < thisObject.speedometers.length; i++) { + let speedometer = thisObject.speedometers[i] + speedometer.draw() + } + + drawQuotedAssetalances() + } + + function drawQuotedAssetalances() { + if (thisObject.paramsArray === undefined) { return } + + let fontSize + let label + let xOffset + let yOffset + + const OPACITY = 1 + + /* We put the params.VALUE in the middle */ + + fontSize = 15 + + browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY + + label = 'ASSET BALANCES' + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + yOffset = -45 + 9 + + labelPoint = { + x: 0 - xOffset + (thisObject.paramsArray[1].LEFT_OFFSET - thisObject.paramsArray[0].LEFT_OFFSET) / 2 + thisObject.paramsArray[0].LEFT_OFFSET - 20, + y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2 - yOffset + } + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } } diff --git a/CockpitSpace/FullScreen.js b/CockpitSpace/FullScreen.js index 9fb2717d9..4f0c8e5c8 100644 --- a/CockpitSpace/FullScreen.js +++ b/CockpitSpace/FullScreen.js @@ -1,169 +1,169 @@ -function newFullScreen () { - const MODULE_NAME = 'Fullscreen' +function newFullScreen() { + const MODULE_NAME = 'Fullscreen' - let thisObject = { - visible: true, - container: undefined, - status: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - thisObject.container.isClickeable = true - thisObject.container.detectMouseOver = true - - let selfMouseOverEventSubscriptionId - let selfMouseClickEventSubscriptionId - let selfMouseNotOverEventSubscriptionId - - let isMouseOver = false - let counterTillNextState = 0 - - let layersToTurnOn = [] - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - } - - function initialize () { - thisObject.container.frame.width = 50 - thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - 12 - - selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - - thisObject.status = 'Ready' - } - - function getContainer (point, purpose) { - if (thisObject.visible !== true) { return } - - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - - function onMouseOver (point) { - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - isMouseOver = true - } else { - isMouseOver = false - } - } - - function onMouseNotOver (point) { - isMouseOver = false - } - - function onMouseClick (event) { - if (thisObject.status !== 'On') { - thisObject.status = 'On' - goFullscreen() - CURRENT_TOP_MARGIN = 0 - AT_FULL_SCREEN_MODE = true - } else { - thisObject.status = 'Off' - goOutFullscreen() - CURRENT_TOP_MARGIN = TOP_MARGIN - AT_FULL_SCREEN_MODE = false - } - } - - function goFullscreen () { - if (browserCanvas.requestFullscreen) { - browserCanvas.requestFullscreen() - } else if (browserCanvas.mozRequestFullScreen) { - browserCanvas.mozRequestFullScreen() - } else if (browserCanvas.webkitRequestFullscreen) { - browserCanvas.webkitRequestFullscreen() - } else if (browserCanvas.msRequestFullscreen) { browserCanvas.msRequestFullscreen() } - } - - function goOutFullscreen () { - if (document.exitFullscreen) { - document.exitFullscreen() - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen() - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen() - } else if (document.msExitFullscreen) { document.msExitFullscreen() } - } - - function physics () { - positionPhysics() - } - - function positionPhysics () { - thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width - thisObject.container.frame.position.y = 6 - } - - function draw () { - if (thisObject.visible !== true) { return } - drawBackground() - drawText() - } - - function drawBackground () { - let params = { - cornerRadius: 3, - lineWidth: 0.01, - container: thisObject.container, - borderColor: UI_COLOR.DARK, - castShadow: false, - opacity: 1 + let thisObject = { + visible: true, + container: undefined, + status: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - if (isMouseOver === true) { - params.backgroundColor = UI_COLOR.TURQUOISE - } else { - params.backgroundColor = UI_COLOR.DARK_TURQUOISE + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = false + thisObject.container.isClickeable = true + thisObject.container.detectMouseOver = true + + let selfMouseOverEventSubscriptionId + let selfMouseClickEventSubscriptionId + let selfMouseNotOverEventSubscriptionId + + let isMouseOver = false + let counterTillNextState = 0 + + let layersToTurnOn = [] + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined } - roundedCornersBackground(params) - } + function initialize() { + thisObject.container.frame.width = 50 + thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - 12 - function drawText () { - let fontSize - let label - let xOffset - let yOffset + selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - const OPACITY = 1 - - /* We put the params.VALUE in the middle */ - - fontSize = 15 - - browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY - label = 'FS' - - let labelPoint = { - x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO, - y: thisObject.container.frame.height - 9 + thisObject.status = 'Ready' } - labelPoint = thisObject.container.frame.frameThisPoint(labelPoint) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } + function getContainer(point, purpose) { + if (thisObject.visible !== true) { return } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function onMouseOver(point) { + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + isMouseOver = true + } else { + isMouseOver = false + } + } + + function onMouseNotOver(point) { + isMouseOver = false + } + + function onMouseClick(event) { + if (thisObject.status !== 'On') { + thisObject.status = 'On' + goFullscreen() + CURRENT_TOP_MARGIN = 0 + AT_FULL_SCREEN_MODE = true + } else { + thisObject.status = 'Off' + goOutFullscreen() + CURRENT_TOP_MARGIN = TOP_MARGIN + AT_FULL_SCREEN_MODE = false + } + } + + function goFullscreen() { + if (browserCanvas.requestFullscreen) { + browserCanvas.requestFullscreen() + } else if (browserCanvas.mozRequestFullScreen) { + browserCanvas.mozRequestFullScreen() + } else if (browserCanvas.webkitRequestFullscreen) { + browserCanvas.webkitRequestFullscreen() + } else if (browserCanvas.msRequestFullscreen) { browserCanvas.msRequestFullscreen() } + } + + function goOutFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen() + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen() + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen() + } else if (document.msExitFullscreen) { document.msExitFullscreen() } + } + + function physics() { + positionPhysics() + } + + function positionPhysics() { + thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width + thisObject.container.frame.position.y = 6 + } + + function draw() { + if (thisObject.visible !== true) { return } + drawBackground() + drawText() + } + + function drawBackground() { + let params = { + cornerRadius: 3, + lineWidth: 0.01, + container: thisObject.container, + borderColor: UI_COLOR.DARK, + castShadow: false, + opacity: 1 + } + + if (isMouseOver === true) { + params.backgroundColor = UI_COLOR.TURQUOISE + } else { + params.backgroundColor = UI_COLOR.DARK_TURQUOISE + } + + roundedCornersBackground(params) + } + + function drawText() { + let fontSize + let label + let xOffset + let yOffset + + const OPACITY = 1 + + /* We put the params.VALUE in the middle */ + + fontSize = 15 + + browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY + label = 'FS' + + let labelPoint = { + x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO, + y: thisObject.container.frame.height - 9 + } + labelPoint = thisObject.container.frame.frameThisPoint(labelPoint) + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } } diff --git a/CockpitSpace/Speedometer.js b/CockpitSpace/Speedometer.js index b2e26df1f..7d64af030 100644 --- a/CockpitSpace/Speedometer.js +++ b/CockpitSpace/Speedometer.js @@ -1,265 +1,265 @@ -function newSpeedometer () { - const MODULE_NAME = 'Speedometer' +function newSpeedometer() { + const MODULE_NAME = 'Speedometer' - let thisObject = { - visible: true, - container: undefined, - params: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - - return thisObject - - function finalize () { - thisObject.container.finalize() - thisObject.container = undefined - thisObject.params = undefined - } - - function initialize () { - - } - - function getContainer (point, purpose) { - if (thisObject.visible !== true) { return } - - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - - function physics () { - - } - - function draw () { - if (thisObject.params === undefined) { return } - drawAssetCircle() - } - - function drawAssetCircle () { - const RED_LINE_HIGHT = 2 - const RADIUS = 50 - const OPACITY = 1 - - let centerPoint = { - x: 0, - y: 0 + let thisObject = { + visible: true, + container: undefined, + params: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - centerPoint = thisObject.container.frame.frameThisPoint(centerPoint) + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIUS + RED_LINE_HIGHT, 0 * Math.PI, 2.0 * Math.PI) - browserCanvasContext.closePath() + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = false - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' - browserCanvasContext.fill() + return thisObject - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIUS, 0.0 * Math.PI, 2.0 * Math.PI) - browserCanvasContext.closePath() + function finalize() { + thisObject.container.finalize() + thisObject.container = undefined + thisObject.params = undefined + } - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' - browserCanvasContext.fill() + function initialize() { - /* We draw the circle bar */ + } - const DEFAULT_THICKNESS = 2 - const VALUE_THICKNESS = 8 - const VALUE_BG_THICKNESS = 1 - const BAR_RADIUS = RADIUS * 0.85 + function getContainer(point, purpose) { + if (thisObject.visible !== true) { return } - let BAR_START_ANGLE = 0.85 * Math.PI - let BAR_END_ANGLE = 2.15 * Math.PI - let CURRENT_VALUE_ANGLE = thisObject.params.VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE - let MIN_VALUE_ANGLE = thisObject.params.MIN_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE - let INIT_VALUE_ANGLE = thisObject.params.INIT_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE - let PROFIT_VALUE_ANGLE = CURRENT_VALUE_ANGLE + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } - if (CURRENT_VALUE_ANGLE > INIT_VALUE_ANGLE) { CURRENT_VALUE_ANGLE = INIT_VALUE_ANGLE } - if (CURRENT_VALUE_ANGLE < MIN_VALUE_ANGLE) { CURRENT_VALUE_ANGLE = MIN_VALUE_ANGLE } - if (PROFIT_VALUE_ANGLE > BAR_END_ANGLE) { PROFIT_VALUE_ANGLE = BAR_END_ANGLE } + function physics() { - if ( - thisObject.params.VALUE > 0 && - thisObject.params.ASSET_NAME === thisObject.params.BASE_ASSET && - thisObject.params.POSITION_TAKEN === false - ) { - browserCanvasContext.setLineDash([0, 0]) + } - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, BAR_START_ANGLE, MIN_VALUE_ANGLE) + function draw() { + if (thisObject.params === undefined) { return } + drawAssetCircle() + } - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_BG_THICKNESS - browserCanvasContext.stroke() - browserCanvasContext.closePath() + function drawAssetCircle() { + const RED_LINE_HIGHT = 2 + const RADIUS = 50 + const OPACITY = 1 - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE) + let centerPoint = { + x: 0, + y: 0 + } - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_BG_THICKNESS - browserCanvasContext.stroke() - browserCanvasContext.closePath() + centerPoint = thisObject.container.frame.frameThisPoint(centerPoint) - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE) - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_BG_THICKNESS - browserCanvasContext.stroke() - browserCanvasContext.closePath() - - if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) { browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE) - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_BG_THICKNESS - browserCanvasContext.stroke() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIUS + RED_LINE_HIGHT, 0 * Math.PI, 2.0 * Math.PI) browserCanvasContext.closePath() - } - browserCanvasContext.setLineDash([2, 3]) + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' + browserCanvasContext.fill() - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, BAR_START_ANGLE, MIN_VALUE_ANGLE) - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_THICKNESS - browserCanvasContext.stroke() - browserCanvasContext.closePath() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE) - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_THICKNESS - browserCanvasContext.stroke() - browserCanvasContext.closePath() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE) - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_THICKNESS - browserCanvasContext.stroke() - browserCanvasContext.closePath() - - if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) { browserCanvasContext.beginPath() - browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE) - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = VALUE_THICKNESS - browserCanvasContext.stroke() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIUS, 0.0 * Math.PI, 2.0 * Math.PI) browserCanvasContext.closePath() - } + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' + browserCanvasContext.fill() + + /* We draw the circle bar */ + + const DEFAULT_THICKNESS = 2 + const VALUE_THICKNESS = 8 + const VALUE_BG_THICKNESS = 1 + const BAR_RADIUS = RADIUS * 0.85 + + let BAR_START_ANGLE = 0.85 * Math.PI + let BAR_END_ANGLE = 2.15 * Math.PI + let CURRENT_VALUE_ANGLE = thisObject.params.VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE + let MIN_VALUE_ANGLE = thisObject.params.MIN_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE + let INIT_VALUE_ANGLE = thisObject.params.INIT_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE + let PROFIT_VALUE_ANGLE = CURRENT_VALUE_ANGLE + + if (CURRENT_VALUE_ANGLE > INIT_VALUE_ANGLE) { CURRENT_VALUE_ANGLE = INIT_VALUE_ANGLE } + if (CURRENT_VALUE_ANGLE < MIN_VALUE_ANGLE) { CURRENT_VALUE_ANGLE = MIN_VALUE_ANGLE } + if (PROFIT_VALUE_ANGLE > BAR_END_ANGLE) { PROFIT_VALUE_ANGLE = BAR_END_ANGLE } + + if ( + thisObject.params.VALUE > 0 && + thisObject.params.ASSET_NAME === thisObject.params.BASE_ASSET && + thisObject.params.POSITION_TAKEN === false + ) { + browserCanvasContext.setLineDash([0, 0]) + + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, BAR_START_ANGLE, MIN_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_BG_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_BG_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_BG_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + + if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) { + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_BG_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + } + + browserCanvasContext.setLineDash([2, 3]) + + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, BAR_START_ANGLE, MIN_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + + if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) { + browserCanvasContext.beginPath() + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath() + } + } + + /* Common Variables */ + + let fontSize + let label + let xOffset + let yOffset + + /* We put the thisObject.params.VALUE in the middle */ + + label = thisObject.params.VALUE + + if (isNaN(label) === false) { + label = Number(label) + + label = dynamicDecimals(label, 2) + if (label === 0) { label = label.toFixed(2) } + } + + fontSize = 22 + if (label.length > 8) { + fontSize = 18 + } + if (label.length > 10) { + fontSize = 14 + } + if (label.length > 12) { + fontSize = 10 + } + if (label.length > 14) { + fontSize = 8 + } + + browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY + + // label = label.substring(0, 6) + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 7 + + labelPoint = { + x: centerPoint.x - xOffset, + y: centerPoint.y + } + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + + /* We put the top label */ + + fontSize = 12 + + browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY + + label = thisObject.params.ASSET_LABEL + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 3 + yOffset = 22 + + labelPoint = { + x: centerPoint.x - xOffset, + y: centerPoint.y - yOffset + } + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + + /* We put the bottom label */ + + fontSize = 12 + + browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY + + label = thisObject.params.ASSET_NAME + ' ' + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 3 + yOffset = -15 + + labelPoint = { + x: centerPoint.x - xOffset, + y: centerPoint.y - yOffset + } + + if (thisObject.params.ASSET_NAME === thisObject.params.BASE_ASSET) { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + } else { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + } + + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } - - /* Common Variables */ - - let fontSize - let label - let xOffset - let yOffset - - /* We put the thisObject.params.VALUE in the middle */ - - label = thisObject.params.VALUE - - if (isNaN(label) === false) { - label = Number(label) - - label = dynamicDecimals(label, 2) - if (label === 0) { label = label.toFixed(2) } - } - - fontSize = 22 - if (label.length > 8) { - fontSize = 18 - } - if (label.length > 10) { - fontSize = 14 - } - if (label.length > 12) { - fontSize = 10 - } - if (label.length > 14) { - fontSize = 8 - } - - browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY - - // label = label.substring(0, 6) - - xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 7 - - labelPoint = { - x: centerPoint.x - xOffset, - y: centerPoint.y - } - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - - /* We put the top label */ - - fontSize = 12 - - browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY - - label = thisObject.params.ASSET_LABEL - - xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 3 - yOffset = 22 - - labelPoint = { - x: centerPoint.x - xOffset, - y: centerPoint.y - yOffset - } - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - - /* We put the bottom label */ - - fontSize = 12 - - browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY - - label = thisObject.params.ASSET_NAME + ' ' - - xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 3 - yOffset = -15 - - labelPoint = { - x: centerPoint.x - xOffset, - y: centerPoint.y - yOffset - } - - if (thisObject.params.ASSET_NAME === thisObject.params.BASE_ASSET) { - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - } else { - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - } - - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } } diff --git a/Container.js b/Container.js index 56cf14085..f3afb66e5 100644 --- a/Container.js +++ b/Container.js @@ -1,262 +1,262 @@ -function newContainer () { - let thisObject = { - id: newUniqueId(), - type: 'Rectangle', - frame: undefined, - eventHandler: undefined, - parentContainer: undefined, - isDraggeable: true, - notDraggingOnX: false, - notDraggingOnY: false, - isClickeable: false, - isWheelable: false, - detectMouseOver: false, - name: undefined, - fitFunction: undefined, - isVisibleFunction: undefined, - displace: displace, - initialize: initialize, - finalize: finalize, - connectToParent: connectToParent, - isForThisPurpose: isForThisPurpose - } - - let connectedToParentWidth = false - let connectedToParentHeight = false - let connectedToParentRadius = false - - let onDimmensionsChangedParentEvent = false - let onMouseOverParentEvent = false - let onMouseNotOverParentEvent = false - let onFocusParentEvent = false - let onNotFocusParentEvent = false - let onDisplaceParentEvent = false - let onDragStartedParentEvent = false - let onDragFinishedParentEvent = false - - let isConnectedToParent = false - - let dimensionsChangedEventSubscriptionId - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - let onFocusEventSubscriptionId - let onNotFocusEventSubscriptionId - let onDisplaceEventSubscriptionId - let onDragStartedEventSubscriptionId - let onDragFinishedEventSubscriptionId - - return thisObject - - function finalize () { - if (isConnectedToParent === true) { - thisObject.parentContainer.eventHandler.stopListening(dimensionsChangedEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onFocusEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onNotFocusEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onDisplaceEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onDragStartedEventSubscriptionId) - thisObject.parentContainer.eventHandler.stopListening(onDragFinishedEventSubscriptionId) - - thisObject.parentContainer = undefined - thisObject.eventHandler.finalize() - - thisObject.frame.finalize() - } - } - - function initialize (pName, pType) { - thisObject.name = pName - thisObject.type = pType - - thisObject.frame = newFrame() - thisObject.frame.initialize(pType) - if (pName !== undefined) { - thisObject.frame.containerName = pName - } - thisObject.frame.container = thisObject - - thisObject.eventHandler = newEventHandler() - thisObject.eventHandler.name = pName - } - - function connectToParent ( - parentContainer, - onWidth, - onHeight, - onRadius, - onDimmensionsChangedEvent, - onMouseOverEvent, - onMouseNotOverEvent, - onFocusEvent, - onNotFocusEvent, - onDisplaceEvent, - onDragStartedEvent, - onDragFinishedEvent - ) { - connectedToParentWidth = onWidth - connectedToParentHeight = onHeight - connectedToParentRadius = onRadius - - onDimmensionsChangedParentEvent = onDimmensionsChangedEvent - onMouseOverParentEvent = onMouseOverEvent - onMouseNotOverParentEvent = onMouseNotOverEvent - onFocusParentEvent = onFocusEvent - onNotFocusParentEvent = onNotFocusEvent - onDisplaceParentEvent = onDisplaceEvent - onDragStartedParentEvent = onDragStartedEvent - onDragFinishedParentEvent = onDragFinishedEvent - - isConnectedToParent = true - - thisObject.frame.parentFrame = parentContainer.frame - thisObject.parentContainer = parentContainer - - if (onDimmensionsChangedParentEvent === true) { - dimensionsChangedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('Dimmensions Changed', onParentDimmensionsChanged) - } - if (onMouseOverParentEvent === true) { - onMouseOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseOver', onMouseOver) - } - if (onMouseNotOverParentEvent === true) { - onMouseNotOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - } - if (onFocusParentEvent === true) { - onFocusEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onFocus', onFocus) - } - if (onNotFocusParentEvent === true) { - onNotFocusEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onNotFocus', onNotFocus) - } - if (onDisplaceParentEvent === true) { - onDisplaceEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDisplace', onDisplace) - } - if (onDragStartedParentEvent === true) { - onDragStartedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDragStarted', onDragStarted) - } - if (onDragFinishedParentEvent === true) { - onDragFinishedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDragFinished', onDragFinished) +function newContainer() { + let thisObject = { + id: newUniqueId(), + type: 'Rectangle', + frame: undefined, + eventHandler: undefined, + parentContainer: undefined, + isDraggeable: true, + notDraggingOnX: false, + notDraggingOnY: false, + isClickeable: false, + isWheelable: false, + detectMouseOver: false, + name: undefined, + fitFunction: undefined, + isVisibleFunction: undefined, + displace: displace, + initialize: initialize, + finalize: finalize, + connectToParent: connectToParent, + isForThisPurpose: isForThisPurpose } - if (connectedToParentWidth) { - thisObject.frame.width = thisObject.parentContainer.frame.width - } - if (connectedToParentHeight) { - thisObject.frame.height = thisObject.parentContainer.frame.height - } - if (connectedToParentRadius) { - thisObject.frame.radius = thisObject.parentContainer.frame.radius - } - } + let connectedToParentWidth = false + let connectedToParentHeight = false + let connectedToParentRadius = false - function onParentDimmensionsChanged (event) { - let dimmensionsChanged = false - if (connectedToParentWidth) { - thisObject.frame.width = thisObject.parentContainer.frame.width - dimmensionsChanged = true - } - if (connectedToParentHeight) { - thisObject.frame.height = thisObject.parentContainer.frame.height - dimmensionsChanged = true - } - if (connectedToParentRadius) { - thisObject.frame.radius = thisObject.parentContainer.frame.radius - dimmensionsChanged = true + let onDimmensionsChangedParentEvent = false + let onMouseOverParentEvent = false + let onMouseNotOverParentEvent = false + let onFocusParentEvent = false + let onNotFocusParentEvent = false + let onDisplaceParentEvent = false + let onDragStartedParentEvent = false + let onDragFinishedParentEvent = false + + let isConnectedToParent = false + + let dimensionsChangedEventSubscriptionId + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + let onFocusEventSubscriptionId + let onNotFocusEventSubscriptionId + let onDisplaceEventSubscriptionId + let onDragStartedEventSubscriptionId + let onDragFinishedEventSubscriptionId + + return thisObject + + function finalize() { + if (isConnectedToParent === true) { + thisObject.parentContainer.eventHandler.stopListening(dimensionsChangedEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onFocusEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onNotFocusEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onDisplaceEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onDragStartedEventSubscriptionId) + thisObject.parentContainer.eventHandler.stopListening(onDragFinishedEventSubscriptionId) + + thisObject.parentContainer = undefined + thisObject.eventHandler.finalize() + + thisObject.frame.finalize() + } } - if (dimmensionsChanged) { - thisObject.eventHandler.raiseEvent('Dimmensions Changed', event) + function initialize(pName, pType) { + thisObject.name = pName + thisObject.type = pType + + thisObject.frame = newFrame() + thisObject.frame.initialize(pType) + if (pName !== undefined) { + thisObject.frame.containerName = pName + } + thisObject.frame.container = thisObject + + thisObject.eventHandler = newEventHandler() + thisObject.eventHandler.name = pName } - } - function onMouseOver (event) { - thisObject.eventHandler.raiseEvent('onMouseOver', event) - } + function connectToParent( + parentContainer, + onWidth, + onHeight, + onRadius, + onDimmensionsChangedEvent, + onMouseOverEvent, + onMouseNotOverEvent, + onFocusEvent, + onNotFocusEvent, + onDisplaceEvent, + onDragStartedEvent, + onDragFinishedEvent + ) { + connectedToParentWidth = onWidth + connectedToParentHeight = onHeight + connectedToParentRadius = onRadius - function onMouseNotOver (event) { - thisObject.eventHandler.raiseEvent('onMouseNotOver', event) - } + onDimmensionsChangedParentEvent = onDimmensionsChangedEvent + onMouseOverParentEvent = onMouseOverEvent + onMouseNotOverParentEvent = onMouseNotOverEvent + onFocusParentEvent = onFocusEvent + onNotFocusParentEvent = onNotFocusEvent + onDisplaceParentEvent = onDisplaceEvent + onDragStartedParentEvent = onDragStartedEvent + onDragFinishedParentEvent = onDragFinishedEvent - function onFocus (event) { - thisObject.eventHandler.raiseEvent('onFocus', event) - } + isConnectedToParent = true - function onNotFocus (event) { - thisObject.eventHandler.raiseEvent('onNotFocus', event) - } + thisObject.frame.parentFrame = parentContainer.frame + thisObject.parentContainer = parentContainer - function onDisplace (event) { - thisObject.eventHandler.raiseEvent('onDisplace', event) - } + if (onDimmensionsChangedParentEvent === true) { + dimensionsChangedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('Dimmensions Changed', onParentDimmensionsChanged) + } + if (onMouseOverParentEvent === true) { + onMouseOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseOver', onMouseOver) + } + if (onMouseNotOverParentEvent === true) { + onMouseNotOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + } + if (onFocusParentEvent === true) { + onFocusEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onFocus', onFocus) + } + if (onNotFocusParentEvent === true) { + onNotFocusEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onNotFocus', onNotFocus) + } + if (onDisplaceParentEvent === true) { + onDisplaceEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDisplace', onDisplace) + } + if (onDragStartedParentEvent === true) { + onDragStartedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDragStarted', onDragStarted) + } + if (onDragFinishedParentEvent === true) { + onDragFinishedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDragFinished', onDragFinished) + } - function onDragStarted (event) { - thisObject.eventHandler.raiseEvent('onDragStarted', event) - } - - function onDragFinished (event) { - thisObject.eventHandler.raiseEvent('onDragFinished', event) - } - - function isForThisPurpose (purpose) { - if (purpose !== undefined) { - switch (purpose) { - case GET_CONTAINER_PURPOSE.MOUSE_OVER: - if (thisObject.detectMouseOver === true) { - return true - } - break - case GET_CONTAINER_PURPOSE.MOUSE_WHEEL: - if (thisObject.isWheelable === true) { - return true - } - break - case GET_CONTAINER_PURPOSE.MOUSE_CLICK: - if (thisObject.isClickeable === true) { - return true - } - break - case GET_CONTAINER_PURPOSE.DRAGGING: - if (thisObject.isDraggeable === true) { - return true - } - break - default: { return false } - - } + if (connectedToParentWidth) { + thisObject.frame.width = thisObject.parentContainer.frame.width + } + if (connectedToParentHeight) { + thisObject.frame.height = thisObject.parentContainer.frame.height + } + if (connectedToParentRadius) { + thisObject.frame.radius = thisObject.parentContainer.frame.radius + } } - return false - } - function displace (point) { - /* This function will move the container according to the vector received. If it has a visible function will use it - to see if the container can be moved there or not. It wont if the center will not be visible. + function onParentDimmensionsChanged(event) { + let dimmensionsChanged = false + if (connectedToParentWidth) { + thisObject.frame.width = thisObject.parentContainer.frame.width + dimmensionsChanged = true + } + if (connectedToParentHeight) { + thisObject.frame.height = thisObject.parentContainer.frame.height + dimmensionsChanged = true + } + if (connectedToParentRadius) { + thisObject.frame.radius = thisObject.parentContainer.frame.radius + dimmensionsChanged = true + } - Returns true if move was possible, false if not. */ + if (dimmensionsChanged) { + thisObject.eventHandler.raiseEvent('Dimmensions Changed', event) + } + } - let checkPoint = {} + function onMouseOver(event) { + thisObject.eventHandler.raiseEvent('onMouseOver', event) + } - if (thisObject.isVisibleFunction === undefined) { - drag() - return true - } else { - checkPoint.x = thisObject.frame.position.x + point.x + thisObject.frame.width / 2 - checkPoint.y = thisObject.frame.position.y + point.y + thisObject.frame.height / 2 - let isVisible = thisObject.isVisibleFunction(checkPoint) - if (isVisible === true) { - drag() - return true - } else { + function onMouseNotOver(event) { + thisObject.eventHandler.raiseEvent('onMouseNotOver', event) + } + + function onFocus(event) { + thisObject.eventHandler.raiseEvent('onFocus', event) + } + + function onNotFocus(event) { + thisObject.eventHandler.raiseEvent('onNotFocus', event) + } + + function onDisplace(event) { + thisObject.eventHandler.raiseEvent('onDisplace', event) + } + + function onDragStarted(event) { + thisObject.eventHandler.raiseEvent('onDragStarted', event) + } + + function onDragFinished(event) { + thisObject.eventHandler.raiseEvent('onDragFinished', event) + } + + function isForThisPurpose(purpose) { + if (purpose !== undefined) { + switch (purpose) { + case GET_CONTAINER_PURPOSE.MOUSE_OVER: + if (thisObject.detectMouseOver === true) { + return true + } + break + case GET_CONTAINER_PURPOSE.MOUSE_WHEEL: + if (thisObject.isWheelable === true) { + return true + } + break + case GET_CONTAINER_PURPOSE.MOUSE_CLICK: + if (thisObject.isClickeable === true) { + return true + } + break + case GET_CONTAINER_PURPOSE.DRAGGING: + if (thisObject.isDraggeable === true) { + return true + } + break + default: { return false } + + } + } return false - } } - function drag () { - if (thisObject.notDraggingOnX === false) { - thisObject.frame.position.x = thisObject.frame.position.x + point.x - } - if (thisObject.notDraggingOnY === false) { - thisObject.frame.position.y = thisObject.frame.position.y + point.y - } - thisObject.eventHandler.raiseEvent('onDisplace', event) + + function displace(point) { + /* This function will move the container according to the vector received. If it has a visible function will use it + to see if the container can be moved there or not. It wont if the center will not be visible. + + Returns true if move was possible, false if not. */ + + let checkPoint = {} + + if (thisObject.isVisibleFunction === undefined) { + drag() + return true + } else { + checkPoint.x = thisObject.frame.position.x + point.x + thisObject.frame.width / 2 + checkPoint.y = thisObject.frame.position.y + point.y + thisObject.frame.height / 2 + let isVisible = thisObject.isVisibleFunction(checkPoint) + if (isVisible === true) { + drag() + return true + } else { + return false + } + } + function drag() { + if (thisObject.notDraggingOnX === false) { + thisObject.frame.position.x = thisObject.frame.position.x + point.x + } + if (thisObject.notDraggingOnY === false) { + thisObject.frame.position.y = thisObject.frame.position.y + point.y + } + thisObject.eventHandler.raiseEvent('onDisplace', event) + } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js index 047c4dcf3..ff51d8cce 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js @@ -1,224 +1,224 @@ -function newCCXTFunctions () { - thisObject = { - addMissingExchanges: addMissingExchanges, - addMissingAssets: addMissingAssets, - addMissingMarkets: addMissingMarkets - } - - return thisObject - - function addMissingExchanges (node, functionLibraryUiObjectsFromNodes) { - currentExchanges = new Map() - let parent = node.payload.parentNode - if (parent !== undefined) { - for (let i = 0; i < parent.cryptoExchanges.length; i++) { - let cryptoExchanges = parent.cryptoExchanges[i] - for (let j = 0; j < cryptoExchanges.exchanges.length; j++) { - let exchange = cryptoExchanges.exchanges[j] - let codeName = loadPropertyFromNodeConfig(exchange.payload, 'codeName') - currentExchanges.set(codeName, exchange) - } - } +function newCCXTFunctions() { + thisObject = { + addMissingExchanges: addMissingExchanges, + addMissingAssets: addMissingAssets, + addMissingMarkets: addMissingMarkets } - let params = { - method: 'listExchanges', - has: { - fetchOHLCV: true, - fetchMarkets: true - } - } + return thisObject - callServer(JSON.stringify(params), 'CCXT', onResponse) - - function onResponse (err, data) { - if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') - return - } - - let exchanges = JSON.parse(data) - for (let i = 0; i < exchanges.length; i++) { - let exchange = exchanges[i] - let existingExchange = currentExchanges.get(exchange.id) - if (existingExchange === undefined) { - let newExchange = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Crypto Exchange') - newExchange.name = exchange.name - newExchange.config = '{ \n\"codeName\": \"' + exchange.id + '\"\n}' - newExchange.payload.floatingObject.collapseToggle() - newExchange.exchangeAssets.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - newExchange.exchangeMarkets.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - newExchange.exchangeAccounts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - newExchange.exchangeAssets.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X - newExchange.exchangeMarkets.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X - newExchange.exchangeAccounts.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X - newExchange.exchangeAssets.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - newExchange.exchangeMarkets.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - newExchange.exchangeAccounts.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - } - } - } - } - - function addMissingAssets (node, functionLibraryUiObjectsFromNodes) { - if (node.payload.parentNode === undefined) { return } - - let currentAssets = new Map() - for (let j = 0; j < node.assets.length; j++) { - let asset = node.assets[j] - let codeName = loadPropertyFromNodeConfig(asset.payload, 'codeName') - currentAssets.set(codeName, asset) - } - - let exchangeId = loadPropertyFromNodeConfig(node.payload.parentNode.payload, 'codeName') - - try { - let params = { - exchangeId: exchangeId, - method: 'fetchMarkets' - } - callServer(JSON.stringify(params), 'CCXT', onResponse) - - function onResponse (err, data) { - if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') - return - } - let queryParams = loadPropertyFromNodeConfig(node.payload, 'addMissingAssets') - - let markets = JSON.parse(data) - for (let i = 0; i < markets.length; i++) { - let market = markets[i] - - if (queryParams !== undefined) { - if (queryParams.baseAsset !== undefined) { - if (market.base.indexOf(queryParams.baseAsset) < 0) { - continue - } + function addMissingExchanges(node, functionLibraryUiObjectsFromNodes) { + currentExchanges = new Map() + let parent = node.payload.parentNode + if (parent !== undefined) { + for (let i = 0; i < parent.cryptoExchanges.length; i++) { + let cryptoExchanges = parent.cryptoExchanges[i] + for (let j = 0; j < cryptoExchanges.exchanges.length; j++) { + let exchange = cryptoExchanges.exchanges[j] + let codeName = loadPropertyFromNodeConfig(exchange.payload, 'codeName') + currentExchanges.set(codeName, exchange) + } } - if (queryParams.quotedAsset !== undefined) { - if (market.quote.indexOf(queryParams.quotedAsset) < 0) { - continue - } + } + + let params = { + method: 'listExchanges', + has: { + fetchOHLCV: true, + fetchMarkets: true } - } - if (currentAssets.get(market.base) === undefined) { - addAsset(market.base) - currentAssets.set(market.base, market.base) - } - if (currentAssets.get(market.quote) === undefined) { - addAsset(market.quote) - currentAssets.set(market.quote, market.quote) - } - - function addAsset (name) { - let newAsseet = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Asset') - newAsseet.name = name - newAsseet.config = '{ \n\"codeName\": \"' + name + '\"\n}' - } - } - } - } catch (err) { - node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') - console.log(err.stack) - } - } - - function addMissingMarkets (node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) { - if (node.payload.parentNode === undefined) { return } - if (node.payload.parentNode.exchangeAssets === undefined) { return } - if (node.payload.parentNode.payload.parentNode === undefined) { return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.superActions === undefined) { return } - - let currentAssets = new Map() - let exchangeAssets = node.payload.parentNode.exchangeAssets - for (let j = 0; j < exchangeAssets.assets.length; j++) { - let asset = exchangeAssets.assets[j] - let codeName = loadPropertyFromNodeConfig(asset.payload, 'codeName') - currentAssets.set(codeName, asset) - } - - let currentMarkets = new Map() - let exchangeMarkets = node - for (let j = 0; j < exchangeMarkets.markets.length; j++) { - let asset = exchangeMarkets.markets[j] - let codeName = loadPropertyFromNodeConfig(asset.payload, 'codeName') - currentMarkets.set(codeName, asset) - } - - let exchangeId = loadPropertyFromNodeConfig(node.payload.parentNode.payload, 'codeName') - - try { - let params = { - exchangeId: exchangeId, - method: 'fetchMarkets' - } - callServer(JSON.stringify(params), 'CCXT', onResponse) - - function onResponse (err, data) { - if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') - return } - let markets = JSON.parse(data) - for (let i = 0; i < markets.length; i++) { - let market = markets[i] - let baseAsset = currentAssets.get(market.base) - let quotedAsset = currentAssets.get(market.quote) + callServer(JSON.stringify(params), 'CCXT', onResponse) - if (baseAsset === undefined) { - continue - } - if (quotedAsset === undefined) { - continue - } + function onResponse(err, data) { + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') + return + } - if (currentMarkets.get(market.symbol) === undefined) { - addMarket(market.symbol, baseAsset, quotedAsset) - } - - function addMarket (name, baseAsset, quotedAsset) { - let newMarket = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Market') - newMarket.name = name - newMarket.config = '{ \n\"codeName\": \"' + name + '\"\n}' - newMarket.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - newMarket.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X - newMarket.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - newMarket.baseAsset.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 - newMarket.quotedAsset.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 - newMarket.baseAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X - newMarket.quotedAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_150X - newMarket.baseAsset.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - newMarket.quotedAsset.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - newMarket.baseAsset.payload.referenceParent = baseAsset - newMarket.quotedAsset.payload.referenceParent = quotedAsset - - currentMarkets.set(name, newMarket) - - let superActions = node.payload.parentNode.payload.parentNode.payload.parentNode.superActions - - for (let j = 0; j < superActions.superActions.length; j++) { - let superAction = superActions.superActions[j] - let clone = functionLibraryNodeCloning.getNodeClone(superAction) - functionLibraryUiObjectsFromNodes.createUiObjectFromNode(clone, newMarket, newMarket) - newMarket.superActions.push(clone) - switch (j) { - case 0: - clone.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X - break - case 1: - clone.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X - break - } + let exchanges = JSON.parse(data) + for (let i = 0; i < exchanges.length; i++) { + let exchange = exchanges[i] + let existingExchange = currentExchanges.get(exchange.id) + if (existingExchange === undefined) { + let newExchange = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Crypto Exchange') + newExchange.name = exchange.name + newExchange.config = '{ \n\"codeName\": \"' + exchange.id + '\"\n}' + newExchange.payload.floatingObject.collapseToggle() + newExchange.exchangeAssets.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + newExchange.exchangeMarkets.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + newExchange.exchangeAccounts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + newExchange.exchangeAssets.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X + newExchange.exchangeMarkets.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X + newExchange.exchangeAccounts.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X + newExchange.exchangeAssets.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + newExchange.exchangeMarkets.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + newExchange.exchangeAccounts.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + } } - } } - } - } catch (err) { - node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') - console.log(err.stack) } - } + + function addMissingAssets(node, functionLibraryUiObjectsFromNodes) { + if (node.payload.parentNode === undefined) { return } + + let currentAssets = new Map() + for (let j = 0; j < node.assets.length; j++) { + let asset = node.assets[j] + let codeName = loadPropertyFromNodeConfig(asset.payload, 'codeName') + currentAssets.set(codeName, asset) + } + + let exchangeId = loadPropertyFromNodeConfig(node.payload.parentNode.payload, 'codeName') + + try { + let params = { + exchangeId: exchangeId, + method: 'fetchMarkets' + } + callServer(JSON.stringify(params), 'CCXT', onResponse) + + function onResponse(err, data) { + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') + return + } + let queryParams = loadPropertyFromNodeConfig(node.payload, 'addMissingAssets') + + let markets = JSON.parse(data) + for (let i = 0; i < markets.length; i++) { + let market = markets[i] + + if (queryParams !== undefined) { + if (queryParams.baseAsset !== undefined) { + if (market.base.indexOf(queryParams.baseAsset) < 0) { + continue + } + } + if (queryParams.quotedAsset !== undefined) { + if (market.quote.indexOf(queryParams.quotedAsset) < 0) { + continue + } + } + } + if (currentAssets.get(market.base) === undefined) { + addAsset(market.base) + currentAssets.set(market.base, market.base) + } + if (currentAssets.get(market.quote) === undefined) { + addAsset(market.quote) + currentAssets.set(market.quote, market.quote) + } + + function addAsset(name) { + let newAsseet = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Asset') + newAsseet.name = name + newAsseet.config = '{ \n\"codeName\": \"' + name + '\"\n}' + } + } + } + } catch (err) { + node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') + console.log(err.stack) + } + } + + function addMissingMarkets(node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) { + if (node.payload.parentNode === undefined) { return } + if (node.payload.parentNode.exchangeAssets === undefined) { return } + if (node.payload.parentNode.payload.parentNode === undefined) { return } + if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } + if (node.payload.parentNode.payload.parentNode.payload.parentNode.superActions === undefined) { return } + + let currentAssets = new Map() + let exchangeAssets = node.payload.parentNode.exchangeAssets + for (let j = 0; j < exchangeAssets.assets.length; j++) { + let asset = exchangeAssets.assets[j] + let codeName = loadPropertyFromNodeConfig(asset.payload, 'codeName') + currentAssets.set(codeName, asset) + } + + let currentMarkets = new Map() + let exchangeMarkets = node + for (let j = 0; j < exchangeMarkets.markets.length; j++) { + let asset = exchangeMarkets.markets[j] + let codeName = loadPropertyFromNodeConfig(asset.payload, 'codeName') + currentMarkets.set(codeName, asset) + } + + let exchangeId = loadPropertyFromNodeConfig(node.payload.parentNode.payload, 'codeName') + + try { + let params = { + exchangeId: exchangeId, + method: 'fetchMarkets' + } + callServer(JSON.stringify(params), 'CCXT', onResponse) + + function onResponse(err, data) { + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') + return + } + + let markets = JSON.parse(data) + for (let i = 0; i < markets.length; i++) { + let market = markets[i] + let baseAsset = currentAssets.get(market.base) + let quotedAsset = currentAssets.get(market.quote) + + if (baseAsset === undefined) { + continue + } + if (quotedAsset === undefined) { + continue + } + + if (currentMarkets.get(market.symbol) === undefined) { + addMarket(market.symbol, baseAsset, quotedAsset) + } + + function addMarket(name, baseAsset, quotedAsset) { + let newMarket = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Market') + newMarket.name = name + newMarket.config = '{ \n\"codeName\": \"' + name + '\"\n}' + newMarket.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + newMarket.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X + newMarket.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + newMarket.baseAsset.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 + newMarket.quotedAsset.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 + newMarket.baseAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X + newMarket.quotedAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_150X + newMarket.baseAsset.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + newMarket.quotedAsset.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + newMarket.baseAsset.payload.referenceParent = baseAsset + newMarket.quotedAsset.payload.referenceParent = quotedAsset + + currentMarkets.set(name, newMarket) + + let superActions = node.payload.parentNode.payload.parentNode.payload.parentNode.superActions + + for (let j = 0; j < superActions.superActions.length; j++) { + let superAction = superActions.superActions[j] + let clone = functionLibraryNodeCloning.getNodeClone(superAction) + functionLibraryUiObjectsFromNodes.createUiObjectFromNode(clone, newMarket, newMarket) + newMarket.superActions.push(clone) + switch (j) { + case 0: + clone.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X + break + case 1: + clone.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X + break + } + } + } + } + } + } catch (err) { + node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') + console.log(err.stack) + } + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/ChainAttachDetach.js b/DesignSpace/Workspace/FunctionLibraries/ChainAttachDetach.js index 5a75546ab..faff8bafb 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChainAttachDetach.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChainAttachDetach.js @@ -1,221 +1,221 @@ -function newChainAttachDetach () { - thisObject = { - chainDetachNode: chainDetachNode, - chainAttachNode: chainAttachNode - } +function newChainAttachDetach() { + thisObject = { + chainDetachNode: chainDetachNode, + chainAttachNode: chainAttachNode + } - return thisObject + return thisObject - function chainDetachNode (node, rootNodes) { - if (node.payload.parentNode === undefined) { return } - switch (node.type) { - case 'Phase': { - let payload = node.payload - for (let i = 0; i < payload.parentNode.phases.length; i++) { - let phase = payload.parentNode.phases[i] - if (phase.id === node.id) { - if (i < payload.parentNode.phases.length - 1) { - let nextPhase = payload.parentNode.phases[i + 1] - if (i > 0) { - let previousPhase = payload.parentNode.phases[i - 1] - nextPhase.payload.chainParent = previousPhase - } else { - nextPhase.payload.chainParent = payload.parentNode - } - } - payload.parentNode.phases.splice(i, 1) - completeDetachment(node, rootNodes) - return - } - } - return - } - default: { - let nodeDefinition = getNodeDefinition (node) - if (nodeDefinition !== undefined) { - /* Detach from parent */ - if (node.payload.parentNode !== undefined) { - let parentNodeDefinition = getNodeDefinition (node.payload.parentNode) - if (parentNodeDefinition !== undefined) { - if (parentNodeDefinition.properties !== undefined) { - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (nodeDefinition.propertyNameAtParent === property.name) { - switch (property.type) { - case 'node': { - node.payload.parentNode[property.name] = undefined - } - break - case 'array': { - let nodePropertyArray = node.payload.parentNode[property.name] - if (nodePropertyArray !== undefined) { - for (let j = 0; j < nodePropertyArray.length; j++) { - let arrayItem = nodePropertyArray[j] - if (arrayItem.id === node.id) { - nodePropertyArray.splice(j, 1) + function chainDetachNode(node, rootNodes) { + if (node.payload.parentNode === undefined) { return } + switch (node.type) { + case 'Phase': { + let payload = node.payload + for (let i = 0; i < payload.parentNode.phases.length; i++) { + let phase = payload.parentNode.phases[i] + if (phase.id === node.id) { + if (i < payload.parentNode.phases.length - 1) { + let nextPhase = payload.parentNode.phases[i + 1] + if (i > 0) { + let previousPhase = payload.parentNode.phases[i - 1] + nextPhase.payload.chainParent = previousPhase + } else { + nextPhase.payload.chainParent = payload.parentNode } - } } - } - break + payload.parentNode.phases.splice(i, 1) + completeDetachment(node, rootNodes) + return } - } } - } + return + } + default: { + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + /* Detach from parent */ + if (node.payload.parentNode !== undefined) { + let parentNodeDefinition = getNodeDefinition(node.payload.parentNode) + if (parentNodeDefinition !== undefined) { + if (parentNodeDefinition.properties !== undefined) { + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (nodeDefinition.propertyNameAtParent === property.name) { + switch (property.type) { + case 'node': { + node.payload.parentNode[property.name] = undefined + } + break + case 'array': { + let nodePropertyArray = node.payload.parentNode[property.name] + if (nodePropertyArray !== undefined) { + for (let j = 0; j < nodePropertyArray.length; j++) { + let arrayItem = nodePropertyArray[j] + if (arrayItem.id === node.id) { + nodePropertyArray.splice(j, 1) + } + } + } + } + break + } + } + } + } + } + } + completeDetachment(node, rootNodes) + } } - } - completeDetachment(node, rootNodes) } - } } - } - function chainAttachNode (node, attachToNode, rootNodes) { - switch (node.type) { + function chainAttachNode(node, attachToNode, rootNodes) { + switch (node.type) { - case 'Exchange Account Key': { - node.payload.parentNode = attachToNode - node.payload.chainParent = attachToNode - if (node.payload.parentNode.keys !== undefined) { - node.payload.parentNode.keys.push(node) - } else { - node.payload.parentNode.key = node - } - completeAttachment(node, rootNodes) - } - break - - case 'Phase': { - switch (attachToNode.type) { - case 'Stop': { - node.payload.parentNode = attachToNode - if (attachToNode.phases.length > 0) { - let phase = attachToNode.phases[attachToNode.phases.length - 1] - node.payload.chainParent = phase - } else { - node.payload.chainParent = attachToNode - } - attachToNode.phases.push(node) - completeAttachment(node, rootNodes) - } - break - case 'Take Profit': { - node.payload.parentNode = attachToNode - if (attachToNode.phases.length > 0) { - let phase = attachToNode.phases[attachToNode.phases.length - 1] - node.payload.chainParent = phase - } else { - node.payload.chainParent = attachToNode - } - attachToNode.phases.push(node) - completeAttachment(node, rootNodes) - } - break - case 'Initial Stop': { - if (attachToNode.phases.length >= 1) { - return - } - - node.payload.parentNode = attachToNode - if (attachToNode.phases.length > 0) { - let phase = attachToNode.phases[attachToNode.phases.length - 1] - node.payload.chainParent = phase - } else { - node.payload.chainParent = attachToNode - } - attachToNode.phases.push(node) - completeAttachment(node, rootNodes) - } - break - case 'Initial Take Profit': { - if (attachToNode.phases.length >= 1) { - return - } - node.payload.parentNode = attachToNode - if (attachToNode.phases.length > 0) { - let phase = attachToNode.phases[attachToNode.phases.length - 1] - node.payload.chainParent = phase - } else { - node.payload.chainParent = attachToNode - } - attachToNode.phases.push(node) - completeAttachment(node, rootNodes) - } - break - case 'Phase': { - node.payload.parentNode = attachToNode.payload.parentNode - for (let i = 0; i < node.payload.parentNode.phases.length; i++) { - let phase = node.payload.parentNode.phases[i] - if (attachToNode.id === phase.id) { - if (i === node.payload.parentNode.phases.length - 1) { - node.payload.chainParent = attachToNode - node.payload.parentNode.phases.push(node) - completeAttachment(node, rootNodes) + case 'Exchange Account Key': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + if (node.payload.parentNode.keys !== undefined) { + node.payload.parentNode.keys.push(node) } else { - node.payload.chainParent = attachToNode - let nextPhase = node.payload.parentNode.phases[i + 1] - nextPhase.payload.chainParent = node - node.payload.parentNode.phases.splice(i + 1, 0, node) - completeAttachment(node, rootNodes) - return + node.payload.parentNode.key = node } - } + completeAttachment(node, rootNodes) } - } - } - } - break - default: { - let nodeDefinition = getNodeDefinition (node) - if (nodeDefinition !== undefined) { - node.payload.parentNode = attachToNode - node.payload.chainParent = attachToNode - /* Attach to new parent */ - if (node.payload.parentNode !== undefined) { - let parentNodeDefinition = getNodeDefinition (node.payload.parentNode) - if (parentNodeDefinition !== undefined) { - if (parentNodeDefinition.properties !== undefined) { - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (nodeDefinition.propertyNameAtParent === property.name) { - switch (property.type) { - case 'node': { - node.payload.parentNode[property.name] = node - } + break + + case 'Phase': { + switch (attachToNode.type) { + case 'Stop': { + node.payload.parentNode = attachToNode + if (attachToNode.phases.length > 0) { + let phase = attachToNode.phases[attachToNode.phases.length - 1] + node.payload.chainParent = phase + } else { + node.payload.chainParent = attachToNode + } + attachToNode.phases.push(node) + completeAttachment(node, rootNodes) + } break - case 'array': { - if (node.payload.parentNode[property.name] === undefined) { - node.payload.parentNode[property.name] = [] + case 'Take Profit': { + node.payload.parentNode = attachToNode + if (attachToNode.phases.length > 0) { + let phase = attachToNode.phases[attachToNode.phases.length - 1] + node.payload.chainParent = phase + } else { + node.payload.chainParent = attachToNode + } + attachToNode.phases.push(node) + completeAttachment(node, rootNodes) + } + break + case 'Initial Stop': { + if (attachToNode.phases.length >= 1) { + return + } + + node.payload.parentNode = attachToNode + if (attachToNode.phases.length > 0) { + let phase = attachToNode.phases[attachToNode.phases.length - 1] + node.payload.chainParent = phase + } else { + node.payload.chainParent = attachToNode + } + attachToNode.phases.push(node) + completeAttachment(node, rootNodes) + } + break + case 'Initial Take Profit': { + if (attachToNode.phases.length >= 1) { + return + } + node.payload.parentNode = attachToNode + if (attachToNode.phases.length > 0) { + let phase = attachToNode.phases[attachToNode.phases.length - 1] + node.payload.chainParent = phase + } else { + node.payload.chainParent = attachToNode + } + attachToNode.phases.push(node) + completeAttachment(node, rootNodes) + } + break + case 'Phase': { + node.payload.parentNode = attachToNode.payload.parentNode + for (let i = 0; i < node.payload.parentNode.phases.length; i++) { + let phase = node.payload.parentNode.phases[i] + if (attachToNode.id === phase.id) { + if (i === node.payload.parentNode.phases.length - 1) { + node.payload.chainParent = attachToNode + node.payload.parentNode.phases.push(node) + completeAttachment(node, rootNodes) + } else { + node.payload.chainParent = attachToNode + let nextPhase = node.payload.parentNode.phases[i + 1] + nextPhase.payload.chainParent = node + node.payload.parentNode.phases.splice(i + 1, 0, node) + completeAttachment(node, rootNodes) + return + } + } } - let nodePropertyArray = node.payload.parentNode[property.name] - nodePropertyArray.push(node) - } - break } - } } - } } - } - completeAttachment(node, rootNodes) + break + default: { + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + /* Attach to new parent */ + if (node.payload.parentNode !== undefined) { + let parentNodeDefinition = getNodeDefinition(node.payload.parentNode) + if (parentNodeDefinition !== undefined) { + if (parentNodeDefinition.properties !== undefined) { + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (nodeDefinition.propertyNameAtParent === property.name) { + switch (property.type) { + case 'node': { + node.payload.parentNode[property.name] = node + } + break + case 'array': { + if (node.payload.parentNode[property.name] === undefined) { + node.payload.parentNode[property.name] = [] + } + let nodePropertyArray = node.payload.parentNode[property.name] + nodePropertyArray.push(node) + } + break + } + } + } + } + } + } + completeAttachment(node, rootNodes) + } + } } - } } - } - function completeDetachment (node, rootNodes) { - node.payload.parentNode = undefined - node.payload.chainParent = undefined - rootNodes.push(node) - } + function completeDetachment(node, rootNodes) { + node.payload.parentNode = undefined + node.payload.chainParent = undefined + rootNodes.push(node) + } - function completeAttachment (node, rootNodes) { - for (let i = 0; i < rootNodes.length; i++) { - let rootNode = rootNodes[i] - if (rootNode.id === node.id) { - rootNodes.splice(i, 1) - return - } + function completeAttachment(node, rootNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.id === node.id) { + rootNodes.splice(i, 1) + return + } + } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/DependenciesFilter.js b/DesignSpace/Workspace/FunctionLibraries/DependenciesFilter.js index 1e4fb26ac..88b9eb45d 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DependenciesFilter.js +++ b/DesignSpace/Workspace/FunctionLibraries/DependenciesFilter.js @@ -1,74 +1,74 @@ -function newDependenciesFilter () { - thisObject = { - createFilter: createFilter - } +function newDependenciesFilter() { + thisObject = { + createFilter: createFilter + } - return thisObject + return thisObject - function createFilter (node) { - let filters = new Map() - recursiveFilter(node) + function createFilter(node) { + let filters = new Map() + recursiveFilter(node) - return Array.from(filters.keys()) + return Array.from(filters.keys()) - function recursiveFilter (node) { - filter(node.code) + function recursiveFilter(node) { + filter(node.code) - let nodeDefinition = getNodeDefinition (node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - recursiveFilter(node[property.name]) - } - previousPropertyName = property.name + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + recursiveFilter(node[property.name]) + } + previousPropertyName = property.name + } + } + break + case 'array': { + let nodePropertyArray = node[property.name] + if (nodePropertyArray !== undefined) { + for (let j = 0; j < nodePropertyArray.length; j++) { + let nodeProperty = nodePropertyArray[j] + recursiveFilter(nodeProperty) + } + } + } + break + } + } } - } - break - case 'array': { - let nodePropertyArray = node[property.name] - if (nodePropertyArray !== undefined) { - for (let j = 0; j < nodePropertyArray.length; j++) { - let nodeProperty = nodePropertyArray[j] - recursiveFilter(nodeProperty) - } - } - } - break } - } } - } - } - function filter (code) { - if (code === undefined) { return } + function filter(code) { + if (code === undefined) { return } - let instructionsArray = code.split(' ') - for (let i = 0; i < instructionsArray.length; i++) { - let instruction = instructionsArray[i] - if (instruction.indexOf('chart') >= 0) { - let parts = instruction.split('.') - let timeFrame = parts[1] - let product = parts[2] - let productParts = product.split(',') - product = productParts[0] - productParts = product.split(')') - product = productParts[0] + let instructionsArray = code.split(' ') + for (let i = 0; i < instructionsArray.length; i++) { + let instruction = instructionsArray[i] + if (instruction.indexOf('chart') >= 0) { + let parts = instruction.split('.') + let timeFrame = parts[1] + let product = parts[2] + let productParts = product.split(',') + product = productParts[0] + productParts = product.split(')') + product = productParts[0] - // Example: chart.at01hs.popularSMA.sma200 - chart.at01hs.popularSMA.sma100 < 10 - if (timeFrame !== 'atAnyTimeFrame') { - timeFrame = timeFrame.substring(2, 4) + '-' + timeFrame.substring(4, 7) - } - filters.set(timeFrame + '-' + product, true) + // Example: chart.at01hs.popularSMA.sma200 - chart.at01hs.popularSMA.sma100 < 10 + if (timeFrame !== 'atAnyTimeFrame') { + timeFrame = timeFrame.substring(2, 4) + '-' + timeFrame.substring(4, 7) + } + filters.set(timeFrame + '-' + product, true) + } + } } - } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/NodeChildren.js b/DesignSpace/Workspace/FunctionLibraries/NodeChildren.js index 0165b1ecd..30178d28f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/NodeChildren.js +++ b/DesignSpace/Workspace/FunctionLibraries/NodeChildren.js @@ -1,67 +1,67 @@ -function newNodeChildren () { - thisObject = { - childrenCount: childrenCount - } - - return thisObject - - function childrenCount (parentNode, childNode) { - return countChildrenUiObject(parentNode, childNode) - } - - function countChildrenUiObject (parentNode, childNode) { - let response = { - childrenCount: 0, - childIndex: undefined +function newNodeChildren() { + thisObject = { + childrenCount: childrenCount } - let parentNodeDefinition = getNodeDefinition (parentNode) - if (parentNodeDefinition !== undefined) { - if (parentNodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (parentNode[property.name] !== undefined) { - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - response.childrenCount++ - if (parentNode[property.name].id === childNode.id) { - response.childIndex = response.childrenCount - } - previousPropertyName = property.name - } - } - break - case 'array': { - let nodeDefinition = getNodeDefinition (childNode) - if (nodeDefinition !== undefined) { - let nodePropertyArray = parentNode[property.name] - for (let j = 0; j < nodePropertyArray.length; j++) { - let child = nodePropertyArray[j] - if (nodeDefinition.chainedToSameType === true) { - if (j < 1) { - response.childrenCount++ - if (child.id === childNode.id) { - response.childIndex = response.childrenCount - } - } - } else { - response.childrenCount++ - if (child.id === childNode.id) { - response.childIndex = response.childrenCount - } - } - } - } - } - break - } - } + return thisObject + + function childrenCount(parentNode, childNode) { + return countChildrenUiObject(parentNode, childNode) + } + + function countChildrenUiObject(parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined } - } - } + let parentNodeDefinition = getNodeDefinition(parentNode) + if (parentNodeDefinition !== undefined) { + if (parentNodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - return response - } + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (parentNode[property.name] !== undefined) { + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + response.childrenCount++ + if (parentNode[property.name].id === childNode.id) { + response.childIndex = response.childrenCount + } + previousPropertyName = property.name + } + } + break + case 'array': { + let nodeDefinition = getNodeDefinition(childNode) + if (nodeDefinition !== undefined) { + let nodePropertyArray = parentNode[property.name] + for (let j = 0; j < nodePropertyArray.length; j++) { + let child = nodePropertyArray[j] + if (nodeDefinition.chainedToSameType === true) { + if (j < 1) { + response.childrenCount++ + if (child.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + } else { + response.childrenCount++ + if (child.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + } + } + } + break + } + } + } + } + } + + return response + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js b/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js index 6de8afad8..9d5f920aa 100644 --- a/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js +++ b/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js @@ -1,176 +1,176 @@ -function newNodeCloning () { - const MODULE_NAME = 'Node Cloning' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodeCloning() { + const MODULE_NAME = 'Node Cloning' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - thisObject = { - getNodeClone: getNodeClone - } - return thisObject + thisObject = { + getNodeClone: getNodeClone + } + return thisObject - function getNodeClone (node) { - let idConversionMap = new Map() + function getNodeClone(node) { + let idConversionMap = new Map() - let inmatureClone = cloneNode(node) - let matureClone = redirectReferenceParents(inmatureClone) + let inmatureClone = cloneNode(node) + let matureClone = redirectReferenceParents(inmatureClone) - return matureClone + return matureClone - function cloneNode (node) { - if (node === undefined) { return } - let nodeDefinition = getNodeDefinition(node) - if (nodeDefinition !== undefined) { - let object = { - type: node.type, - name: node.name, - code: node.code, - config: node.config - } - - /* Children Nodes */ - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - object[property.name] = cloneNode(node[property.name]) - } - previousPropertyName = property.name + function cloneNode(node) { + if (node === undefined) { return } + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + let object = { + type: node.type, + name: node.name, + code: node.code, + config: node.config } - break - } - case 'array': { - if (node[property.name] !== undefined) { - let nodePropertyArray = node[property.name] - object[property.name] = [] - for (let m = 0; m < nodePropertyArray.length; m++) { - let protocolNode = cloneNode(nodePropertyArray[m]) - if (protocolNode !== undefined) { - object[property.name].push(protocolNode) + + /* Children Nodes */ + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + object[property.name] = cloneNode(node[property.name]) + } + previousPropertyName = property.name + } + break + } + case 'array': { + if (node[property.name] !== undefined) { + let nodePropertyArray = node[property.name] + object[property.name] = [] + for (let m = 0; m < nodePropertyArray.length; m++) { + let protocolNode = cloneNode(nodePropertyArray[m]) + if (protocolNode !== undefined) { + object[property.name].push(protocolNode) + } + } + } + break + } + } } - } } - break - } + + object.id = newUniqueId() + idConversionMap.set(node.id, object.id) + + object.savedPayload = getSavedPayload(node) + + return object } - } } - object.id = newUniqueId() - idConversionMap.set(node.id, object.id) - - object.savedPayload = getSavedPayload(node) - - return object - } - } - - function redirectReferenceParents (node) { - if (node === undefined) { return } - let nodeDefinition = getNodeDefinition(node) - if (nodeDefinition !== undefined) { - let object = { - type: node.type, - name: node.name, - code: node.code, - config: node.config - } - - /* Children Nodes */ - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - object[property.name] = redirectReferenceParents(node[property.name]) - } - previousPropertyName = property.name + function redirectReferenceParents(node) { + if (node === undefined) { return } + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + let object = { + type: node.type, + name: node.name, + code: node.code, + config: node.config } - break - } - case 'array': { - if (node[property.name] !== undefined) { - let nodePropertyArray = node[property.name] - object[property.name] = [] - for (let m = 0; m < nodePropertyArray.length; m++) { - let protocolNode = redirectReferenceParents(nodePropertyArray[m]) - if (protocolNode !== undefined) { - object[property.name].push(protocolNode) + + /* Children Nodes */ + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + object[property.name] = redirectReferenceParents(node[property.name]) + } + previousPropertyName = property.name + } + break + } + case 'array': { + if (node[property.name] !== undefined) { + let nodePropertyArray = node[property.name] + object[property.name] = [] + for (let m = 0; m < nodePropertyArray.length; m++) { + let protocolNode = redirectReferenceParents(nodePropertyArray[m]) + if (protocolNode !== undefined) { + object[property.name].push(protocolNode) + } + } + } + break + } + } } - } } - break - } + + object.id = node.id + + object.savedPayload = node.savedPayload + + if (object.savedPayload !== undefined) { + if (object.savedPayload.referenceParent !== undefined) { + let newId = idConversionMap.get(object.savedPayload.referenceParent.id) + if (newId !== undefined) { + object.savedPayload.referenceParent.id = newId + } + } + } + + return object + } + } + } + + function getSavedPayload(node) { + if (node.payload === undefined) { return } + let savedPayload = { + position: { + x: node.payload.position.x, + y: node.payload.position.y + }, + targetPosition: { + x: node.payload.targetPosition.x, + y: node.payload.targetPosition.y + }, + floatingObject: { + isPinned: node.payload.floatingObject.isPinned, + isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually), + isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually), + angleToParent: (node.payload.floatingObject.angleToParent), + distanceToParent: (node.payload.floatingObject.distanceToParent), + arrangementStyle: (node.payload.floatingObject.arrangementStyle) + }, + uiObject: { + isRunning: node.payload.uiObject.isRunning, + shortcutKey: node.payload.uiObject.shortcutKey } - } } - object.id = node.id - - object.savedPayload = node.savedPayload - - if (object.savedPayload !== undefined) { - if (object.savedPayload.referenceParent !== undefined) { - let newId = idConversionMap.get(object.savedPayload.referenceParent.id) - if (newId !== undefined) { - object.savedPayload.referenceParent.id = newId + /* Next for the ones that have a reference parent, we include it */ + if (node.payload.referenceParent !== undefined) { + savedPayload.referenceParent = { + type: node.payload.referenceParent.type, + name: node.payload.referenceParent.name, + id: node.payload.referenceParent.id + } + } else { + /* The referenceParent property can be inherited from the previous saved payload. */ + if (node.savedPayload !== undefined) { + savedPayload.referenceParent = node.savedPayload.referenceParent } - } } - return object - } + return savedPayload } - } - - function getSavedPayload (node) { - if (node.payload === undefined) { return } - let savedPayload = { - position: { - x: node.payload.position.x, - y: node.payload.position.y - }, - targetPosition: { - x: node.payload.targetPosition.x, - y: node.payload.targetPosition.y - }, - floatingObject: { - isPinned: node.payload.floatingObject.isPinned, - isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually), - isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually), - angleToParent: (node.payload.floatingObject.angleToParent), - distanceToParent: (node.payload.floatingObject.distanceToParent), - arrangementStyle: (node.payload.floatingObject.arrangementStyle) - }, - uiObject: { - isRunning: node.payload.uiObject.isRunning, - shortcutKey: node.payload.uiObject.shortcutKey - } - } - - /* Next for the ones that have a reference parent, we include it */ - if (node.payload.referenceParent !== undefined) { - savedPayload.referenceParent = { - type: node.payload.referenceParent.type, - name: node.payload.referenceParent.name, - id: node.payload.referenceParent.id - } - } else { - /* The referenceParent property can be inherited from the previous saved payload. */ - if (node.savedPayload !== undefined) { - savedPayload.referenceParent = node.savedPayload.referenceParent - } - } - - return savedPayload - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/NodeDeleter.js b/DesignSpace/Workspace/FunctionLibraries/NodeDeleter.js index 7b17905dc..99b1d656f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/NodeDeleter.js +++ b/DesignSpace/Workspace/FunctionLibraries/NodeDeleter.js @@ -1,138 +1,138 @@ -function newNodeDeleter () { - thisObject = { - deleteWorkspace: deleteWorkspace, - deleteUIObject: deleteUIObject - } - - return thisObject - - function destroyUiObject (node) { - canvas.floatingSpace.uiObjectConstructor.destroyUiObject(node.payload) - } - - function deleteWorkspace (node, rootNodes) { - if (node.rootNodes !== undefined) { - while (node.rootNodes.length > 0) { - let rootNode = node.rootNodes[0] - deleteUIObject(rootNode, rootNodes) - } +function newNodeDeleter() { + thisObject = { + deleteWorkspace: deleteWorkspace, + deleteUIObject: deleteUIObject } - completeDeletion(node, rootNodes) - destroyUiObject(node) - cleanNode(node) - } + return thisObject - function deleteUIObject (node, rootNodes) { - /* First we restore the reference parent to its default state */ - if (node.payload !== undefined && node.payload.referenceParent !== undefined && node.payload.referenceParent.payload !== undefined && node.payload.referenceParent.payload.uiObject !== undefined) { - node.payload.referenceParent.payload.uiObject.isShowing = false + function destroyUiObject(node) { + canvas.floatingSpace.uiObjectConstructor.destroyUiObject(node.payload) } - let nodeDefinition = getNodeDefinition (node) - if (nodeDefinition !== undefined) { - /* Remove all of its own children nodes. */ - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - deleteUIObject(node[property.name], rootNodes) - } - previousPropertyName = property.name - } + function deleteWorkspace(node, rootNodes) { + if (node.rootNodes !== undefined) { + while (node.rootNodes.length > 0) { + let rootNode = node.rootNodes[0] + deleteUIObject(rootNode, rootNodes) } - break - case 'array': { - let nodePropertyArray = node[property.name] - if (nodePropertyArray !== undefined) { - while (nodePropertyArray.length > 0) { - deleteUIObject(nodePropertyArray[0], rootNodes) - } - } - } - break - } } - } - /* Remove node from parent */ - if (node.payload !== undefined) { - if (node.payload.parentNode !== undefined) { - let parentNodeDefinition = getNodeDefinition (node.payload.parentNode) - if (parentNodeDefinition !== undefined) { - if (parentNodeDefinition.properties !== undefined) { - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (nodeDefinition.propertyNameAtParent === property.name) { - switch (property.type) { - case 'node': { - node.payload.parentNode[property.name] = undefined - } - break - case 'array': { - let nodePropertyArray = node.payload.parentNode[property.name] - if (nodePropertyArray !== undefined) { - for (let j = 0; j < nodePropertyArray.length; j++) { - let arrayItem = nodePropertyArray[j] - if (arrayItem.id === node.id) { - /* If this object is chained to the ones of the same type we need to give the next in the chain the reference to the current chain parent */ - if (nodeDefinition.chainedToSameType === true) { - if (j < nodePropertyArray.length - 1) { - let nextArrayItem = nodePropertyArray[j + 1] - nextArrayItem.payload.chainParent = node.payload.chainParent - } + completeDeletion(node, rootNodes) + destroyUiObject(node) + cleanNode(node) + } + + function deleteUIObject(node, rootNodes) { + /* First we restore the reference parent to its default state */ + if (node.payload !== undefined && node.payload.referenceParent !== undefined && node.payload.referenceParent.payload !== undefined && node.payload.referenceParent.payload.uiObject !== undefined) { + node.payload.referenceParent.payload.uiObject.isShowing = false + } + + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + /* Remove all of its own children nodes. */ + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + deleteUIObject(node[property.name], rootNodes) + } + previousPropertyName = property.name } - - nodePropertyArray.splice(j, 1) - } } - } + break + case 'array': { + let nodePropertyArray = node[property.name] + if (nodePropertyArray !== undefined) { + while (nodePropertyArray.length > 0) { + deleteUIObject(nodePropertyArray[0], rootNodes) + } + } + } + break } - break - } } - } } - } + + /* Remove node from parent */ + if (node.payload !== undefined) { + if (node.payload.parentNode !== undefined) { + let parentNodeDefinition = getNodeDefinition(node.payload.parentNode) + if (parentNodeDefinition !== undefined) { + if (parentNodeDefinition.properties !== undefined) { + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (nodeDefinition.propertyNameAtParent === property.name) { + switch (property.type) { + case 'node': { + node.payload.parentNode[property.name] = undefined + } + break + case 'array': { + let nodePropertyArray = node.payload.parentNode[property.name] + if (nodePropertyArray !== undefined) { + for (let j = 0; j < nodePropertyArray.length; j++) { + let arrayItem = nodePropertyArray[j] + if (arrayItem.id === node.id) { + /* If this object is chained to the ones of the same type we need to give the next in the chain the reference to the current chain parent */ + if (nodeDefinition.chainedToSameType === true) { + if (j < nodePropertyArray.length - 1) { + let nextArrayItem = nodePropertyArray[j + 1] + nextArrayItem.payload.chainParent = node.payload.chainParent + } + } + + nodePropertyArray.splice(j, 1) + } + } + } + } + break + } + } + } + } + } + } + } + + completeDeletion(node, rootNodes) + destroyUiObject(node) + cleanNode(node) } - } - - completeDeletion(node, rootNodes) - destroyUiObject(node) - cleanNode(node) } - } - function completeDeletion (node, rootNodes) { - for (let i = 0; i < rootNodes.length; i++) { - let rootNode = rootNodes[i] - if (rootNode.id === node.id) { - rootNodes.splice(i, 1) - return - } + function completeDeletion(node, rootNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.id === node.id) { + rootNodes.splice(i, 1) + return + } + } } - } - function cleanNode (node) { - if (node.payload === undefined) { return } - if (node === undefined) { return } + function cleanNode(node) { + if (node.payload === undefined) { return } + if (node === undefined) { return } - node.payload.targetPosition.x = undefined - node.payload.targetPosition.y = undefined - node.payload.visible = undefined - node.payload.subTitle = undefined - node.payload.title = undefined - node.payload.node = undefined - node.payload.parentNode = undefined - node.payload.chainParent = undefined - node.payload.onMenuItemClick = undefined - node.handle = undefined - node.payload = undefined - node.cleaned = true - } + node.payload.targetPosition.x = undefined + node.payload.targetPosition.y = undefined + node.payload.visible = undefined + node.payload.subTitle = undefined + node.payload.title = undefined + node.payload.node = undefined + node.payload.parentNode = undefined + node.payload.chainParent = undefined + node.payload.onMenuItemClick = undefined + node.handle = undefined + node.payload = undefined + node.cleaned = true + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/OnFocus.js b/DesignSpace/Workspace/FunctionLibraries/OnFocus.js index 716114348..1b8bdff6e 100644 --- a/DesignSpace/Workspace/FunctionLibraries/OnFocus.js +++ b/DesignSpace/Workspace/FunctionLibraries/OnFocus.js @@ -1,56 +1,56 @@ -function newOnFocus () { - thisObject = { - getNodeThatIsOnFocus: getNodeThatIsOnFocus - } - return thisObject +function newOnFocus() { + thisObject = { + getNodeThatIsOnFocus: getNodeThatIsOnFocus + } + return thisObject - function getNodeThatIsOnFocus (node) { - if (node === undefined || node === null) { return } - if (node.payload === undefined) { return } - let nodeDefinition = getNodeDefinition(node) - if (nodeDefinition !== undefined) { - /* First we ask the question to ourself */ - if (node.payload.uiObject.isOnFocus === true) { - return node - } + function getNodeThatIsOnFocus(node) { + if (node === undefined || node === null) { return } + if (node.payload === undefined) { return } + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + /* First we ask the question to ourself */ + if (node.payload.uiObject.isOnFocus === true) { + return node + } - /* Then we check all of its own children nodes. */ - if (node.payload.floatingObject.isCollapsed !== true) { - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] + /* Then we check all of its own children nodes. */ + if (node.payload.floatingObject.isCollapsed !== true) { + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - let child - child = getNodeThatIsOnFocus(node[property.name]) - if (child !== undefined) { - return child - } - } - previousPropertyName = property.name - } - } - break - case 'array': { - let nodePropertyArray = node[property.name] - if (nodePropertyArray !== undefined) { - for (let m = 0; m < nodePropertyArray.length; m++) { - child = getNodeThatIsOnFocus(nodePropertyArray[m]) - if (child !== undefined) { - return child + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + let child + child = getNodeThatIsOnFocus(node[property.name]) + if (child !== undefined) { + return child + } + } + previousPropertyName = property.name + } + } + break + case 'array': { + let nodePropertyArray = node[property.name] + if (nodePropertyArray !== undefined) { + for (let m = 0; m < nodePropertyArray.length; m++) { + child = getNodeThatIsOnFocus(nodePropertyArray[m]) + if (child !== undefined) { + return child + } + } + } + } + break + } } - } } - } - break } - } } - } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js index a6a533549..7284030f1 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -1,187 +1,187 @@ -function newProtocolNode () { - const MODULE_NAME = 'Protocol Node' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newProtocolNode() { + const MODULE_NAME = 'Protocol Node' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - thisObject = { - getProtocolNode: getProtocolNode - } - return thisObject + thisObject = { + getProtocolNode: getProtocolNode + } + return thisObject - function getProtocolNode (node, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, lightingPath) { - if (node === undefined) { return } - if (node.payload === undefined) { return } + function getProtocolNode(node, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, lightingPath) { + if (node === undefined) { return } + if (node.payload === undefined) { return } - let nodeDefinition = getNodeDefinition(node) - if (nodeDefinition !== undefined) { - if (removePersonalData === true && nodeDefinition.isPersonalData === true) { return } - let object = { - type: node.type, - name: node.name, - code: node.code, - config: node.config - } - - /* Children Nodes */ - if (nodeDefinition.properties !== undefined) { - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.type) { - case 'node': { - if (node[property.name] !== undefined) { - if (lightingPath === undefined) { - object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseConfig, includeIds, includeReferencesInSavedPayload, includePayload) - } else { - let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType) - if (newLightingPath !== undefined) { - object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) - } - } - } - break + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + if (removePersonalData === true && nodeDefinition.isPersonalData === true) { return } + let object = { + type: node.type, + name: node.name, + code: node.code, + config: node.config } - case 'array': { - if (node[property.name] !== undefined) { - if (lightingPath === undefined) { - let nodePropertyArray = node[property.name] - object[property.name] = [] - for (let m = 0; m < nodePropertyArray.length; m++) { - let protocolNode = getProtocolNode(nodePropertyArray[m], removePersonalData, parseConfig, includeIds, includeReferencesInSavedPayload, includePayload) - if (protocolNode !== undefined) { - object[property.name].push(protocolNode) + + /* Children Nodes */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + if (node[property.name] !== undefined) { + if (lightingPath === undefined) { + object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseConfig, includeIds, includeReferencesInSavedPayload, includePayload) + } else { + let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType) + if (newLightingPath !== undefined) { + object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) + } + } + } + break + } + case 'array': { + if (node[property.name] !== undefined) { + if (lightingPath === undefined) { + let nodePropertyArray = node[property.name] + object[property.name] = [] + for (let m = 0; m < nodePropertyArray.length; m++) { + let protocolNode = getProtocolNode(nodePropertyArray[m], removePersonalData, parseConfig, includeIds, includeReferencesInSavedPayload, includePayload) + if (protocolNode !== undefined) { + object[property.name].push(protocolNode) + } + } + } else { + let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType) + if (newLightingPath !== undefined) { + let nodePropertyArray = node[property.name] + object[property.name] = [] + for (let m = 0; m < nodePropertyArray.length; m++) { + let protocolNode = getProtocolNode(nodePropertyArray[m], removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) + if (protocolNode !== undefined) { + object[property.name].push(protocolNode) + } + } + } + } + } + break + } } - } - } else { - let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType) - if (newLightingPath !== undefined) { - let nodePropertyArray = node[property.name] - object[property.name] = [] - for (let m = 0; m < nodePropertyArray.length; m++) { - let protocolNode = getProtocolNode(nodePropertyArray[m], removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) - if (protocolNode !== undefined) { - object[property.name].push(protocolNode) - } - } - } } - } - break } - } + + /* Parent Nodes */ + if (node.payload.parentNode !== undefined) { + let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type) + if (newLightingPath !== undefined) { + object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) + } + } + if (node.payload.referenceParent !== undefined) { + let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.referenceParent.type) + if (newLightingPath !== undefined) { + object.referenceParent = getProtocolNode(node.payload.referenceParent, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) + } + } + + if (parseConfig && object.config !== undefined && nodeDefinition.editors !== undefined) { + if (nodeDefinition.editors.config === true) { + try { + object.config = JSON.parse(node.config) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> err = ' + err.stack) } + if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.type = ' + node.type) } + if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.name = ' + node.name) } + if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.config = ' + node.config) } + if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.id = ' + node.id) } + } + } + } + + if (includeIds) { + object.id = node.id + } + if (includePayload) { + object.savedPayload = getSavedPayload(node, includeReferencesInSavedPayload) + } + + return object } - } - - /* Parent Nodes */ - if (node.payload.parentNode !== undefined) { - let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type) - if (newLightingPath !== undefined) { - object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) - } - } - if (node.payload.referenceParent !== undefined) { - let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.referenceParent.type) - if (newLightingPath !== undefined) { - object.referenceParent = getProtocolNode(node.payload.referenceParent, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) - } - } - - if (parseConfig && object.config !== undefined && nodeDefinition.editors !== undefined) { - if (nodeDefinition.editors.config === true) { - try { - object.config = JSON.parse(node.config) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> err = ' + err.stack) } - if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.type = ' + node.type) } - if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.name = ' + node.name) } - if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.config = ' + node.config) } - if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.id = ' + node.id) } - } - } - } - - if (includeIds) { - object.id = node.id - } - if (includePayload) { - object.savedPayload = getSavedPayload(node, includeReferencesInSavedPayload) - } - - return object - } - } - - function getNewLightingPath (lightingPath, currentNodeType, nextNodeType) { - if (lightingPath === undefined) { return } - - if (currentNodeType === undefined) { return } - if (nextNodeType === undefined) { return } - - let currentNodePosition = lightingPath.indexOf('->' + currentNodeType + '->') - let nextNodePosition = lightingPath.indexOf('->' + nextNodeType + '->') - - let newLightingPath = lightingPath.substring(nextNodePosition, lightingPath.length + 1) - - if (nextNodePosition > currentNodePosition) { - return newLightingPath - } else { - return - } - } - - function getSavedPayload (node, includeReferencesInSavedPayload) { - if (node.payload === undefined) { return } - let savedPayload = { - position: { - x: node.payload.position.x, - y: node.payload.position.y - }, - targetPosition: { - x: node.payload.targetPosition.x, - y: node.payload.targetPosition.y - }, - floatingObject: { - isPinned: node.payload.floatingObject.isPinned, - isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually), - isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually), - angleToParent: (node.payload.floatingObject.angleToParent), - distanceToParent: (node.payload.floatingObject.distanceToParent), - arrangementStyle: (node.payload.floatingObject.arrangementStyle) - }, - uiObject: { - isRunning: node.payload.uiObject.isRunning, - shortcutKey: node.payload.uiObject.shortcutKey - } } - if (node.payload.frame !== undefined) { - savedPayload.frame = { - position: { - x: node.payload.frame.position.x, - y: node.payload.frame.position.y - }, - width: node.payload.frame.width, - height: node.payload.frame.height, - radius: node.payload.frame.radius - } + function getNewLightingPath(lightingPath, currentNodeType, nextNodeType) { + if (lightingPath === undefined) { return } + + if (currentNodeType === undefined) { return } + if (nextNodeType === undefined) { return } + + let currentNodePosition = lightingPath.indexOf('->' + currentNodeType + '->') + let nextNodePosition = lightingPath.indexOf('->' + nextNodeType + '->') + + let newLightingPath = lightingPath.substring(nextNodePosition, lightingPath.length + 1) + + if (nextNodePosition > currentNodePosition) { + return newLightingPath + } else { + return + } } - if (includeReferencesInSavedPayload) { - /* Next for the ones that have a reference parent, we include it */ - if (node.payload.referenceParent !== undefined) { - savedPayload.referenceParent = { - type: node.payload.referenceParent.type, - name: node.payload.referenceParent.name, - id: node.payload.referenceParent.id + function getSavedPayload(node, includeReferencesInSavedPayload) { + if (node.payload === undefined) { return } + let savedPayload = { + position: { + x: node.payload.position.x, + y: node.payload.position.y + }, + targetPosition: { + x: node.payload.targetPosition.x, + y: node.payload.targetPosition.y + }, + floatingObject: { + isPinned: node.payload.floatingObject.isPinned, + isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually), + isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually), + angleToParent: (node.payload.floatingObject.angleToParent), + distanceToParent: (node.payload.floatingObject.distanceToParent), + arrangementStyle: (node.payload.floatingObject.arrangementStyle) + }, + uiObject: { + isRunning: node.payload.uiObject.isRunning, + shortcutKey: node.payload.uiObject.shortcutKey + } } - } else { - /* The referenceParent property can be inherited from the previous saved payload. */ - if (node.savedPayload !== undefined) { - savedPayload.referenceParent = node.savedPayload.referenceParent + + if (node.payload.frame !== undefined) { + savedPayload.frame = { + position: { + x: node.payload.frame.position.x, + y: node.payload.frame.position.y + }, + width: node.payload.frame.width, + height: node.payload.frame.height, + radius: node.payload.frame.radius + } } - } + + if (includeReferencesInSavedPayload) { + /* Next for the ones that have a reference parent, we include it */ + if (node.payload.referenceParent !== undefined) { + savedPayload.referenceParent = { + type: node.payload.referenceParent.type, + name: node.payload.referenceParent.name, + id: node.payload.referenceParent.id + } + } else { + /* The referenceParent property can be inherited from the previous saved payload. */ + if (node.savedPayload !== undefined) { + savedPayload.referenceParent = node.savedPayload.referenceParent + } + } + } + return savedPayload } - return savedPayload - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/ReferenceAttachDetach.js b/DesignSpace/Workspace/FunctionLibraries/ReferenceAttachDetach.js index f9b6b3cd5..5b8ffe35a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ReferenceAttachDetach.js +++ b/DesignSpace/Workspace/FunctionLibraries/ReferenceAttachDetach.js @@ -1,37 +1,37 @@ -function newReferenceAttachDetach () { - thisObject = { - referenceDetachNode: referenceDetachNode, - referenceAttachNode: referenceAttachNode - } +function newReferenceAttachDetach() { + thisObject = { + referenceDetachNode: referenceDetachNode, + referenceAttachNode: referenceAttachNode + } - return thisObject + return thisObject - function referenceDetachNode (node) { - completeDetachment(node) - } + function referenceDetachNode(node) { + completeDetachment(node) + } - function referenceAttachNode (node, attachToNode, rootNodes) { - completeAttachment(node, attachToNode) - } + function referenceAttachNode(node, attachToNode, rootNodes) { + completeAttachment(node, attachToNode) + } - function completeAttachment (node, attachToNode) { - node.payload.referenceParent = attachToNode - } + function completeAttachment(node, attachToNode) { + node.payload.referenceParent = attachToNode + } - function completeDetachment (node) { - if (node.payload !== undefined !== undefined) { - if (node.payload.referenceParent !== undefined) { - if (node.payload.referenceParent.payload !== undefined) { - if (node.payload.referenceParent.payload.uiObject !== undefined) { - node.payload.referenceParent.payload.uiObject.isShowing = false - } + function completeDetachment(node) { + if (node.payload !== undefined !== undefined) { + if (node.payload.referenceParent !== undefined) { + if (node.payload.referenceParent.payload !== undefined) { + if (node.payload.referenceParent.payload.uiObject !== undefined) { + node.payload.referenceParent.payload.uiObject.isShowing = false + } + } + } } - } - } - node.payload.referenceParent = undefined - if (node.savedPayload !== undefined) { - node.savedPayload.referenceParent = undefined + node.payload.referenceParent = undefined + if (node.savedPayload !== undefined) { + node.savedPayload.referenceParent = undefined + } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index e552a7c53..1dcf1c978 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -1,185 +1,185 @@ -function newSessionFunctions () { - thisObject = { - runSession: runSession, - stopSession: stopSession - } - - return thisObject - - function runSession (node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, resume, callBackFunction) { - if (validations(node) !== true) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return +function newSessionFunctions() { + thisObject = { + runSession: runSession, + stopSession: stopSession } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode - let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + return thisObject - node.payload.uiObject.run(eventsServerClient, callBackFunction) + function runSession(node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, resume, callBackFunction) { + if (validations(node) !== true) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } - let key = node.name + '-' + node.type + '-' + node.id + let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) - let lightingPath = '' + - 'Trading System->' + - 'Parameters->' + - 'Base Asset->Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->' + - 'Exchange Account Asset->Asset->' + - 'Trading Strategy->' + - 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + - 'Announcement->Formula->' + - 'Open Stage->Initial Definition->Open Execution->' + - 'Position Size->Position Rate->Formula->' + - 'Initial Stop->Initial Take Profit->' + - 'Manage Stage->' + - 'Managed Stop Loss->Managed Take Profit->' + - 'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' + - 'Situation->Condition->Javascript Code->' + - 'Close Stage->Close Execution->' + - 'Announcement->Formula->' + - 'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' + - 'Create Order Event->Cancel Order Event->' + - 'Position Size->Position Rate->Formula->' + - 'Situation->Condition->Javascript Code->' + - 'Market Order->Limit Order->' + - 'Simulated Exchange Events->Simulated Partial Fill->Simulated Actual Rate->Simulated Fees Paid->Formula->' + node.payload.uiObject.run(eventsServerClient, callBackFunction) - let tradingSystem = functionLibraryProtocolNode.getProtocolNode(node.tradingSystemReference.payload.referenceParent, false, true, true, false, false, lightingPath) + let key = node.name + '-' + node.type + '-' + node.id - lightingPath = '' + - 'Trading Engine->' + - 'Dynamic Indicators->Indicator Function->Formula->' + - 'Episode->Current->Last->Previous->' + - 'Episode Counters->Episode Statistics->' + - 'Periods->Strategies->Positions->Orders->Hits->Fails->' + - 'Profit Loss->Hit Ratio->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + - 'Formula->' + - 'Candle->' + - 'Begin->End->Open->Close->Min->Max->Index->' + - 'Balance->Base Asset->Quoted Asset->' + - 'Distance To Event->' + - 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + - 'Strategy->' + - 'Serial Number->Identifier->Begin->End->Strategy Name->Index->Trigger Stage Status->Open Stage Status->Manage Stage Status->Close Stage Status->Status->Begin Rate->End Rate->Situation Name->' + - 'Strategy Counters->Periods->' + - 'Position->' + - 'Serial Number->Identifier->Begin->End->Rate->Size->Open Stage Orders Size->Open Stage Filled Size->Close Stage Orders Size->Close Stage Filled Size->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + - 'Stop Loss->Stop Loss Stage->Stop Loss Phase->' + - 'Take Profit->Take Profit Stage->Take Profit Phase->' + - 'Position Counters->Periods->' + - 'Position Statistics->Profit Loss->Days->ROI->Hit Fail->User Defined Statistic->' + - 'Formula->' + - 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + - 'Market Order->Limit Order->' + - 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Size->Exit Type->Status->Order Name->Algorithm Name->Situation Name->' + - 'Order Counters->Periods->' + - 'Order Statistics->Size Filled->Percentage Filled->Amount Received->Actual Rate->Fees Paid->Days->User Defined Statistic->' + let lightingPath = '' + + 'Trading System->' + + 'Parameters->' + + 'Base Asset->Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->' + + 'Exchange Account Asset->Asset->' + + 'Trading Strategy->' + + 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + + 'Announcement->Formula->' + + 'Open Stage->Initial Definition->Open Execution->' + + 'Position Size->Position Rate->Formula->' + + 'Initial Stop->Initial Take Profit->' + + 'Manage Stage->' + + 'Managed Stop Loss->Managed Take Profit->' + + 'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' + + 'Situation->Condition->Javascript Code->' + + 'Close Stage->Close Execution->' + + 'Announcement->Formula->' + + 'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' + + 'Create Order Event->Cancel Order Event->' + + 'Position Size->Position Rate->Formula->' + + 'Situation->Condition->Javascript Code->' + + 'Market Order->Limit Order->' + + 'Simulated Exchange Events->Simulated Partial Fill->Simulated Actual Rate->Simulated Fees Paid->Formula->' - let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) + let tradingSystem = functionLibraryProtocolNode.getProtocolNode(node.tradingSystemReference.payload.referenceParent, false, true, true, false, false, lightingPath) - lightingPath = '' + - 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + - 'Parameters->' + - 'Session Base Asset->Session Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->Snapshots->User Defined Parameters->' + - 'Exchange Account Asset->Asset->' + - 'Social Bots->Telegram Bot->' + lightingPath = '' + + 'Trading Engine->' + + 'Dynamic Indicators->Indicator Function->Formula->' + + 'Episode->Current->Last->Previous->' + + 'Episode Counters->Episode Statistics->' + + 'Periods->Strategies->Positions->Orders->Hits->Fails->' + + 'Profit Loss->Hit Ratio->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + + 'Formula->' + + 'Candle->' + + 'Begin->End->Open->Close->Min->Max->Index->' + + 'Balance->Base Asset->Quoted Asset->' + + 'Distance To Event->' + + 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + + 'Strategy->' + + 'Serial Number->Identifier->Begin->End->Strategy Name->Index->Trigger Stage Status->Open Stage Status->Manage Stage Status->Close Stage Status->Status->Begin Rate->End Rate->Situation Name->' + + 'Strategy Counters->Periods->' + + 'Position->' + + 'Serial Number->Identifier->Begin->End->Rate->Size->Open Stage Orders Size->Open Stage Filled Size->Close Stage Orders Size->Close Stage Filled Size->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + + 'Stop Loss->Stop Loss Stage->Stop Loss Phase->' + + 'Take Profit->Take Profit Stage->Take Profit Phase->' + + 'Position Counters->Periods->' + + 'Position Statistics->Profit Loss->Days->ROI->Hit Fail->User Defined Statistic->' + + 'Formula->' + + 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + + 'Market Order->Limit Order->' + + 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Size->Exit Type->Status->Order Name->Algorithm Name->Situation Name->' + + 'Order Counters->Periods->' + + 'Order Statistics->Size Filled->Percentage Filled->Amount Received->Actual Rate->Fees Paid->Days->User Defined Statistic->' - let session = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath) + let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) - let dependencyFilter = functionLibraryDependenciesFilter.createFilter(node.tradingSystemReference.payload.referenceParent) + lightingPath = '' + + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + + 'Parameters->' + + 'Session Base Asset->Session Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->Snapshots->User Defined Parameters->' + + 'Exchange Account Asset->Asset->' + + 'Social Bots->Telegram Bot->' - /* Raise event to run the session */ - let event = { - appSchema: JSON.stringify(APP_SCHEMA_ARRAY), - session: JSON.stringify(session), - tradingSystem: JSON.stringify(tradingSystem), - tradingEngine: JSON.stringify(tradingEngine), - dependencyFilter: JSON.stringify(dependencyFilter), - resume: resume + let session = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath) + + let dependencyFilter = functionLibraryDependenciesFilter.createFilter(node.tradingSystemReference.payload.referenceParent) + + /* Raise event to run the session */ + let event = { + appSchema: JSON.stringify(APP_SCHEMA_ARRAY), + session: JSON.stringify(session), + tradingSystem: JSON.stringify(tradingSystem), + tradingEngine: JSON.stringify(tradingEngine), + dependencyFilter: JSON.stringify(dependencyFilter), + resume: resume + } + + eventsServerClient.raiseEvent(key, 'Run Session', event) + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } } - eventsServerClient.raiseEvent(key, 'Run Session', event) + function stopSession(node, functionLibraryProtocolNode, callBackFunction) { + if (validations(node) !== true) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - } + let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) - function stopSession (node, functionLibraryProtocolNode, callBackFunction) { - if (validations(node) !== true) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return + let key = node.name + '-' + node.type + '-' + node.id + eventsServerClient.raiseEvent(key, 'Stop Session') + + node.payload.uiObject.stop(callBackFunction) } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode - let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + function validations(node) { + if (node.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.') + return + } - let key = node.name + '-' + node.type + '-' + node.id - eventsServerClient.raiseEvent(key, 'Stop Session') + if (node.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside a Trading Process Instance.') + return + } - node.payload.uiObject.stop(callBackFunction) - } + if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside a Task.') + return + } - function validations (node) { - if (node.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.') - return + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside a Task Manager.') + return + } + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside Exchange Tasks.') + return + } + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside a Testing or Production Environment.') + return + } + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside a Network Node.') + return + } + + if (node.payload.parentNode.payload.uiObject.isRunning !== true) { + node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running.') + return + } + + if (node.tradingSystemReference === undefined) { + node.payload.uiObject.setErrorMessage('Session needs a child Trading System Reference.') + return + } + + if (node.tradingEngineReference === undefined) { + node.payload.uiObject.setErrorMessage('Session needs a child Trading Engine Reference.') + return + } + + if (node.tradingSystemReference.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('Trading System Reference needs to reference a Trading System.') + return + } + + if (node.tradingEngineReference.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('Trading Engine Reference needs to reference a Trading Engine.') + return + } + return true } - - if (node.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs to be inside a Trading Process Instance.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs to be inside a Task.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs to be inside a Task Manager.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs to be inside Exchange Tasks.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs to be inside a Testing or Production Environment.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Session needs to be inside a Network Node.') - return - } - - if (node.payload.parentNode.payload.uiObject.isRunning !== true) { - node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running.') - return - } - - if (node.tradingSystemReference === undefined) { - node.payload.uiObject.setErrorMessage('Session needs a child Trading System Reference.') - return - } - - if (node.tradingEngineReference === undefined) { - node.payload.uiObject.setErrorMessage('Session needs a child Trading Engine Reference.') - return - } - - if (node.tradingSystemReference.payload.referenceParent === undefined) { - node.payload.uiObject.setErrorMessage('Trading System Reference needs to reference a Trading System.') - return - } - - if (node.tradingEngineReference.payload.referenceParent === undefined) { - node.payload.uiObject.setErrorMessage('Trading Engine Reference needs to reference a Trading Engine.') - return - } - return true - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/ShortcutKeys.js b/DesignSpace/Workspace/FunctionLibraries/ShortcutKeys.js index 2cd449769..94d7058eb 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ShortcutKeys.js +++ b/DesignSpace/Workspace/FunctionLibraries/ShortcutKeys.js @@ -1,55 +1,55 @@ -function newShortcutKeys () { - thisObject = { - getNodeByShortcutKey: getNodeByShortcutKey - } - return thisObject +function newShortcutKeys() { + thisObject = { + getNodeByShortcutKey: getNodeByShortcutKey + } + return thisObject - function getNodeByShortcutKey (node, searchingKey) { - if (node === undefined) { return } - let nodeDefinition = getNodeDefinition (node) - if (nodeDefinition !== undefined) { - /* Check Self first */ - if (node.payload.uiObject.shortcutKey === searchingKey) { - return node - } + function getNodeByShortcutKey(node, searchingKey) { + if (node === undefined) { return } + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + /* Check Self first */ + if (node.payload.uiObject.shortcutKey === searchingKey) { + return node + } - /* Check all of its own children nodes. */ - if (node.payload.floatingObject.isCollapsed !== true) { - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] + /* Check all of its own children nodes. */ + if (node.payload.floatingObject.isCollapsed !== true) { + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - let child - child = getNodeByShortcutKey(node[property.name], searchingKey) - if (child !== undefined) { - return child - } - } - previousPropertyName = property.name - } - } - break - case 'array': { - let nodePropertyArray = node[property.name] - if (nodePropertyArray !== undefined) { - for (let m = 0; m < nodePropertyArray.length; m++) { - child = getNodeByShortcutKey(nodePropertyArray[m], searchingKey) - if (child !== undefined) { - return child + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + let child + child = getNodeByShortcutKey(node[property.name], searchingKey) + if (child !== undefined) { + return child + } + } + previousPropertyName = property.name + } + } + break + case 'array': { + let nodePropertyArray = node[property.name] + if (nodePropertyArray !== undefined) { + for (let m = 0; m < nodePropertyArray.length; m++) { + child = getNodeByShortcutKey(nodePropertyArray[m], searchingKey) + if (child !== undefined) { + return child + } + } + } + } + break + } } - } } - } - break } - } } - } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/SuperScripts.js b/DesignSpace/Workspace/FunctionLibraries/SuperScripts.js index e8e6b8a90..bbb214083 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SuperScripts.js +++ b/DesignSpace/Workspace/FunctionLibraries/SuperScripts.js @@ -1,90 +1,90 @@ -function newSuperScriptsFunctions () { - thisObject = { - runSuperScript: runSuperScript - } +function newSuperScriptsFunctions() { + thisObject = { + runSuperScript: runSuperScript + } - return thisObject + return thisObject - function runSuperScript (node, rootNodes, functionLibraryNodeCloning, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { - try { - let clone = functionLibraryNodeCloning.getNodeClone - let executionResult = true - let superAction = node + function runSuperScript(node, rootNodes, functionLibraryNodeCloning, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + try { + let clone = functionLibraryNodeCloning.getNodeClone + let executionResult = true + let superAction = node - function setup (templateClone, target, exchange, exchangeNodeType, arrayPropertyName) { - spawnPosition.x = target.payload.position.x - spawnPosition.y = target.payload.position.y + function setup(templateClone, target, exchange, exchangeNodeType, arrayPropertyName) { + spawnPosition.x = target.payload.position.x + spawnPosition.y = target.payload.position.y - if (exchange === undefined) { - functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, target, target) - } else { - let definition = getNodeDefinition (target) - for (let i = 0; i < definition.properties.length; i++) { - let property = definition.properties[i] - if (property.childType === exchangeNodeType) { - let exchanges = target[property.name] - if (exchanges === undefined) { - exchanges = [] - } - let targetExchange - for (let j = 0; j < exchanges.length; j++) { - let thisExchange = exchanges[j] - if (thisExchange.payload.referenceParent !== undefined) { - if (thisExchange.payload.referenceParent.id === exchange.id) { - targetExchange = thisExchange - } + if (exchange === undefined) { + functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, target, target) + } else { + let definition = getNodeDefinition(target) + for (let i = 0; i < definition.properties.length; i++) { + let property = definition.properties[i] + if (property.childType === exchangeNodeType) { + let exchanges = target[property.name] + if (exchanges === undefined) { + exchanges = [] + } + let targetExchange + for (let j = 0; j < exchanges.length; j++) { + let thisExchange = exchanges[j] + if (thisExchange.payload.referenceParent !== undefined) { + if (thisExchange.payload.referenceParent.id === exchange.id) { + targetExchange = thisExchange + } + } + } + if (targetExchange === undefined) { + targetExchange = functionLibraryUiObjectsFromNodes.addUIObject(target, exchangeNodeType) + targetExchange.payload.referenceParent = exchange + } + let nodesArray = targetExchange[arrayPropertyName] + nodesArray.push(templateClone) + functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, targetExchange, targetExchange) + } + } } - } - if (targetExchange === undefined) { - targetExchange = functionLibraryUiObjectsFromNodes.addUIObject(target, exchangeNodeType) - targetExchange.payload.referenceParent = exchange - } - let nodesArray = targetExchange[arrayPropertyName] - nodesArray.push(templateClone) - functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, targetExchange, targetExchange) } - } - } - } - function deleteNode (node) { - functionLibraryNodeDeleter.deleteUIObject(node, rootNodes) - } + function deleteNode(node) { + functionLibraryNodeDeleter.deleteUIObject(node, rootNodes) + } - /* Validations */ - if (executionResult === true && node.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Super Action node needs a Parent Node.') - executionResult = false - } - if (executionResult === true && node.payload.referenceParent === undefined) { - node.payload.uiObject.setErrorMessage('Super Action node needs to reference a Master Script Node.') - executionResult = false - } - if (executionResult === true && node.payload.referenceParent.javascriptCode === undefined) { - node.payload.uiObject.setErrorMessage('Master Script Node needs to have a child Javascript Code Node.') - executionResult = false - } + /* Validations */ + if (executionResult === true && node.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Super Action node needs a Parent Node.') + executionResult = false + } + if (executionResult === true && node.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('Super Action node needs to reference a Master Script Node.') + executionResult = false + } + if (executionResult === true && node.payload.referenceParent.javascriptCode === undefined) { + node.payload.uiObject.setErrorMessage('Master Script Node needs to have a child Javascript Code Node.') + executionResult = false + } - let masterScript = node.payload.referenceParent + let masterScript = node.payload.referenceParent - eval(masterScript.javascriptCode.code) + eval(masterScript.javascriptCode.code) - let masterScriptInstance = newNewMasterScriptInstance() + let masterScriptInstance = newNewMasterScriptInstance() - if (executionResult === true) { - executionResult = masterScriptInstance.runValidations(superAction, masterScript) - } - if (executionResult === true) { - executionResult = masterScriptInstance.runScript(superAction, masterScript) - } - if (executionResult === true) { - superAction.payload.uiObject.setValue('Execution Completed Successfully') - } else { - superAction.payload.uiObject.setValue('Execution Failed') - } - } catch (err) { - superAction.payload.uiObject.setErrorMessage(err.message) - superAction.payload.uiObject.setValue('Execution Failed') + if (executionResult === true) { + executionResult = masterScriptInstance.runValidations(superAction, masterScript) + } + if (executionResult === true) { + executionResult = masterScriptInstance.runScript(superAction, masterScript) + } + if (executionResult === true) { + superAction.payload.uiObject.setValue('Execution Completed Successfully') + } else { + superAction.payload.uiObject.setValue('Execution Failed') + } + } catch (err) { + superAction.payload.uiObject.setErrorMessage(err.message) + superAction.payload.uiObject.setValue('Execution Failed') + } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 832e7bcd8..db9aa5e3f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -1,228 +1,228 @@ -function newTaskFunctions () { - thisObject = { - runTask: runTask, - stopTask: stopTask, - runAllTasks: runAllTasks, - stopAllTasks: stopAllTasks, - runAllTaskManagers: runAllTaskManagers, - stopAllTaskManagers: stopAllTaskManagers, - runAllExchangeTasks: runAllExchangeTasks, - stopAllExchangeTasks: stopAllExchangeTasks - } - - return thisObject - - function runTask (node, functionLibraryProtocolNode, isDebugging, callBackFunction) { - if (validations(node) !== true) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return +function newTaskFunctions() { + thisObject = { + runTask: runTask, + stopTask: stopTask, + runAllTasks: runAllTasks, + stopAllTasks: stopAllTasks, + runAllTaskManagers: runAllTaskManagers, + stopAllTaskManagers: stopAllTaskManagers, + runAllExchangeTasks: runAllExchangeTasks, + stopAllExchangeTasks: stopAllExchangeTasks } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode - let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + return thisObject - for (let i = 0; i < node.bot.processes.length; i++) { - let process = node.bot.processes[i] - process.payload.uiObject.run(eventsServerClient) + function runTask(node, functionLibraryProtocolNode, isDebugging, callBackFunction) { + if (validations(node) !== true) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + + for (let i = 0; i < node.bot.processes.length; i++) { + let process = node.bot.processes[i] + process.payload.uiObject.run(eventsServerClient) + } + + let taskLightingPath = '->Task->' + + 'Sensor Bot Instance->' + + 'Indicator Bot Instance->Time Frames Filter->' + + 'Trading Bot Instance->' + + 'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' + + 'Market Reference->' + + 'Key Reference->Exchange Account Key->' + + 'Market->Exchange Markets->Crypto Exchange->' + + 'Market Base Asset->Market Quoted Asset->Asset->' + + 'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' + + 'Process Definition->' + + 'Process Output->Output Dataset->Dataset Definition->Product Definition->' + + 'Process Dependencies->' + + 'Status Dependency->Status Report->Process Definition->' + + 'Data Dependency->Dataset Definition->Product Definition->' + + 'Record Definition->Record Property->Formula->' + + 'Data Building Procedure->' + + 'Procedure Initialization->Javascript Code->' + + 'Procedure Loop->Javascript Code->' + + 'Calculations Procedure->' + + 'Procedure Initialization->Javascript Code->' + + 'Procedure Loop->Javascript Code->' + + 'Status Report->' + + 'Execution Finished Event->' + + 'Execution Started Event->Execution Finished Event->Process Definition->' + + 'Sensor Bot->' + + 'Indicator Bot->' + + 'Trading Bot->' + + 'Data Mine->' + + let taskDefinition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, taskLightingPath) + + let networkLightingPath = '->Network->Network Node->' + + 'Data Storage->Session Independent Data->Exchange Data Products->' + + 'Single Market Data->Data Product->Product Definition->' + + 'Data Mining->Testing Environment->Production Environment->' + + 'Exchange Tasks->Crypto Exchange->' + + 'Task Manager->Task->' + + 'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' + + 'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' + + 'Paper Trading Session->Forward Testing Session->Backtesting Session->Live Trading Session->' + + 'Market Reference->Market->' + + 'Process Definition->' + + let networkDefinition = functionLibraryProtocolNode.getProtocolNode(networkNode.payload.parentNode, false, true, true, false, false, networkLightingPath) + + let event = { + taskId: node.id, + taskName: node.name, + taskDefinition: JSON.stringify(taskDefinition), + networkDefinition: JSON.stringify(networkDefinition) + } + + if (isDebugging === true) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + eventsServerClient.raiseEvent('Task Server', 'Debug Task Started', event) + return + } + + node.payload.uiObject.run(eventsServerClient, callBackFunction) + eventsServerClient.raiseEvent('Task Manager', 'Run Task', event) } - let taskLightingPath = '->Task->' + - 'Sensor Bot Instance->' + - 'Indicator Bot Instance->Time Frames Filter->' + - 'Trading Bot Instance->' + - 'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' + - 'Market Reference->' + - 'Key Reference->Exchange Account Key->' + - 'Market->Exchange Markets->Crypto Exchange->' + - 'Market Base Asset->Market Quoted Asset->Asset->' + - 'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' + - 'Process Definition->' + - 'Process Output->Output Dataset->Dataset Definition->Product Definition->' + - 'Process Dependencies->' + - 'Status Dependency->Status Report->Process Definition->' + - 'Data Dependency->Dataset Definition->Product Definition->' + - 'Record Definition->Record Property->Formula->' + - 'Data Building Procedure->' + - 'Procedure Initialization->Javascript Code->' + - 'Procedure Loop->Javascript Code->' + - 'Calculations Procedure->' + - 'Procedure Initialization->Javascript Code->' + - 'Procedure Loop->Javascript Code->' + - 'Status Report->' + - 'Execution Finished Event->' + - 'Execution Started Event->Execution Finished Event->Process Definition->' + - 'Sensor Bot->' + - 'Indicator Bot->' + - 'Trading Bot->' + - 'Data Mine->' + function stopTask(node, functionLibraryProtocolNode, callBackFunction) { + if (validations(node) !== true) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } - let taskDefinition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, taskLightingPath) + let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) - let networkLightingPath = '->Network->Network Node->' + - 'Data Storage->Session Independent Data->Exchange Data Products->' + - 'Single Market Data->Data Product->Product Definition->' + - 'Data Mining->Testing Environment->Production Environment->' + - 'Exchange Tasks->Crypto Exchange->' + - 'Task Manager->Task->' + - 'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' + - 'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' + - 'Paper Trading Session->Forward Testing Session->Backtesting Session->Live Trading Session->' + - 'Market Reference->Market->' + - 'Process Definition->' + let event = { + taskId: node.id, + taskName: node.name + } - let networkDefinition = functionLibraryProtocolNode.getProtocolNode(networkNode.payload.parentNode, false, true, true, false, false, networkLightingPath) + node.payload.uiObject.stop(callBackFunction) + eventsServerClient.raiseEvent('Task Manager', 'Stop Task', event) - let event = { - taskId: node.id, - taskName: node.name, - taskDefinition: JSON.stringify(taskDefinition), - networkDefinition: JSON.stringify(networkDefinition) + if (node.bot === undefined) { return } + if (node.bot.processes.length === 0) { return } + + for (let i = 0; i < node.bot.processes.length; i++) { + let process = node.bot.processes[i] + process.payload.uiObject.stop() + } } - if (isDebugging === true) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - eventsServerClient.raiseEvent('Task Server', 'Debug Task Started', event) - return + function validations(node) { + if (node.bot === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to have a Bot Instance.') + return + } + if (node.bot.processes.length === 0) { + node.payload.uiObject.setErrorMessage('Task Bot Instance needs to have al least once Process Instance.') + return + } + + if (node.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside a Task Manager.') + return + } + + if (node.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside Exchange Tasks.') + return + } + + if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment or a Data Mining node.') + return + } + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside a Network Node.') + return + } + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside a Network.') + return + } + + let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + if (loadPropertyFromNodeConfig(networkNode.payload, 'host') === undefined) { + node.payload.uiObject.setErrorMessage('Network Node needs to have a valid Host property at its config.') + return + } + + if (loadPropertyFromNodeConfig(networkNode.payload, 'webPort') === undefined) { + node.payload.uiObject.setErrorMessage('Network Node needs to have a valid webPort property at its config.') + return + } + + if (loadPropertyFromNodeConfig(networkNode.payload, 'webSocketsPort') === undefined) { + node.payload.uiObject.setErrorMessage('Network Node needs to have a valid webSocketsPort property at its config.') + return + } + + return true } - node.payload.uiObject.run(eventsServerClient, callBackFunction) - eventsServerClient.raiseEvent('Task Manager', 'Run Task', event) - } + function runAllTasks(taskManager, functionLibraryProtocolNode) { + for (let i = 0; i < taskManager.tasks.length; i++) { + let node = taskManager.tasks[i] + let menu = node.payload.uiObject.menu - function stopTask (node, functionLibraryProtocolNode, callBackFunction) { - if (validations(node) !== true) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return + menu.internalClick('Run Task') + } } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode - let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + function stopAllTasks(taskManager, functionLibraryProtocolNode) { + for (let i = 0; i < taskManager.tasks.length; i++) { + let node = taskManager.tasks[i] + let menu = node.payload.uiObject.menu - let event = { - taskId: node.id, - taskName: node.name + menu.internalClick('Stop Task') + } } - node.payload.uiObject.stop(callBackFunction) - eventsServerClient.raiseEvent('Task Manager', 'Stop Task', event) + function runAllTaskManagers(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.taskManagers.length; i++) { + let node = parent.taskManagers[i] + let menu = node.payload.uiObject.menu - if (node.bot === undefined) { return } - if (node.bot.processes.length === 0) { return } - - for (let i = 0; i < node.bot.processes.length; i++) { - let process = node.bot.processes[i] - process.payload.uiObject.stop() - } - } - - function validations (node) { - if (node.bot === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to have a Bot Instance.') - return - } - if (node.bot.processes.length === 0) { - node.payload.uiObject.setErrorMessage('Task Bot Instance needs to have al least once Process Instance.') - return + menu.internalClick('Run All Tasks') + menu.internalClick('Run All Tasks') + } } - if (node.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Task Manager.') - return + function stopAllTaskManagers(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.taskManagers.length; i++) { + let node = parent.taskManagers[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Tasks') + menu.internalClick('Stop All Tasks') + } + } + function runAllExchangeTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.exchangeTasks.length; i++) { + let node = parent.exchangeTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Run All Task Managers') + menu.internalClick('Run All Task Managers') + } } - if (node.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside Exchange Tasks.') - return + function stopAllExchangeTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.exchangeTasks.length; i++) { + let node = parent.exchangeTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Task Managers') + menu.internalClick('Stop All Task Managers') + } } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment or a Data Mining node.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Network Node.') - return - } - - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Network.') - return - } - - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode - if (loadPropertyFromNodeConfig(networkNode.payload, 'host') === undefined) { - node.payload.uiObject.setErrorMessage('Network Node needs to have a valid Host property at its config.') - return - } - - if (loadPropertyFromNodeConfig(networkNode.payload, 'webPort') === undefined) { - node.payload.uiObject.setErrorMessage('Network Node needs to have a valid webPort property at its config.') - return - } - - if (loadPropertyFromNodeConfig(networkNode.payload, 'webSocketsPort') === undefined) { - node.payload.uiObject.setErrorMessage('Network Node needs to have a valid webSocketsPort property at its config.') - return - } - - return true - } - - function runAllTasks (taskManager, functionLibraryProtocolNode) { - for (let i = 0; i < taskManager.tasks.length; i++) { - let node = taskManager.tasks[i] - let menu = node.payload.uiObject.menu - - menu.internalClick('Run Task') - } - } - - function stopAllTasks (taskManager, functionLibraryProtocolNode) { - for (let i = 0; i < taskManager.tasks.length; i++) { - let node = taskManager.tasks[i] - let menu = node.payload.uiObject.menu - - menu.internalClick('Stop Task') - } - } - - function runAllTaskManagers (parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.taskManagers.length; i++) { - let node = parent.taskManagers[i] - let menu = node.payload.uiObject.menu - - menu.internalClick('Run All Tasks') - menu.internalClick('Run All Tasks') - } - } - - function stopAllTaskManagers (parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.taskManagers.length; i++) { - let node = parent.taskManagers[i] - let menu = node.payload.uiObject.menu - - menu.internalClick('Stop All Tasks') - menu.internalClick('Stop All Tasks') - } - } - function runAllExchangeTasks (parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.exchangeTasks.length; i++) { - let node = parent.exchangeTasks[i] - let menu = node.payload.uiObject.menu - - menu.internalClick('Run All Task Managers') - menu.internalClick('Run All Task Managers') - } - } - - function stopAllExchangeTasks (parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.exchangeTasks.length; i++) { - let node = parent.exchangeTasks[i] - let menu = node.payload.uiObject.menu - - menu.internalClick('Stop All Task Managers') - menu.internalClick('Stop All Task Managers') - } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index c852cb93f..10edaa3a4 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -1,605 +1,605 @@ -function newUiObjectsFromNodes () { - thisObject = { - runTasks: runTasks, - runSessions: runSessions, - recreateWorkspace: recreateWorkspace, - tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents, - createUiObjectFromNode: createUiObjectFromNode, - addUIObject: addUIObject, - addMissingChildren: addMissingChildren - } - - let mapOfReferenceChildren = new Map() - let mapOfNodes - let tasksToRun - let sessionsToRun - - return thisObject - - function recreateWorkspace (node, callBackFunction) { - mapOfNodes = new Map() - tasksToRun = [] - sessionsToRun = [] - - addIncludedNodes() - - function addIncludedNodes () { - let blobService = newFileStorage() - - // if (node.config === undefined) { - node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Example-ETH-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' - // } - - let config = JSON.parse(node.config) - let includeDataMines = config.includeDataMines - let includeTradingSystems = config.includeTradingSystems - let includeSuperScripts = config.includeSuperScripts - - let totalIncluded = 0 - - for (let i = 0; i < includeDataMines.length; i++) { - let name = includeDataMines[i] - blobService.getFileFromHost('DataMines' + '/' + name, onFileReceived, true) - function onFileReceived (err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Data Mine') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { - rootNodes.splice(i, 1) - } - } - } - } - receivedNode.isIncluded = true - node.rootNodes.push(receivedNode) - totalIncluded++ - if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { - addUserDefinedNodes() - } - } - } - - for (let i = 0; i < includeTradingSystems.length; i++) { - let name = includeTradingSystems[i] - blobService.getFileFromHost('TradingSystems' + '/' + name, onFileReceived, true) - function onFileReceived (err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Trading System') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { - rootNodes.splice(i, 1) - } - } - } - } - receivedNode.isIncluded = true - node.rootNodes.push(receivedNode) - totalIncluded++ - if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { - addUserDefinedNodes() - } - } - } - - for (let i = 0; i < includeSuperScripts.length; i++) { - let name = includeSuperScripts[i] - blobService.getFileFromHost('SuperScripts' + '/' + name, onFileReceived, true) - function onFileReceived (err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Super Scripts') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { - rootNodes.splice(i, 1) - } - } - } - } - receivedNode.isIncluded = true - node.rootNodes.push(receivedNode) - totalIncluded++ - if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { - addUserDefinedNodes() - } - } - } +function newUiObjectsFromNodes() { + thisObject = { + runTasks: runTasks, + runSessions: runSessions, + recreateWorkspace: recreateWorkspace, + tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents, + createUiObjectFromNode: createUiObjectFromNode, + addUIObject: addUIObject, + addMissingChildren: addMissingChildren } - function addUserDefinedNodes () { - /* Create the workspace UI OBject and then continue with the root nodes. */ - createUiObject(false, 'Workspace', node.name, node, undefined, undefined, 'Workspace') - if (node.rootNodes !== undefined) { - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - createUiObjectFromNode(rootNode, undefined, undefined) - } - } + let mapOfReferenceChildren = new Map() + let mapOfNodes + let tasksToRun + let sessionsToRun - tryToConnectChildrenWithReferenceParents() + return thisObject - if (callBackFunction !== undefined) { - callBackFunction() // The recreation of the workspace is complete - } - } - } + function recreateWorkspace(node, callBackFunction) { + mapOfNodes = new Map() + tasksToRun = [] + sessionsToRun = [] - function runTasks () { - for (let i = 0; i < tasksToRun.length; i++) { - let node = tasksToRun[i] - node.payload.uiObject.menu.internalClick('Run Task') - } - tasksToRun = undefined - } + addIncludedNodes() - function runSessions () { - for (let i = 0; i < sessionsToRun.length; i++) { - let node = sessionsToRun[i] - node.payload.uiObject.menu.internalClick('Run Session') - } - sessionsToRun = undefined - } + function addIncludedNodes() { + let blobService = newFileStorage() - function tryToConnectChildrenWithReferenceParents () { - /* We reconstruct here the reference relationships. */ - for (const [key, node] of mapOfNodes) { - if (node.payload === undefined) { continue } - if (node.payload.referenceParent !== undefined) { - if (node.payload.referenceParent.cleaned === true) { - node.payload.referenceParent = mapOfNodes.get(node.payload.referenceParent.id) - continue // We were referencing a deleted node, so we replace it potentially with a newly created one. - } else { - continue // In this case the reference is already good. - } - } - if (node.savedPayload !== undefined) { - if (node.savedPayload.referenceParent !== undefined) { // these are children recreated - node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) - } - } - } - } + // if (node.config === undefined) { + node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Example-ETH-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' + // } - function migrateCodeToConfig (node, nodeDefinition) { - /* Code needed to Migrante from Beta 5 to Beta a Workspace */ - if (nodeDefinition.editors !== undefined) { - if (nodeDefinition.editors.config === true) { - if (node.code !== undefined) { - node.config = node.code - node.code = undefined - } - } - } - } + let config = JSON.parse(node.config) + let includeDataMines = config.includeDataMines + let includeTradingSystems = config.includeTradingSystems + let includeSuperScripts = config.includeSuperScripts - function createUiObjectFromNode (node, parentNode, chainParent, positionOffset) { - /* Code needed to Migrante from Beta 5 to Beta 6 a Trading System - if (node.type === 'Take Profit') { - node.type = 'Managed Take Profit' - } - if (node.type === 'Stop') { - node.type = 'Managed Stop Loss' - } - */ + let totalIncluded = 0 - /* Get node definition */ - let nodeDefinition = getNodeDefinition(node) - if (nodeDefinition !== undefined) { - migrateCodeToConfig(node, nodeDefinition) - - /* Resolve Initial Values */ - if (nodeDefinition.initialValues !== undefined) { - if (nodeDefinition.initialValues.code !== undefined) { - if (node.code === undefined) { - node.code = nodeDefinition.initialValues.code - } - } - if (nodeDefinition.initialValues.config !== undefined) { - if (node.config === undefined) { - node.config = nodeDefinition.initialValues.config - } - } - } - - /* For the cases where an node is not chained to its parent but to the one at the parent before it at its collection */ - if (nodeDefinition.chainedToSameType === true) { - if (parentNode !== undefined) { - let parentNodeDefinition = getNodeDefinition(parentNode) - if (parentNodeDefinition !== undefined) { - if (parentNodeDefinition.properties !== undefined) { - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (property.childType === node.type) { - if (property.type === 'array') { - if (parentNode[property.name] !== undefined) { - if (parentNode[property.name].length > 1) { - let nodeChildren = parentNode[property.name] - for (let j = 0; j < nodeChildren.length; j++) { - if (node.id === nodeChildren[j].id) { - if (j > 0) { - chainParent = nodeChildren[j - 1] + for (let i = 0; i < includeDataMines.length; i++) { + let name = includeDataMines[i] + blobService.getFileFromHost('DataMines' + '/' + name, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') + return + } + let receivedNode = JSON.parse(text) + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.type === 'Data Mine') { + if (rootNode.config !== undefined) { + let config = JSON.parse(rootNode.config) + if (config.name === name) { + rootNodes.splice(i, 1) + } } - } } - } + } + receivedNode.isIncluded = true + node.rootNodes.push(receivedNode) + totalIncluded++ + if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { + addUserDefinedNodes() } - } } - } } - } - } - } - /* Create Self */ - createUiObject(false, node.type, node.name, node, parentNode, chainParent, node.type, positionOffset) - /* Create Children */ - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - if (node[property.name] !== undefined) { - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - createUiObjectFromNode(node[property.name], node, node, positionOffset) - previousPropertyName = property.name + for (let i = 0; i < includeTradingSystems.length; i++) { + let name = includeTradingSystems[i] + blobService.getFileFromHost('TradingSystems' + '/' + name, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') + return + } + let receivedNode = JSON.parse(text) + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.type === 'Trading System') { + if (rootNode.config !== undefined) { + let config = JSON.parse(rootNode.config) + if (config.name === name) { + rootNodes.splice(i, 1) + } + } + } + } + receivedNode.isIncluded = true + node.rootNodes.push(receivedNode) + totalIncluded++ + if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { + addUserDefinedNodes() + } } - } - break - case 'array': { - let nodePropertyArray = node[property.name] - for (let m = 0; m < nodePropertyArray.length; m++) { - let arrayItem = nodePropertyArray[m] - createUiObjectFromNode(arrayItem, node, node, positionOffset) + } + + for (let i = 0; i < includeSuperScripts.length; i++) { + let name = includeSuperScripts[i] + blobService.getFileFromHost('SuperScripts' + '/' + name, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') + return + } + let receivedNode = JSON.parse(text) + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.type === 'Super Scripts') { + if (rootNode.config !== undefined) { + let config = JSON.parse(rootNode.config) + if (config.name === name) { + rootNodes.splice(i, 1) + } + } + } + } + receivedNode.isIncluded = true + node.rootNodes.push(receivedNode) + totalIncluded++ + if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { + addUserDefinedNodes() + } } - } - break } - } else { - if (property.type === 'array') { - node[property.name] = [] - } - } } - } - } - } - function addUIObject (parentNode, type) { - let object = { - name: 'New ' + type, - type: type - } - - let parentNodeDefinition = getNodeDefinition(parentNode) - if (parentNodeDefinition === undefined) { - console.log('Cannot addUIOBject from parent of ' + type + ' because that type it is not defined at the APP_SCHEMA.') - } - /* Resolve Initial Values */ - let nodeDefinition = getNodeDefinition(object) - - if (nodeDefinition === undefined) { - console.log('Cannot addUIOBject of ' + type + ' because that type it is not defined at the APP_SCHEMA.') - } - - if (nodeDefinition.initialValues !== undefined) { - if (nodeDefinition.initialValues.code !== undefined) { - object.code = nodeDefinition.initialValues.code - } - } - if (nodeDefinition.initialValues !== undefined) { - if (nodeDefinition.initialValues.config !== undefined) { - object.config = nodeDefinition.initialValues.config - } - } - - if (nodeDefinition.isHierarchyHead === true) { - parentNode.rootNodes.push(object) - createUiObject(true, object.type, object.name, object, parentNode, undefined) - return object - } - - /* For the cases where an node is not chained to its parent but to the one at the parent before it at its collection */ - let chainParent = parentNode - if (nodeDefinition.chainedToSameType === true) { - if (parentNodeDefinition.properties !== undefined) { - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (property.childType === type) { - if (property.type === 'array') { - if (parentNode[property.name] !== undefined) { - if (parentNode[property.name].length > 0) { - let nodeChildren = parentNode[property.name] - chainParent = nodeChildren[nodeChildren.length - 1] + function addUserDefinedNodes() { + /* Create the workspace UI OBject and then continue with the root nodes. */ + createUiObject(false, 'Workspace', node.name, node, undefined, undefined, 'Workspace') + if (node.rootNodes !== undefined) { + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + createUiObjectFromNode(rootNode, undefined, undefined) } - } } - } - } - } - } - /* Create Empty Arrays for properties of type Array */ - if (nodeDefinition.properties !== undefined) { - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - if (property.type === 'array') { - object[property.name] = [] - } - } - } + tryToConnectChildrenWithReferenceParents() - if (nodeDefinition !== undefined) { - if (nodeDefinition.initialValues !== undefined) { - if (nodeDefinition.initialValues.code !== undefined) { - object.code = nodeDefinition.initialValues.code - } - if (nodeDefinition.initialValues.config !== undefined) { - object.config = nodeDefinition.initialValues.config - } - } - } - - /* Connect to Parent */ - if (parentNodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < parentNodeDefinition.properties.length; i++) { - let property = parentNodeDefinition.properties[i] - if (property.childType === type) { - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - parentNode[property.name] = object - previousPropertyName = property.name - } + if (callBackFunction !== undefined) { + callBackFunction() // The recreation of the workspace is complete } - break - case 'array': { - if (parentNode[property.name] === undefined) { - parentNode[property.name] = [] - } - if (property.maxItems !== undefined) { - if (parentNode[property.name].length < property.maxItems) { - parentNode[property.name].push(object) + } + } + + function runTasks() { + for (let i = 0; i < tasksToRun.length; i++) { + let node = tasksToRun[i] + node.payload.uiObject.menu.internalClick('Run Task') + } + tasksToRun = undefined + } + + function runSessions() { + for (let i = 0; i < sessionsToRun.length; i++) { + let node = sessionsToRun[i] + node.payload.uiObject.menu.internalClick('Run Session') + } + sessionsToRun = undefined + } + + function tryToConnectChildrenWithReferenceParents() { + /* We reconstruct here the reference relationships. */ + for (const [key, node] of mapOfNodes) { + if (node.payload === undefined) { continue } + if (node.payload.referenceParent !== undefined) { + if (node.payload.referenceParent.cleaned === true) { + node.payload.referenceParent = mapOfNodes.get(node.payload.referenceParent.id) + continue // We were referencing a deleted node, so we replace it potentially with a newly created one. } else { - return // Object can not be created. + continue // In this case the reference is already good. } - } else { - parentNode[property.name].push(object) - } } - break - } - } - } - } - - createUiObject(true, object.type, object.name, object, parentNode, chainParent) - - /* Auto Add more Children */ - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (property.autoAdd === true) { - addUIObject(object, property.childType) - previousPropertyName = property.name - } + if (node.savedPayload !== undefined) { + if (node.savedPayload.referenceParent !== undefined) { // these are children recreated + node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) + } } - } - break - case 'array': { - if (property.autoAdd === true) { - if (object[property.name] === undefined) { - object[property.name] = [] - } - addUIObject(object, property.childType) + } + } + + function migrateCodeToConfig(node, nodeDefinition) { + /* Code needed to Migrante from Beta 5 to Beta a Workspace */ + if (nodeDefinition.editors !== undefined) { + if (nodeDefinition.editors.config === true) { + if (node.code !== undefined) { + node.config = node.code + node.code = undefined + } } - } - break } - } } - return object - } + function createUiObjectFromNode(node, parentNode, chainParent, positionOffset) { + /* Code needed to Migrante from Beta 5 to Beta 6 a Trading System + if (node.type === 'Take Profit') { + node.type = 'Managed Take Profit' + } + if (node.type === 'Stop') { + node.type = 'Managed Stop Loss' + } + */ - function addMissingChildren (node) { - let nodeDefinition = getNodeDefinition(node) + /* Get node definition */ + let nodeDefinition = getNodeDefinition(node) + if (nodeDefinition !== undefined) { + migrateCodeToConfig(node, nodeDefinition) - /* Connect to Parent */ - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - if (property.type === 'node') { - if (property.name !== previousPropertyName) { - if (node[property.name] === undefined) { - addUIObject(node, property.childType) - previousPropertyName = property.name + /* Resolve Initial Values */ + if (nodeDefinition.initialValues !== undefined) { + if (nodeDefinition.initialValues.code !== undefined) { + if (node.code === undefined) { + node.code = nodeDefinition.initialValues.code + } + } + if (nodeDefinition.initialValues.config !== undefined) { + if (node.config === undefined) { + node.config = nodeDefinition.initialValues.config + } + } + } + + /* For the cases where an node is not chained to its parent but to the one at the parent before it at its collection */ + if (nodeDefinition.chainedToSameType === true) { + if (parentNode !== undefined) { + let parentNodeDefinition = getNodeDefinition(parentNode) + if (parentNodeDefinition !== undefined) { + if (parentNodeDefinition.properties !== undefined) { + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (property.childType === node.type) { + if (property.type === 'array') { + if (parentNode[property.name] !== undefined) { + if (parentNode[property.name].length > 1) { + let nodeChildren = parentNode[property.name] + for (let j = 0; j < nodeChildren.length; j++) { + if (node.id === nodeChildren[j].id) { + if (j > 0) { + chainParent = nodeChildren[j - 1] + } + } + } + } + } + } + } + } + } + } + } + } + /* Create Self */ + createUiObject(false, node.type, node.name, node, parentNode, chainParent, node.type, positionOffset) + + /* Create Children */ + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + if (node[property.name] !== undefined) { + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + createUiObjectFromNode(node[property.name], node, node, positionOffset) + previousPropertyName = property.name + } + } + break + case 'array': { + let nodePropertyArray = node[property.name] + for (let m = 0; m < nodePropertyArray.length; m++) { + let arrayItem = nodePropertyArray[m] + createUiObjectFromNode(arrayItem, node, node, positionOffset) + } + } + break + } + } else { + if (property.type === 'array') { + node[property.name] = [] + } + } + } } - } } - } - } - } - - function createUiObject (userAddingNew, uiObjectType, name, node, parentNode, chainParent, title, positionOffset) { - let payload = {} - - /* Mechanism related to keeping references when cloning */ - if (node.id === undefined) { - node.id = newUniqueId() - } else { - let testNode = mapOfNodes.get(node.id) - if (testNode !== undefined && testNode.cleaned !== true) { - node.id = newUniqueId() - } } - /* Default Naming */ - if (name === '' || name === undefined) { name = 'My ' + uiObjectType } - - /* If we are creating this object as the result of restoring a backup, share or clone, we will bring some of the saved properties to the new running instance. */ - if (userAddingNew === false && uiObjectType !== 'Workspace') { - /* This following info can not be missing. */ - if (node.savedPayload === undefined) { - console.log('Node ' + node.type + ' without savedPayload.', node) - return - } - if (node.savedPayload.position === undefined) { - console.log('Node ' + node.type + ' without savedPayload.position.', node) - return - } - if (node.savedPayload.targetPosition === undefined) { - console.log('Node ' + node.type + ' without savedPayload.targetPosition.', node) - return - } - - /* If there is not a position offset, which happens when we are dropping a node into the designer, we create a cero vector then. */ - if (positionOffset === undefined) { - positionOffset = { - x: 0, - y: 0 + function addUIObject(parentNode, type) { + let object = { + name: 'New ' + type, + type: type } - } - /* Adding the offset to the saved positions. */ - node.savedPayload.targetPosition.x = node.savedPayload.targetPosition.x + positionOffset.x - node.savedPayload.targetPosition.y = node.savedPayload.targetPosition.y + positionOffset.y - node.savedPayload.position.x = node.savedPayload.position.x + positionOffset.x - node.savedPayload.position.y = node.savedPayload.position.y + positionOffset.y - - /* Transferring the saved payload properties into the running instance being created. */ - payload.targetPosition = { - x: node.savedPayload.targetPosition.x, - y: node.savedPayload.targetPosition.y - } - node.savedPayload.targetPosition = undefined - - /* Reference children connection to parents */ - if (node.savedPayload.referenceParent !== undefined) { - payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) - - if (payload.referenceParent !== undefined) { - mapOfReferenceChildren.set(node.id, node) + let parentNodeDefinition = getNodeDefinition(parentNode) + if (parentNodeDefinition === undefined) { + console.log('Cannot addUIOBject from parent of ' + type + ' because that type it is not defined at the APP_SCHEMA.') } - } + /* Resolve Initial Values */ + let nodeDefinition = getNodeDefinition(object) + + if (nodeDefinition === undefined) { + console.log('Cannot addUIOBject of ' + type + ' because that type it is not defined at the APP_SCHEMA.') + } + + if (nodeDefinition.initialValues !== undefined) { + if (nodeDefinition.initialValues.code !== undefined) { + object.code = nodeDefinition.initialValues.code + } + } + if (nodeDefinition.initialValues !== undefined) { + if (nodeDefinition.initialValues.config !== undefined) { + object.config = nodeDefinition.initialValues.config + } + } + + if (nodeDefinition.isHierarchyHead === true) { + parentNode.rootNodes.push(object) + createUiObject(true, object.type, object.name, object, parentNode, undefined) + return object + } + + /* For the cases where an node is not chained to its parent but to the one at the parent before it at its collection */ + let chainParent = parentNode + if (nodeDefinition.chainedToSameType === true) { + if (parentNodeDefinition.properties !== undefined) { + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (property.childType === type) { + if (property.type === 'array') { + if (parentNode[property.name] !== undefined) { + if (parentNode[property.name].length > 0) { + let nodeChildren = parentNode[property.name] + chainParent = nodeChildren[nodeChildren.length - 1] + } + } + } + } + } + } + } + + /* Create Empty Arrays for properties of type Array */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + if (property.type === 'array') { + object[property.name] = [] + } + } + } + + if (nodeDefinition !== undefined) { + if (nodeDefinition.initialValues !== undefined) { + if (nodeDefinition.initialValues.code !== undefined) { + object.code = nodeDefinition.initialValues.code + } + if (nodeDefinition.initialValues.config !== undefined) { + object.config = nodeDefinition.initialValues.config + } + } + } + + /* Connect to Parent */ + if (parentNodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < parentNodeDefinition.properties.length; i++) { + let property = parentNodeDefinition.properties[i] + if (property.childType === type) { + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + parentNode[property.name] = object + previousPropertyName = property.name + } + } + break + case 'array': { + if (parentNode[property.name] === undefined) { + parentNode[property.name] = [] + } + if (property.maxItems !== undefined) { + if (parentNode[property.name].length < property.maxItems) { + parentNode[property.name].push(object) + } else { + return // Object can not be created. + } + } else { + parentNode[property.name].push(object) + } + } + break + } + } + } + } + + createUiObject(true, object.type, object.name, object, parentNode, chainParent) + + /* Auto Add more Children */ + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (property.autoAdd === true) { + addUIObject(object, property.childType) + previousPropertyName = property.name + } + } + } + break + case 'array': { + if (property.autoAdd === true) { + if (object[property.name] === undefined) { + object[property.name] = [] + } + addUIObject(object, property.childType) + } + } + break + } + } + } + + return object } - /* If we are adding a new object, then we set the initial values for position and targetPosition */ - if (userAddingNew === true || uiObjectType === 'Workspace') { - /* Workspace allways to the spawn position */ - if (uiObjectType === 'Workspace') { - payload.position = { - x: spawnPosition.x, - y: spawnPosition.y - } - } + function addMissingChildren(node) { + let nodeDefinition = getNodeDefinition(node) - /* Chain parent pointing to the position of the chain parent if defined. */ - if (chainParent === undefined) { - payload.targetPosition = { - x: spawnPosition.x, - y: spawnPosition.y + /* Connect to Parent */ + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + if (property.type === 'node') { + if (property.name !== previousPropertyName) { + if (node[property.name] === undefined) { + addUIObject(node, property.childType) + previousPropertyName = property.name + } + } + } + } } - } else { - payload.targetPosition = { - x: chainParent.payload.position.x, - y: chainParent.payload.position.y - } - } } - /* Setting the title */ - if (title !== undefined) { - payload.subTitle = title - } else { - payload.subTitle = uiObjectType - } + function createUiObject(userAddingNew, uiObjectType, name, node, parentNode, chainParent, title, positionOffset) { + let payload = {} - payload.visible = true - payload.title = name - payload.node = node - payload.parentNode = parentNode - payload.chainParent = chainParent - payload.onMenuItemClick = canvas.designSpace.workspace.onMenuItemClick - - node.payload = payload - node.type = uiObjectType - - /* - Now we copy the possible frame saved to the payload where it can be used. A saved frame stores the position of a a chartingSpace object related to a node. - This will prevent that if those charting space objects never get activated, that the frame information is lost when the workspace is saved. - */ - if (node.savedPayload !== undefined) { - if (node.savedPayload.frame !== undefined) { - let frame = { - position: { - x: 0, - y: 0 - } + /* Mechanism related to keeping references when cloning */ + if (node.id === undefined) { + node.id = newUniqueId() + } else { + let testNode = mapOfNodes.get(node.id) + if (testNode !== undefined && testNode.cleaned !== true) { + node.id = newUniqueId() + } } - frame.position.x = node.savedPayload.frame.position.x - frame.position.y = node.savedPayload.frame.position.y - frame.width = node.savedPayload.frame.width - frame.height = node.savedPayload.frame.height - frame.radius = node.savedPayload.frame.radius - saveFrame(payload, frame) - } - } - /* Now we mount the floating object where the UIOBject will be laying on top of */ - canvas.floatingSpace.uiObjectConstructor.createUiObject(userAddingNew, payload) + /* Default Naming */ + if (name === '' || name === undefined) { name = 'My ' + uiObjectType } - mapOfNodes.set(node.id, node) + /* If we are creating this object as the result of restoring a backup, share or clone, we will bring some of the saved properties to the new running instance. */ + if (userAddingNew === false && uiObjectType !== 'Workspace') { + /* This following info can not be missing. */ + if (node.savedPayload === undefined) { + console.log('Node ' + node.type + ' without savedPayload.', node) + return + } + if (node.savedPayload.position === undefined) { + console.log('Node ' + node.type + ' without savedPayload.position.', node) + return + } + if (node.savedPayload.targetPosition === undefined) { + console.log('Node ' + node.type + ' without savedPayload.targetPosition.', node) + return + } - /* Check if there are tasks to run */ - if (userAddingNew === false && uiObjectType === 'Task' && node.savedPayload !== undefined) { - if (node.savedPayload.uiObject.isRunning === true) { - if (node.payload.parentNode !== undefined) { - if (tasksToRun !== undefined) { // it might be undefined when you are spawning a task that was running while backed up - tasksToRun.push(node) - } + /* If there is not a position offset, which happens when we are dropping a node into the designer, we create a cero vector then. */ + if (positionOffset === undefined) { + positionOffset = { + x: 0, + y: 0 + } + } + + /* Adding the offset to the saved positions. */ + node.savedPayload.targetPosition.x = node.savedPayload.targetPosition.x + positionOffset.x + node.savedPayload.targetPosition.y = node.savedPayload.targetPosition.y + positionOffset.y + node.savedPayload.position.x = node.savedPayload.position.x + positionOffset.x + node.savedPayload.position.y = node.savedPayload.position.y + positionOffset.y + + /* Transferring the saved payload properties into the running instance being created. */ + payload.targetPosition = { + x: node.savedPayload.targetPosition.x, + y: node.savedPayload.targetPosition.y + } + node.savedPayload.targetPosition = undefined + + /* Reference children connection to parents */ + if (node.savedPayload.referenceParent !== undefined) { + payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) + + if (payload.referenceParent !== undefined) { + mapOfReferenceChildren.set(node.id, node) + } + } + } + + /* If we are adding a new object, then we set the initial values for position and targetPosition */ + if (userAddingNew === true || uiObjectType === 'Workspace') { + /* Workspace allways to the spawn position */ + if (uiObjectType === 'Workspace') { + payload.position = { + x: spawnPosition.x, + y: spawnPosition.y + } + } + + /* Chain parent pointing to the position of the chain parent if defined. */ + if (chainParent === undefined) { + payload.targetPosition = { + x: spawnPosition.x, + y: spawnPosition.y + } + } else { + payload.targetPosition = { + x: chainParent.payload.position.x, + y: chainParent.payload.position.y + } + } + } + + /* Setting the title */ + if (title !== undefined) { + payload.subTitle = title + } else { + payload.subTitle = uiObjectType + } + + payload.visible = true + payload.title = name + payload.node = node + payload.parentNode = parentNode + payload.chainParent = chainParent + payload.onMenuItemClick = canvas.designSpace.workspace.onMenuItemClick + + node.payload = payload + node.type = uiObjectType + + /* + Now we copy the possible frame saved to the payload where it can be used. A saved frame stores the position of a a chartingSpace object related to a node. + This will prevent that if those charting space objects never get activated, that the frame information is lost when the workspace is saved. + */ + if (node.savedPayload !== undefined) { + if (node.savedPayload.frame !== undefined) { + let frame = { + position: { + x: 0, + y: 0 + } + } + frame.position.x = node.savedPayload.frame.position.x + frame.position.y = node.savedPayload.frame.position.y + frame.width = node.savedPayload.frame.width + frame.height = node.savedPayload.frame.height + frame.radius = node.savedPayload.frame.radius + saveFrame(payload, frame) + } + } + + /* Now we mount the floating object where the UIOBject will be laying on top of */ + canvas.floatingSpace.uiObjectConstructor.createUiObject(userAddingNew, payload) + + mapOfNodes.set(node.id, node) + + /* Check if there are tasks to run */ + if (userAddingNew === false && uiObjectType === 'Task' && node.savedPayload !== undefined) { + if (node.savedPayload.uiObject.isRunning === true) { + if (node.payload.parentNode !== undefined) { + if (tasksToRun !== undefined) { // it might be undefined when you are spawning a task that was running while backed up + tasksToRun.push(node) + } + } + } } - } - } /* Check if there are sessions to run */ - if (userAddingNew === false && node.savedPayload !== undefined) { - if (uiObjectType === 'Live Trading Session' || uiObjectType === 'Fordward Testing Session' || uiObjectType === 'Backtesting Session' || uiObjectType === 'Paper Trading Session') { - if (node.savedPayload.uiObject.isRunning === true) { - if (node.payload.parentNode !== undefined) { - if (sessionsToRun !== undefined) { // it might be undefined when you are spawning a session that was running while backed up - sessionsToRun.push(node) + if (userAddingNew === false && node.savedPayload !== undefined) { + if (uiObjectType === 'Live Trading Session' || uiObjectType === 'Fordward Testing Session' || uiObjectType === 'Backtesting Session' || uiObjectType === 'Paper Trading Session') { + if (node.savedPayload.uiObject.isRunning === true) { + if (node.payload.parentNode !== undefined) { + if (sessionsToRun !== undefined) { // it might be undefined when you are spawning a session that was running while backed up + sessionsToRun.push(node) + } + } + } } - } } - } } - } } diff --git a/DesignSpace/Workspace/FunctionLibraries/WebhookFunctions.js b/DesignSpace/Workspace/FunctionLibraries/WebhookFunctions.js index ca7e6b2f1..609a94c5a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/WebhookFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/WebhookFunctions.js @@ -1,22 +1,22 @@ -function newWebhookFunctions () { - thisObject = { - sendTestMessage: sendTestMessage - } +function newWebhookFunctions() { + thisObject = { + sendTestMessage: sendTestMessage + } - return thisObject + return thisObject - function sendTestMessage (node, callBackFunction) { - let testMessage = loadPropertyFromNodeConfig(node.payload, 'testMessage') - let letURL = loadPropertyFromNodeConfig(node.payload, 'webhookURL') + function sendTestMessage(node, callBackFunction) { + let testMessage = loadPropertyFromNodeConfig(node.payload, 'testMessage') + let letURL = loadPropertyFromNodeConfig(node.payload, 'webhookURL') - callServer(testMessage, letURL, onResponse) + callServer(testMessage, letURL, onResponse) - function onResponse (err) { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - } else { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } + function onResponse(err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + } else { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } } - } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 5f1c80761..7008cb873 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -1,621 +1,621 @@ -function newWorkspace () { - const MODULE_NAME = 'Workspace' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newWorkspace() { + const MODULE_NAME = 'Workspace' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - workspaceNode: undefined, - container: undefined, - enabled: false, - nodeChildren: undefined, - eventsServerClients: new Map(), - replaceWorkspaceByLoadingOne: replaceWorkspaceByLoadingOne, - save: saveWorkspace, - getHierarchyHeads: getHierarchyHeads, - getHierarchyHeadsById: getHierarchyHeadsById, - getNodeThatIsOnFocus: getNodeThatIsOnFocus, - getNodeByShortcutKey: getNodeByShortcutKey, - stopAllRunningTasks: stopAllRunningTasks, - onMenuItemClick: onMenuItemClick, - physics: physics, - draw: draw, - spawn: spawn, - chainDetachNode: chainDetachNode, - chainAttachNode: chainAttachNode, - referenceDetachNode: referenceDetachNode, - referenceAttachNode: referenceAttachNode, - initialize: initialize, - finalize: finalize - } + let thisObject = { + workspaceNode: undefined, + container: undefined, + enabled: false, + nodeChildren: undefined, + eventsServerClients: new Map(), + replaceWorkspaceByLoadingOne: replaceWorkspaceByLoadingOne, + save: saveWorkspace, + getHierarchyHeads: getHierarchyHeads, + getHierarchyHeadsById: getHierarchyHeadsById, + getNodeThatIsOnFocus: getNodeThatIsOnFocus, + getNodeByShortcutKey: getNodeByShortcutKey, + stopAllRunningTasks: stopAllRunningTasks, + onMenuItemClick: onMenuItemClick, + physics: physics, + draw: draw, + spawn: spawn, + chainDetachNode: chainDetachNode, + chainAttachNode: chainAttachNode, + referenceDetachNode: referenceDetachNode, + referenceAttachNode: referenceAttachNode, + initialize: initialize, + finalize: finalize + } - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - thisObject.container.detectMouseOver = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = 0 - thisObject.container.frame.height = 0 + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = false + thisObject.container.detectMouseOver = false + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + thisObject.container.frame.width = 0 + thisObject.container.frame.height = 0 - spawnPosition = { - x: canvas.floatingSpace.container.frame.width / 2, - y: canvas.floatingSpace.container.frame.height / 2 - } + spawnPosition = { + x: canvas.floatingSpace.container.frame.width / 2, + y: canvas.floatingSpace.container.frame.height / 2 + } - thisObject.workspaceNode = {} - thisObject.workspaceNode.rootNodes = [] + thisObject.workspaceNode = {} + thisObject.workspaceNode.rootNodes = [] - let functionLibraryReferenceAttachDetach = newReferenceAttachDetach() - let functionLibraryChainAttachDetach = newChainAttachDetach() - let functionLibraryNodeDeleter = newNodeDeleter() - let functionLibraryUiObjectsFromNodes = newUiObjectsFromNodes() - let functionLibraryProtocolNode = newProtocolNode() - let functionLibraryNodeCloning = newNodeCloning() - let functionLibraryTaskFunctions = newTaskFunctions() - let functionLibrarySessionFunctions = newSessionFunctions() - let functionLibraryShortcutKeys = newShortcutKeys() - let functionLibraryOnFocus = newOnFocus() - let functionLibrarySuperScripts = newSuperScriptsFunctions() - let functionLibraryCCXTFunctions = newCCXTFunctions() - let functionLibraryWebhookFunctions = newWebhookFunctions() - let functionLibraryDependenciesFilter = newDependenciesFilter() + let functionLibraryReferenceAttachDetach = newReferenceAttachDetach() + let functionLibraryChainAttachDetach = newChainAttachDetach() + let functionLibraryNodeDeleter = newNodeDeleter() + let functionLibraryUiObjectsFromNodes = newUiObjectsFromNodes() + let functionLibraryProtocolNode = newProtocolNode() + let functionLibraryNodeCloning = newNodeCloning() + let functionLibraryTaskFunctions = newTaskFunctions() + let functionLibrarySessionFunctions = newSessionFunctions() + let functionLibraryShortcutKeys = newShortcutKeys() + let functionLibraryOnFocus = newOnFocus() + let functionLibrarySuperScripts = newSuperScriptsFunctions() + let functionLibraryCCXTFunctions = newCCXTFunctions() + let functionLibraryWebhookFunctions = newWebhookFunctions() + let functionLibraryDependenciesFilter = newDependenciesFilter() - thisObject.nodeChildren = newNodeChildren() + thisObject.nodeChildren = newNodeChildren() - let isInitialized = false - let workingAtTask = 0 - let circularProgressBar = newBusyProgressBar() - circularProgressBar.fitFunction = canvas.floatingSpace.fitIntoVisibleArea - let loadedWorkspaceNode - let sessionTimestamp = (new Date()).valueOf() - window.localStorage.setItem('Session Timestamp', sessionTimestamp) + let isInitialized = false + let workingAtTask = 0 + let circularProgressBar = newBusyProgressBar() + circularProgressBar.fitFunction = canvas.floatingSpace.fitIntoVisibleArea + let loadedWorkspaceNode + let sessionTimestamp = (new Date()).valueOf() + window.localStorage.setItem('Session Timestamp', sessionTimestamp) - return thisObject + return thisObject - function finalize () { - thisObject.definition = undefined - thisObject.container.finalize() - thisObject.container = undefined - thisObject.workspaceNode = undefined - circularProgressBar.finalize() - circularProgressBar = undefined - } + function finalize() { + thisObject.definition = undefined + thisObject.container.finalize() + thisObject.container = undefined + thisObject.workspaceNode = undefined + circularProgressBar.finalize() + circularProgressBar = undefined + } - function initialize () { - try { - let lastUsedWorkspace = window.localStorage.getItem('Last Used Workspace') + function initialize() { + try { + let lastUsedWorkspace = window.localStorage.getItem('Last Used Workspace') - if (lastUsedWorkspace !== 'undefined' && lastUsedWorkspace !== null && lastUsedWorkspace !== undefined) { - let blobService = newFileStorage() - blobService.getFileFromHost('LoadWorkspace' + '/' + lastUsedWorkspace, onFileReceived, true) - function onFileReceived (err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - canvas.cockpitSpace.setStatus('Could not load the last Workspace used, called "' + lastUsedWorkspace + '". Will switch to the default Workspace instead.', 500, canvas.cockpitSpace.statusTypes.WARNING) - thisObject.workspaceNode = getWorkspace() // This is the default workspace that comes with the system. - recreateWorkspace() - return - } - thisObject.workspaceNode = JSON.parse(text) - recreateWorkspace() + if (lastUsedWorkspace !== 'undefined' && lastUsedWorkspace !== null && lastUsedWorkspace !== undefined) { + let blobService = newFileStorage() + blobService.getFileFromHost('LoadWorkspace' + '/' + lastUsedWorkspace, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + canvas.cockpitSpace.setStatus('Could not load the last Workspace used, called "' + lastUsedWorkspace + '". Will switch to the default Workspace instead.', 500, canvas.cockpitSpace.statusTypes.WARNING) + thisObject.workspaceNode = getWorkspace() // This is the default workspace that comes with the system. + recreateWorkspace() + return + } + thisObject.workspaceNode = JSON.parse(text) + recreateWorkspace() + } + } else { + thisObject.workspaceNode = getWorkspace() // This is the default workspace that comes with the system. + recreateWorkspace() + } + + function recreateWorkspace() { + functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, finishInitialization) + } + + function finishInitialization() { + setupEventsServerClients() + runTasksAndSessions(false) + thisObject.enabled = true + canvas.cockpitSpace.initializePosition() + canvas.splashScreen.initialize() + setInterval(saveWorkspace, 60000) + isInitialized = true + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } } - } else { - thisObject.workspaceNode = getWorkspace() // This is the default workspace that comes with the system. - recreateWorkspace() - } - - function recreateWorkspace () { - functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, finishInitialization) - } - - function finishInitialization () { - setupEventsServerClients() - runTasksAndSessions(false) - thisObject.enabled = true - canvas.cockpitSpace.initializePosition() - canvas.splashScreen.initialize() - setInterval(saveWorkspace, 60000) - isInitialized = true - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } } - } - function runTasksAndSessions (replacingCurrentWorkspace) { - if (replacingCurrentWorkspace === true) { - // We need to wait all tasks that were potentially running to stop - setTimeout(functionLibraryUiObjectsFromNodes.runTasks, 70000) - // We give a few seconds for the tasks to start - setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 80000) - } else { - functionLibraryUiObjectsFromNodes.runTasks() - // We give a few seconds for the tasks to start - setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 10000) - } - } - - function setupEventsServerClients () { - for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { - let rootNode = thisObject.workspaceNode.rootNodes[i] - - if (rootNode.type === 'Network') { - for (let j = 0; j < rootNode.networkNodes.length; j++) { - let networkNode = rootNode.networkNodes[j] - - let host - let webSocketsPort - /* At this point the node does not have the payload property yet, that is why we have to do this manually */ - try { - let config = JSON.parse(networkNode.config) - host = config.host - webSocketsPort = config.webSocketsPort - } catch (err) { - console.log('[ERROR] networkNode ' + networkNode.name + ' has an invalid configuration. Cannot know the host name and webSocketsPort.') - return - } - - if (host === undefined) { host = 'localhost' } - if (webSocketsPort === undefined) { webSocketsPort = '8080' } - - let eventsServerClient = newEventsServerClient(host, webSocketsPort, networkNode.name) - eventsServerClient.initialize() - - thisObject.eventsServerClients.set(networkNode.id, eventsServerClient) - } - } - } - } - - function chainDetachNode (node) { - functionLibraryChainAttachDetach.chainDetachNode(node, thisObject.workspaceNode.rootNodes) - } - - function chainAttachNode (node, attachToNode) { - functionLibraryChainAttachDetach.chainAttachNode(node, attachToNode, thisObject.workspaceNode.rootNodes) - } - - function referenceDetachNode (node) { - functionLibraryReferenceAttachDetach.referenceDetachNode(node) - } - - function referenceAttachNode (node, attachToNode) { - functionLibraryReferenceAttachDetach.referenceAttachNode(node, attachToNode, thisObject.workspaceNode.rootNodes) - } - - function saveWorkspace () { - if (isInitialized === false) { return } - /* When there is an exception while loading the app, the rootNodes of the workspace get into null value. To avoid saving a corrupt staate we are going to verufy we are not in that situation before saving. */ - let workspace = canvas.designSpace.workspace.workspaceNode - - let savedSessionTimestamp = window.localStorage.getItem('Session Timestamp') - if (Number(savedSessionTimestamp) !== sessionTimestamp) { - canvas.cockpitSpace.setStatus('Could not save the Workspace. You have more that one instance of the Superlagos User Interface open at the same time. Plese close this instance as it is older than the others.', 150, canvas.cockpitSpace.statusTypes.WARNING) - } else { - let textToSave = stringifyWorkspace() - window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave) - window.localStorage.setItem('Session Timestamp', sessionTimestamp) - - if (workspace.name !== undefined) { - let url = 'SaveWorkspace/' + workspace.name - callServer(textToSave, url, onResponse) - } - - function onResponse (err) { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - window.localStorage.setItem('Last Used Workspace', workspace.name) - window.localStorage.setItem('Session Timestamp', sessionTimestamp) - if (ARE_WE_RECORDING_A_MARKET_PANORAMA === false) { - canvas.cockpitSpace.setStatus(workspace.name + ' Saved.', 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) - } + function runTasksAndSessions(replacingCurrentWorkspace) { + if (replacingCurrentWorkspace === true) { + // We need to wait all tasks that were potentially running to stop + setTimeout(functionLibraryUiObjectsFromNodes.runTasks, 70000) + // We give a few seconds for the tasks to start + setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 80000) } else { - canvas.cockpitSpace.setStatus('Could not save the Workspace at the Backend. Please check the Backend Console for more information.', 150, canvas.cockpitSpace.statusTypes.WARNING) + functionLibraryUiObjectsFromNodes.runTasks() + // We give a few seconds for the tasks to start + setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 10000) } - } - return true - } - } - - function physics () { - eventsServerClientsPhysics() - replacingWorkspacePhysics() - } - - function eventsServerClientsPhysics () { - thisObject.eventsServerClients.forEach(applyPhysics) - - function applyPhysics (eventServerClient) { - eventServerClient.physics() - } - } - - function replacingWorkspacePhysics () { - if (thisObject.enabled !== true) { return } - - if (workingAtTask > 0) { - circularProgressBar.physics() - - switch (workingAtTask) { - case 1: - stopAllRunningTasks() - workingAtTask++ - break - case 2: - functionLibraryNodeDeleter.deleteWorkspace(thisObject.workspaceNode, thisObject.workspaceNode.rootNodes) - workingAtTask++ - break - case 3: - thisObject.workspaceNode = loadedWorkspaceNode - loadedWorkspaceNode = undefined - workingAtTask++ - break - case 4: - functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode) - setupEventsServerClients() - runTasksAndSessions(true) - workingAtTask++ - break - case 5: - canvas.chartingSpace.reset() - workingAtTask++ - break - case 6: - workingAtTask = 0 - circularProgressBar.visible = false - break - } - } - } - - function draw () { - if (circularProgressBar !== undefined) { - circularProgressBar.draw() - } - } - - function stringifyWorkspace (removePersonalData) { - let stringifyReadyNodes = [] - for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { - let rootNode = thisObject.workspaceNode.rootNodes[i] - - if (rootNode.isIncluded !== true) { - let node = functionLibraryProtocolNode.getProtocolNode(rootNode, removePersonalData, false, true, true, true) - stringifyReadyNodes.push(node) - } - } - let workspace = { - type: 'Workspace', - name: thisObject.workspaceNode.name, - rootNodes: stringifyReadyNodes } - return JSON.stringify(workspace) - } + function setupEventsServerClients() { + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] - function stopAllRunningTasks () { - for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { - let rootNode = thisObject.workspaceNode.rootNodes[i] - if (rootNode.type === 'Network') { - if (rootNode.networkNodes !== undefined) { - for (let j = 0; j < rootNode.networkNodes.length; j++) { - let networkNode = rootNode.networkNodes[j] - if (networkNode.dataMining !== undefined && networkNode.dataMining.payload !== undefined) { - networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') - networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + if (rootNode.type === 'Network') { + for (let j = 0; j < rootNode.networkNodes.length; j++) { + let networkNode = rootNode.networkNodes[j] + + let host + let webSocketsPort + /* At this point the node does not have the payload property yet, that is why we have to do this manually */ + try { + let config = JSON.parse(networkNode.config) + host = config.host + webSocketsPort = config.webSocketsPort + } catch (err) { + console.log('[ERROR] networkNode ' + networkNode.name + ' has an invalid configuration. Cannot know the host name and webSocketsPort.') + return + } + + if (host === undefined) { host = 'localhost' } + if (webSocketsPort === undefined) { webSocketsPort = '8080' } + + let eventsServerClient = newEventsServerClient(host, webSocketsPort, networkNode.name) + eventsServerClient.initialize() + + thisObject.eventsServerClients.set(networkNode.id, eventsServerClient) + } } - if (networkNode.testingEnvironment !== undefined && networkNode.testingEnvironment.payload !== undefined) { - networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') - networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + } + } + + function chainDetachNode(node) { + functionLibraryChainAttachDetach.chainDetachNode(node, thisObject.workspaceNode.rootNodes) + } + + function chainAttachNode(node, attachToNode) { + functionLibraryChainAttachDetach.chainAttachNode(node, attachToNode, thisObject.workspaceNode.rootNodes) + } + + function referenceDetachNode(node) { + functionLibraryReferenceAttachDetach.referenceDetachNode(node) + } + + function referenceAttachNode(node, attachToNode) { + functionLibraryReferenceAttachDetach.referenceAttachNode(node, attachToNode, thisObject.workspaceNode.rootNodes) + } + + function saveWorkspace() { + if (isInitialized === false) { return } + /* When there is an exception while loading the app, the rootNodes of the workspace get into null value. To avoid saving a corrupt staate we are going to verufy we are not in that situation before saving. */ + let workspace = canvas.designSpace.workspace.workspaceNode + + let savedSessionTimestamp = window.localStorage.getItem('Session Timestamp') + if (Number(savedSessionTimestamp) !== sessionTimestamp) { + canvas.cockpitSpace.setStatus('Could not save the Workspace. You have more that one instance of the Superlagos User Interface open at the same time. Plese close this instance as it is older than the others.', 150, canvas.cockpitSpace.statusTypes.WARNING) + } else { + let textToSave = stringifyWorkspace() + window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave) + window.localStorage.setItem('Session Timestamp', sessionTimestamp) + + if (workspace.name !== undefined) { + let url = 'SaveWorkspace/' + workspace.name + callServer(textToSave, url, onResponse) } - if (networkNode.productionEnvironment !== undefined && networkNode.productionEnvironment.payload !== undefined) { - networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') - networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + + function onResponse(err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + window.localStorage.setItem('Last Used Workspace', workspace.name) + window.localStorage.setItem('Session Timestamp', sessionTimestamp) + if (ARE_WE_RECORDING_A_MARKET_PANORAMA === false) { + canvas.cockpitSpace.setStatus(workspace.name + ' Saved.', 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) + } + } else { + canvas.cockpitSpace.setStatus('Could not save the Workspace at the Backend. Please check the Backend Console for more information.', 150, canvas.cockpitSpace.statusTypes.WARNING) + } } - } + return true } - } } - } - function getNodeByShortcutKey (searchingKey) { - for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { - let rootNode = thisObject.workspaceNode.rootNodes[i] - let node = functionLibraryShortcutKeys.getNodeByShortcutKey(rootNode, searchingKey) - if (node !== undefined) { return node } + function physics() { + eventsServerClientsPhysics() + replacingWorkspacePhysics() } - } - function getNodeThatIsOnFocus () { - for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { - let rootNode = thisObject.workspaceNode.rootNodes[i] - let node = functionLibraryOnFocus.getNodeThatIsOnFocus(rootNode) - if (node !== undefined) { return node } + function eventsServerClientsPhysics() { + thisObject.eventsServerClients.forEach(applyPhysics) + + function applyPhysics(eventServerClient) { + eventServerClient.physics() + } } - } - function getHierarchyHeads () { - let nodes = [] - for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { - let rootNode = thisObject.workspaceNode.rootNodes[i] - let nodeDefinition = getNodeDefinition(rootNode) - if (nodeDefinition !== undefined) { - if (nodeDefinition.isHierarchyHead === true) { - nodes.push(rootNode) - } - } - } - return nodes - } + function replacingWorkspacePhysics() { + if (thisObject.enabled !== true) { return } - function getHierarchyHeadsById (nodeId) { - let hiriatchyHeads = getHierarchyHeads() - for (let i = 0; i < hiriatchyHeads.length; i++) { - let hiriatchyHead = hiriatchyHeads[i] - if (hiriatchyHead.id === nodeId) { - return hiriatchyHead - } - } - } + if (workingAtTask > 0) { + circularProgressBar.physics() - function replaceWorkspaceByLoadingOne (name) { - let blobService = newFileStorage() - blobService.getFileFromHost('LoadWorkspace' + '/' + name, onFileReceived, true) - function onFileReceived (err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - canvas.cockpitSpace.setStatus('Could not load the Workspace called "' + name + '". ', 500, canvas.cockpitSpace.statusTypes.WARNING) - return - } - - loadedWorkspaceNode = JSON.parse(text) - saveWorkspace() - canvas.cockpitSpace.toTop() - - let position = { - x: browserCanvas.width / 2, - y: browserCanvas.height / 2 - } - - circularProgressBar.initialize(position) - circularProgressBar.visible = true - workingAtTask = 1 - } - } - - function spawn (nodeText, mousePointer) { - try { - let point = { - x: mousePointer.x, - y: mousePointer.y - } - point = canvas.floatingSpace.container.frame.unframeThisPoint(point) - spawnPosition.x = point.x - spawnPosition.y = point.y - - let droppedNode = JSON.parse(nodeText) - - if (droppedNode.type === 'Workspace') { - loadedWorkspaceNode = droppedNode - circularProgressBar.initialize(mousePointer) - circularProgressBar.visible = true - workingAtTask = 1 - return - } - - /* It does not exist, so we recreeate it respecting the inner state of each object. */ - let positionOffset = { - x: spawnPosition.x - droppedNode.savedPayload.position.x, - y: spawnPosition.y - droppedNode.savedPayload.position.y - } - - thisObject.workspaceNode.rootNodes.push(droppedNode) - functionLibraryUiObjectsFromNodes.createUiObjectFromNode(droppedNode, undefined, undefined, positionOffset) - functionLibraryUiObjectsFromNodes.tryToConnectChildrenWithReferenceParents() - - droppedNode = undefined - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] spawn -> err = ' + err.stack) } - } - } - - async function onMenuItemClick (payload, action, relatedUiObject, callBackFunction) { - switch (action) { - case 'Add UI Object': - { - functionLibraryUiObjectsFromNodes.addUIObject(payload.node, relatedUiObject) - } - break - case 'Add Missing Children': - { - functionLibraryUiObjectsFromNodes.addMissingChildren(payload.node) - } - break - case 'Delete UI Object': - { - functionLibraryNodeDeleter.deleteUIObject(payload.node, thisObject.workspaceNode.rootNodes) - } - break - case 'Share Workspace': - { - let text = stringifyWorkspace(true) - let fileName = 'Share - ' + payload.node.type + ' - ' + payload.node.name + '.json' - downloadText(fileName, text) - } - break - case 'Backup Workspace': - { - let text = stringifyWorkspace(false) - let fileName = 'Backup - ' + payload.node.type + ' - ' + payload.node.name + '.json' - downloadText(fileName, text) - } - break - case 'Edit Code': - - break - case 'Share': - { - let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, true, false, true, true, true)) - - let nodeName = payload.node.name - if (nodeName === undefined) { - nodeName = '' - } else { - nodeName = '.' + nodeName - } - let fileName = 'Share - ' + payload.node.type + ' - ' + nodeName + '.json' - downloadText(fileName, text) - } - - break - case 'Backup': - { - let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, false, false, true, true, true)) - - let nodeName = payload.node.name - if (nodeName === undefined) { - nodeName = '' - } else { - nodeName = ' ' + nodeName - } - let fileName = 'Backup - ' + payload.node.type + ' - ' + nodeName + '.json' - downloadText(fileName, text) - } - - break - case 'Clone': - { - let text = JSON.stringify(functionLibraryNodeCloning.getNodeClone(payload.node)) - - let nodeName = payload.node.name - if (nodeName === undefined) { - nodeName = '' - } else { - nodeName = ' ' + nodeName - } - let fileName = 'Clone - ' + payload.node.type + ' - ' + nodeName + '.json' - downloadText(fileName, text) - } - - break - case 'Debug Task': - { - functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, true, callBackFunction) - } - break - case 'Run Task': - { - functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, false, callBackFunction) - } - break - case 'Stop Task': - { - functionLibraryTaskFunctions.stopTask(payload.node, functionLibraryProtocolNode, callBackFunction) - } - break - case 'Run All Tasks': - { - functionLibraryTaskFunctions.runAllTasks(payload.node, functionLibraryProtocolNode) - } - break - case 'Stop All Tasks': - { - functionLibraryTaskFunctions.stopAllTasks(payload.node, functionLibraryProtocolNode) - } - break - case 'Run All Task Managers': - { - functionLibraryTaskFunctions.runAllTaskManagers(payload.node, functionLibraryProtocolNode) - } - break - case 'Stop All Task Managers': - { - functionLibraryTaskFunctions.stopAllTaskManagers(payload.node, functionLibraryProtocolNode) - } - break - case 'Run All Exchange Tasks': - { - functionLibraryTaskFunctions.runAllExchangeTasks(payload.node, functionLibraryProtocolNode) - } - break - case 'Stop All Exchange Tasks': - { - functionLibraryTaskFunctions.stopAllExchangeTasks(payload.node, functionLibraryProtocolNode) - } - break - case 'Add Missing Crypto Exchanges': - { - functionLibraryCCXTFunctions.addMissingExchanges(payload.node, functionLibraryUiObjectsFromNodes) - } - break - case 'Add Missing Assets': - { - functionLibraryCCXTFunctions.addMissingAssets(payload.node, functionLibraryUiObjectsFromNodes) - } - break - case 'Add Missing Markets': - { - functionLibraryCCXTFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) - } - break - case 'Send Webhook Test Message': - { - functionLibraryWebhookFunctions.sendTestMessage(payload.node, callBackFunction) - } - break - case 'Run Session': - { - functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, false, callBackFunction) - } - break - case 'Resume Session': - { - functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, true, callBackFunction) - } - break - case 'Stop Session': - { - functionLibrarySessionFunctions.stopSession(payload.node, functionLibraryProtocolNode, callBackFunction) - } - break - case 'Run Super Action': - { - functionLibrarySuperScripts.runSuperScript(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryNodeCloning, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) - } - break - case 'Remove Parent': - { - chainDetachNode(payload.node) - } - break - case 'Remove Reference': - { - referenceDetachNode(payload.node) - } - break - case 'Push Code to Javascript Code': - { - payload.node.javascriptCode.code = payload.node.code - } - break - case 'Fetch Code to Javascript Code': - { - payload.node.code = payload.node.javascriptCode.code - } - break - case 'Open Documentation': - { - let definition = getNodeDefinition(payload.node) - if (definition !== undefined) { - if (definition.docURL !== undefined) { - let newTab = window.open(definition.docURL, '_blank') - newTab.focus() + switch (workingAtTask) { + case 1: + stopAllRunningTasks() + workingAtTask++ + break + case 2: + functionLibraryNodeDeleter.deleteWorkspace(thisObject.workspaceNode, thisObject.workspaceNode.rootNodes) + workingAtTask++ + break + case 3: + thisObject.workspaceNode = loadedWorkspaceNode + loadedWorkspaceNode = undefined + workingAtTask++ + break + case 4: + functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode) + setupEventsServerClients() + runTasksAndSessions(true) + workingAtTask++ + break + case 5: + canvas.chartingSpace.reset() + workingAtTask++ + break + case 6: + workingAtTask = 0 + circularProgressBar.visible = false + break } - } } - break } - } + + function draw() { + if (circularProgressBar !== undefined) { + circularProgressBar.draw() + } + } + + function stringifyWorkspace(removePersonalData) { + let stringifyReadyNodes = [] + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] + + if (rootNode.isIncluded !== true) { + let node = functionLibraryProtocolNode.getProtocolNode(rootNode, removePersonalData, false, true, true, true) + stringifyReadyNodes.push(node) + } + } + let workspace = { + type: 'Workspace', + name: thisObject.workspaceNode.name, + rootNodes: stringifyReadyNodes + } + + return JSON.stringify(workspace) + } + + function stopAllRunningTasks() { + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] + if (rootNode.type === 'Network') { + if (rootNode.networkNodes !== undefined) { + for (let j = 0; j < rootNode.networkNodes.length; j++) { + let networkNode = rootNode.networkNodes[j] + if (networkNode.dataMining !== undefined && networkNode.dataMining.payload !== undefined) { + networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + } + if (networkNode.testingEnvironment !== undefined && networkNode.testingEnvironment.payload !== undefined) { + networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + } + if (networkNode.productionEnvironment !== undefined && networkNode.productionEnvironment.payload !== undefined) { + networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + } + } + } + } + } + } + + function getNodeByShortcutKey(searchingKey) { + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] + let node = functionLibraryShortcutKeys.getNodeByShortcutKey(rootNode, searchingKey) + if (node !== undefined) { return node } + } + } + + function getNodeThatIsOnFocus() { + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] + let node = functionLibraryOnFocus.getNodeThatIsOnFocus(rootNode) + if (node !== undefined) { return node } + } + } + + function getHierarchyHeads() { + let nodes = [] + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] + let nodeDefinition = getNodeDefinition(rootNode) + if (nodeDefinition !== undefined) { + if (nodeDefinition.isHierarchyHead === true) { + nodes.push(rootNode) + } + } + } + return nodes + } + + function getHierarchyHeadsById(nodeId) { + let hiriatchyHeads = getHierarchyHeads() + for (let i = 0; i < hiriatchyHeads.length; i++) { + let hiriatchyHead = hiriatchyHeads[i] + if (hiriatchyHead.id === nodeId) { + return hiriatchyHead + } + } + } + + function replaceWorkspaceByLoadingOne(name) { + let blobService = newFileStorage() + blobService.getFileFromHost('LoadWorkspace' + '/' + name, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + canvas.cockpitSpace.setStatus('Could not load the Workspace called "' + name + '". ', 500, canvas.cockpitSpace.statusTypes.WARNING) + return + } + + loadedWorkspaceNode = JSON.parse(text) + saveWorkspace() + canvas.cockpitSpace.toTop() + + let position = { + x: browserCanvas.width / 2, + y: browserCanvas.height / 2 + } + + circularProgressBar.initialize(position) + circularProgressBar.visible = true + workingAtTask = 1 + } + } + + function spawn(nodeText, mousePointer) { + try { + let point = { + x: mousePointer.x, + y: mousePointer.y + } + point = canvas.floatingSpace.container.frame.unframeThisPoint(point) + spawnPosition.x = point.x + spawnPosition.y = point.y + + let droppedNode = JSON.parse(nodeText) + + if (droppedNode.type === 'Workspace') { + loadedWorkspaceNode = droppedNode + circularProgressBar.initialize(mousePointer) + circularProgressBar.visible = true + workingAtTask = 1 + return + } + + /* It does not exist, so we recreeate it respecting the inner state of each object. */ + let positionOffset = { + x: spawnPosition.x - droppedNode.savedPayload.position.x, + y: spawnPosition.y - droppedNode.savedPayload.position.y + } + + thisObject.workspaceNode.rootNodes.push(droppedNode) + functionLibraryUiObjectsFromNodes.createUiObjectFromNode(droppedNode, undefined, undefined, positionOffset) + functionLibraryUiObjectsFromNodes.tryToConnectChildrenWithReferenceParents() + + droppedNode = undefined + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] spawn -> err = ' + err.stack) } + } + } + + async function onMenuItemClick(payload, action, relatedUiObject, callBackFunction) { + switch (action) { + case 'Add UI Object': + { + functionLibraryUiObjectsFromNodes.addUIObject(payload.node, relatedUiObject) + } + break + case 'Add Missing Children': + { + functionLibraryUiObjectsFromNodes.addMissingChildren(payload.node) + } + break + case 'Delete UI Object': + { + functionLibraryNodeDeleter.deleteUIObject(payload.node, thisObject.workspaceNode.rootNodes) + } + break + case 'Share Workspace': + { + let text = stringifyWorkspace(true) + let fileName = 'Share - ' + payload.node.type + ' - ' + payload.node.name + '.json' + downloadText(fileName, text) + } + break + case 'Backup Workspace': + { + let text = stringifyWorkspace(false) + let fileName = 'Backup - ' + payload.node.type + ' - ' + payload.node.name + '.json' + downloadText(fileName, text) + } + break + case 'Edit Code': + + break + case 'Share': + { + let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, true, false, true, true, true)) + + let nodeName = payload.node.name + if (nodeName === undefined) { + nodeName = '' + } else { + nodeName = '.' + nodeName + } + let fileName = 'Share - ' + payload.node.type + ' - ' + nodeName + '.json' + downloadText(fileName, text) + } + + break + case 'Backup': + { + let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, false, false, true, true, true)) + + let nodeName = payload.node.name + if (nodeName === undefined) { + nodeName = '' + } else { + nodeName = ' ' + nodeName + } + let fileName = 'Backup - ' + payload.node.type + ' - ' + nodeName + '.json' + downloadText(fileName, text) + } + + break + case 'Clone': + { + let text = JSON.stringify(functionLibraryNodeCloning.getNodeClone(payload.node)) + + let nodeName = payload.node.name + if (nodeName === undefined) { + nodeName = '' + } else { + nodeName = ' ' + nodeName + } + let fileName = 'Clone - ' + payload.node.type + ' - ' + nodeName + '.json' + downloadText(fileName, text) + } + + break + case 'Debug Task': + { + functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, true, callBackFunction) + } + break + case 'Run Task': + { + functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, false, callBackFunction) + } + break + case 'Stop Task': + { + functionLibraryTaskFunctions.stopTask(payload.node, functionLibraryProtocolNode, callBackFunction) + } + break + case 'Run All Tasks': + { + functionLibraryTaskFunctions.runAllTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Tasks': + { + functionLibraryTaskFunctions.stopAllTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Run All Task Managers': + { + functionLibraryTaskFunctions.runAllTaskManagers(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Task Managers': + { + functionLibraryTaskFunctions.stopAllTaskManagers(payload.node, functionLibraryProtocolNode) + } + break + case 'Run All Exchange Tasks': + { + functionLibraryTaskFunctions.runAllExchangeTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Exchange Tasks': + { + functionLibraryTaskFunctions.stopAllExchangeTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Add Missing Crypto Exchanges': + { + functionLibraryCCXTFunctions.addMissingExchanges(payload.node, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Assets': + { + functionLibraryCCXTFunctions.addMissingAssets(payload.node, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Markets': + { + functionLibraryCCXTFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) + } + break + case 'Send Webhook Test Message': + { + functionLibraryWebhookFunctions.sendTestMessage(payload.node, callBackFunction) + } + break + case 'Run Session': + { + functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, false, callBackFunction) + } + break + case 'Resume Session': + { + functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, true, callBackFunction) + } + break + case 'Stop Session': + { + functionLibrarySessionFunctions.stopSession(payload.node, functionLibraryProtocolNode, callBackFunction) + } + break + case 'Run Super Action': + { + functionLibrarySuperScripts.runSuperScript(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryNodeCloning, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + } + break + case 'Remove Parent': + { + chainDetachNode(payload.node) + } + break + case 'Remove Reference': + { + referenceDetachNode(payload.node) + } + break + case 'Push Code to Javascript Code': + { + payload.node.javascriptCode.code = payload.node.code + } + break + case 'Fetch Code to Javascript Code': + { + payload.node.code = payload.node.javascriptCode.code + } + break + case 'Open Documentation': + { + let definition = getNodeDefinition(payload.node) + if (definition !== undefined) { + if (definition.docURL !== undefined) { + let newTab = window.open(definition.docURL, '_blank') + newTab.focus() + } + } + } + break + } + } } diff --git a/EventHandler.js b/EventHandler.js index d387e2b68..3820a8242 100644 --- a/EventHandler.js +++ b/EventHandler.js @@ -1,46 +1,46 @@ -  -function newEventHandler () { - let thisObject = { - name: undefined, // This is for debugging purposes only. - listenToEvent: listenToEvent, - stopListening: stopListening, - raiseEvent: raiseEvent, - finalize: finalize - } - let eventHandlers = [] // Here we store all the functions we will call when an event is raiseed. - - return thisObject - - function finalize () { - eventHandlers = [] - } - - function listenToEvent (eventType, handler, extraData) { - let eventSubscriptionId = newUniqueId() - eventHandlers.push([eventType, handler, extraData, eventSubscriptionId]) - return eventSubscriptionId - } - - function stopListening (pEventSubscriptionId) { - for (let i = 0; i < eventHandlers.length; i++) { - if (pEventSubscriptionId === eventHandlers[i][3]) { - eventHandlers.splice(i, 1) - return - } +function newEventHandler() { + let thisObject = { + name: undefined, // This is for debugging purposes only. + listenToEvent: listenToEvent, + stopListening: stopListening, + raiseEvent: raiseEvent, + finalize: finalize } - } - function raiseEvent (eventType, event) { - for (var i = 0; i < eventHandlers.length; i++) { + let eventHandlers = [] // Here we store all the functions we will call when an event is raiseed. + + return thisObject + + function finalize() { + eventHandlers = [] + } + + function listenToEvent(eventType, handler, extraData) { + let eventSubscriptionId = newUniqueId() + eventHandlers.push([eventType, handler, extraData, eventSubscriptionId]) + return eventSubscriptionId + } + + function stopListening(pEventSubscriptionId) { + for (let i = 0; i < eventHandlers.length; i++) { + if (pEventSubscriptionId === eventHandlers[i][3]) { + eventHandlers.splice(i, 1) + return + } + } + } + + function raiseEvent(eventType, event) { + for (var i = 0; i < eventHandlers.length; i++) { /* We will execute all the functions listening to this event type. */ - if (eventHandlers[i][0] === eventType) { - let handler = eventHandlers[i][1] - let extraData = eventHandlers[i][2] + if (eventHandlers[i][0] === eventType) { + let handler = eventHandlers[i][1] + let extraData = eventHandlers[i][2] - handler(event, extraData) - } + handler(event, extraData) + } + } } - } } diff --git a/EventsServerClient.js b/EventsServerClient.js index 4760a3c51..2956a6916 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -1,215 +1,215 @@ -function newEventsServerClient (host, port, hostName) { - /* Web Sockets Connection */ +function newEventsServerClient(host, port, hostName) { + /* Web Sockets Connection */ - const MODULE_NAME = 'System Event Handler' - const ERROR_LOG = true - const INFO_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + const MODULE_NAME = 'System Event Handler' + const ERROR_LOG = true + const INFO_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - if (host === '' || host === undefined) { host = 'localhost' } - if (port === '' || port === undefined) { port = '8081' } + if (host === '' || host === undefined) { host = 'localhost' } + if (port === '' || port === undefined) { port = '8081' } - const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + '' - let WEB_SOCKETS_CONNECTION + const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + '' + let WEB_SOCKETS_CONNECTION - let thisObject = { - isConnected: isConnected, - initialize: initialize, - physics: physics, - createEventHandler: createEventHandler, - deleteEventHandler: deleteEventHandler, - listenToEvent: listenToEvent, - stopListening: stopListening, - raiseEvent: raiseEvent - } - - let eventListeners = new Map() - let responseWaiters = new Map() - let commandsWaitingConfirmation = new Map() - let commandsSentByTimestamp = new Map() - let nonce = 0 - - return thisObject - - function initialize (callBackFunction) { - setuptWebSockets(callBackFunction) - } - - function isConnected () { - if (WEB_SOCKETS_CONNECTION.readyState === 1) { - return true - } else { - return false - } - } - - function sendCommand (command, responseCallBack, eventsCallBack) { - if (command.action === 'listenToEvent') { - let key - if (command.callerId !== undefined) { - key = command.eventHandlerName + '-' + command.eventType + '-' + command.callerId - } else { - key = command.eventHandlerName + '-' + command.eventType - } - eventListeners.set(key, eventsCallBack) - } - if (command.callerId && responseCallBack) { - responseWaiters.set(command.callerId, responseCallBack) + let thisObject = { + isConnected: isConnected, + initialize: initialize, + physics: physics, + createEventHandler: createEventHandler, + deleteEventHandler: deleteEventHandler, + listenToEvent: listenToEvent, + stopListening: stopListening, + raiseEvent: raiseEvent } - sendToWebSocketServer(command) - } + let eventListeners = new Map() + let responseWaiters = new Map() + let commandsWaitingConfirmation = new Map() + let commandsSentByTimestamp = new Map() + let nonce = 0 - function sendToWebSocketServer (command) { - nonce++ - let stringNonce = nonce.toString() - let timestamp = (new Date()).valueOf() - commandsWaitingConfirmation.set(stringNonce, command) - commandsSentByTimestamp.set(stringNonce, timestamp) + return thisObject - let messageToWebSocketServer = 'Web Browser' + '|*|' + stringNonce + '|*|' + JSON.stringify(command) - - if (WEB_SOCKETS_CONNECTION.readyState === 1) { - WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer) - } else { - console.log('WebSocket message could not be sent because the connection was not ready. Will retry soon. Message = ' + JSON.stringify(command)) + function initialize(callBackFunction) { + setuptWebSockets(callBackFunction) } - } - function createEventHandler (eventHandlerName, callerId, responseCallBack) { - let eventCommand = { - action: 'createEventHandler', - eventHandlerName: eventHandlerName, - callerId: callerId + function isConnected() { + if (WEB_SOCKETS_CONNECTION.readyState === 1) { + return true + } else { + return false + } } - sendCommand(eventCommand, responseCallBack) - } - function deleteEventHandler (eventHandlerName, callerId, responseCallBack) { - let eventCommand = { - action: 'deleteEventHandler', - eventHandlerName: eventHandlerName, - callerId: callerId - } - sendCommand(eventCommand, responseCallBack) - } - - function listenToEvent (eventHandlerName, eventType, extraData, callerId, responseCallBack, eventsCallBack) { - let eventCommand = { - action: 'listenToEvent', - eventHandlerName: eventHandlerName, - eventType: eventType, - extraData: extraData, - callerId: callerId - } - sendCommand(eventCommand, responseCallBack, eventsCallBack) - } - - function stopListening (eventHandlerName, eventSubscriptionId, callerId, responseCallBack) { - let eventCommand = { - action: 'stopListening', - eventHandlerName: eventHandlerName, - eventSubscriptionId: eventSubscriptionId, - callerId: callerId - } - sendCommand(eventCommand, responseCallBack) - } - - function raiseEvent (eventHandlerName, eventType, event, callerId, responseCallBack) { - let eventCommand = { - action: 'raiseEvent', - eventHandlerName: eventHandlerName, - eventType: eventType, - event: event, - callerId: callerId - } - sendCommand(eventCommand, responseCallBack) - } - - function retryCommandsPhysics () { - commandsSentByTimestamp.forEach(checkTimestamp) - - function checkTimestamp (timestamp, nonce) { - const MILISECONDS_TO_WAIT_FOR_RETRYING_A_COMMAND = 10000 - let now = (new Date()).valueOf() - - if ((now - timestamp) > MILISECONDS_TO_WAIT_FOR_RETRYING_A_COMMAND) { - let command = commandsWaitingConfirmation.get(nonce) - commandsWaitingConfirmation.delete(nonce) - commandsSentByTimestamp.delete(nonce) + function sendCommand(command, responseCallBack, eventsCallBack) { + if (command.action === 'listenToEvent') { + let key + if (command.callerId !== undefined) { + key = command.eventHandlerName + '-' + command.eventType + '-' + command.callerId + } else { + key = command.eventHandlerName + '-' + command.eventType + } + eventListeners.set(key, eventsCallBack) + } + if (command.callerId && responseCallBack) { + responseWaiters.set(command.callerId, responseCallBack) + } sendToWebSocketServer(command) - } - } - } - - function physics () { - if (WEB_SOCKETS_CONNECTION !== undefined) { - if (WEB_SOCKETS_CONNECTION.readyState === 3) { // Connection closed. May happen after computer goes to sleep. - setuptWebSockets(onOpen) - function onOpen () { - if (INFO_LOG === true) { logger.write('[INFO] setuptWebSockets -> Found Web Sockets Connection Closed. Reconnected to WebSockets Server.') } - } - } } - if (thisObject.isConnected() !== true) { - canvas.cockpitSpace.setStatus('Connecting to Superalgos Backend at ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING) - } else { - retryCommandsPhysics() + function sendToWebSocketServer(command) { + nonce++ + let stringNonce = nonce.toString() + let timestamp = (new Date()).valueOf() + commandsWaitingConfirmation.set(stringNonce, command) + commandsSentByTimestamp.set(stringNonce, timestamp) + + let messageToWebSocketServer = 'Web Browser' + '|*|' + stringNonce + '|*|' + JSON.stringify(command) + + if (WEB_SOCKETS_CONNECTION.readyState === 1) { + WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer) + } else { + console.log('WebSocket message could not be sent because the connection was not ready. Will retry soon. Message = ' + JSON.stringify(command)) + } } - DEBUG.variable4 = 'Commands Waiting For Confirmation from WS Server: ' + commandsWaitingConfirmation.size - } - - function setuptWebSockets (callBackFunction) { - try { - WEB_SOCKETS_CONNECTION = new WebSocket(WEB_SOCKETS_URL) - WEB_SOCKETS_CONNECTION.onerror = error => { - console.log('WebSocket error:' + JSON.stringify(error)) - } - WEB_SOCKETS_CONNECTION.onopen = () => { - if (callBackFunction !== undefined) { - callBackFunction() + function createEventHandler(eventHandlerName, callerId, responseCallBack) { + let eventCommand = { + action: 'createEventHandler', + eventHandlerName: eventHandlerName, + callerId: callerId + } + sendCommand(eventCommand, responseCallBack) + } + + function deleteEventHandler(eventHandlerName, callerId, responseCallBack) { + let eventCommand = { + action: 'deleteEventHandler', + eventHandlerName: eventHandlerName, + callerId: callerId + } + sendCommand(eventCommand, responseCallBack) + } + + function listenToEvent(eventHandlerName, eventType, extraData, callerId, responseCallBack, eventsCallBack) { + let eventCommand = { + action: 'listenToEvent', + eventHandlerName: eventHandlerName, + eventType: eventType, + extraData: extraData, + callerId: callerId + } + sendCommand(eventCommand, responseCallBack, eventsCallBack) + } + + function stopListening(eventHandlerName, eventSubscriptionId, callerId, responseCallBack) { + let eventCommand = { + action: 'stopListening', + eventHandlerName: eventHandlerName, + eventSubscriptionId: eventSubscriptionId, + callerId: callerId + } + sendCommand(eventCommand, responseCallBack) + } + + function raiseEvent(eventHandlerName, eventType, event, callerId, responseCallBack) { + let eventCommand = { + action: 'raiseEvent', + eventHandlerName: eventHandlerName, + eventType: eventType, + event: event, + callerId: callerId + } + sendCommand(eventCommand, responseCallBack) + } + + function retryCommandsPhysics() { + commandsSentByTimestamp.forEach(checkTimestamp) + + function checkTimestamp(timestamp, nonce) { + const MILISECONDS_TO_WAIT_FOR_RETRYING_A_COMMAND = 10000 + let now = (new Date()).valueOf() + + if ((now - timestamp) > MILISECONDS_TO_WAIT_FOR_RETRYING_A_COMMAND) { + let command = commandsWaitingConfirmation.get(nonce) + commandsWaitingConfirmation.delete(nonce) + commandsSentByTimestamp.delete(nonce) + + sendToWebSocketServer(command) + } + } + } + + function physics() { + if (WEB_SOCKETS_CONNECTION !== undefined) { + if (WEB_SOCKETS_CONNECTION.readyState === 3) { // Connection closed. May happen after computer goes to sleep. + setuptWebSockets(onOpen) + function onOpen() { + if (INFO_LOG === true) { logger.write('[INFO] setuptWebSockets -> Found Web Sockets Connection Closed. Reconnected to WebSockets Server.') } + } + } + } + + if (thisObject.isConnected() !== true) { + canvas.cockpitSpace.setStatus('Connecting to Superalgos Backend at ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING) + } else { + retryCommandsPhysics() + } + + DEBUG.variable4 = 'Commands Waiting For Confirmation from WS Server: ' + commandsWaitingConfirmation.size + } + + function setuptWebSockets(callBackFunction) { + try { + WEB_SOCKETS_CONNECTION = new WebSocket(WEB_SOCKETS_URL) + WEB_SOCKETS_CONNECTION.onerror = error => { + console.log('WebSocket error:' + JSON.stringify(error)) + } + WEB_SOCKETS_CONNECTION.onopen = () => { + if (callBackFunction !== undefined) { + callBackFunction() + } + } + WEB_SOCKETS_CONNECTION.onmessage = e => { + // console.log('Websoked Message Received: ' + e.data) + + let message = JSON.parse(e.data) + + if (message.action === 'Event Raised') { + let key + if (message.callerId !== undefined) { + key = message.eventHandlerName + '-' + message.eventType + '-' + message.callerId + } else { + key = message.eventHandlerName + '-' + message.eventType + } + let handler = eventListeners.get(key) + if (handler) { + handler(message) + } + return + } + + if (message.action === 'Event Server Response') { + let handler = responseWaiters.get(message.callerId) + if (handler) { + handler(message) + } + return + } + + if (message.action === 'Acknowledge') { + commandsWaitingConfirmation.delete(message.nonce) + commandsSentByTimestamp.delete(message.nonce) + return + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] setuptWebSockets -> err = ' + err.stack) } } - } - WEB_SOCKETS_CONNECTION.onmessage = e => { - // console.log('Websoked Message Received: ' + e.data) - - let message = JSON.parse(e.data) - - if (message.action === 'Event Raised') { - let key - if (message.callerId !== undefined) { - key = message.eventHandlerName + '-' + message.eventType + '-' + message.callerId - } else { - key = message.eventHandlerName + '-' + message.eventType - } - let handler = eventListeners.get(key) - if (handler) { - handler(message) - } - return - } - - if (message.action === 'Event Server Response') { - let handler = responseWaiters.get(message.callerId) - if (handler) { - handler(message) - } - return - } - - if (message.action === 'Acknowledge') { - commandsWaitingConfirmation.delete(message.nonce) - commandsSentByTimestamp.delete(message.nonce) - return - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] setuptWebSockets -> err = ' + err.stack) } } - } } diff --git a/FloatingSpace/BusyProgressBar.js b/FloatingSpace/BusyProgressBar.js index a3c846b38..4b325000a 100644 --- a/FloatingSpace/BusyProgressBar.js +++ b/FloatingSpace/BusyProgressBar.js @@ -1,72 +1,72 @@ -function newBusyProgressBar () { - const MODULE_NAME = 'Circular Progress Bar' +function newBusyProgressBar() { + const MODULE_NAME = 'Circular Progress Bar' - let thisObject = { - container: undefined, - isDeployed: undefined, - visible: undefined, - physics: physics, - draw: draw, - finalize: finalize, - initialize: initialize - } - - let position - let addRadius - - let eventSubscriptionHeartbeat - - return thisObject - - function finalize () { - thisObject.payload = undefined - thisObject.fitFunction = undefined - } - - function initialize (pPosition) { - position = pPosition - - addRadius = 0 - } - - function physics () { - addRadius = addRadius + 20 - } - - function draw () { - if (thisObject.visible !== true) { return } - - let visiblePosition = { - x: position.x, - y: position.y + let thisObject = { + container: undefined, + isDeployed: undefined, + visible: undefined, + physics: physics, + draw: draw, + finalize: finalize, + initialize: initialize } - visiblePosition = thisObject.fitFunction(visiblePosition) + let position + let addRadius - const RADIUS = 10 + addRadius - let OPACITY = 1 + let eventSubscriptionHeartbeat - let initialAngle = 0 - let finalAngle = Math.PI * 2 + return thisObject - browserCanvasContext.beginPath() + function finalize() { + thisObject.payload = undefined + thisObject.fitFunction = undefined + } - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, RADIUS, initialAngle, finalAngle, false) - browserCanvasContext.closePath() + function initialize(pPosition) { + position = pPosition - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', 1)' + addRadius = 0 + } - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY * 2 + ')' - browserCanvasContext.lineWidth = 15 - browserCanvasContext.setLineDash([3, 4]) + function physics() { + addRadius = addRadius + 20 + } - browserCanvasContext.stroke() + function draw() { + if (thisObject.visible !== true) { return } - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([3, 4]) - browserCanvasContext.stroke() - } + let visiblePosition = { + x: position.x, + y: position.y + } + + visiblePosition = thisObject.fitFunction(visiblePosition) + + const RADIUS = 10 + addRadius + let OPACITY = 1 + + let initialAngle = 0 + let finalAngle = Math.PI * 2 + + browserCanvasContext.beginPath() + + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, RADIUS, initialAngle, finalAngle, false) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', 1)' + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY * 2 + ')' + browserCanvasContext.lineWidth = 15 + browserCanvasContext.setLineDash([3, 4]) + + browserCanvasContext.stroke() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([3, 4]) + browserCanvasContext.stroke() + } } diff --git a/FloatingSpace/CircularMenu.js b/FloatingSpace/CircularMenu.js index 0ac7ccad9..efc2dda46 100644 --- a/FloatingSpace/CircularMenu.js +++ b/FloatingSpace/CircularMenu.js @@ -1,224 +1,224 @@ -function newCircularMenu () { - const MODULE_NAME = 'Circular Menu' +function newCircularMenu() { + const MODULE_NAME = 'Circular Menu' - let thisObject = { - container: undefined, - isDeployed: undefined, - internalClick: internalClick, - physics: physics, - invisiblePhysics: invisiblePhysics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME, 'Circle') - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let menuItems = [] - - let selfFocusEventSubscriptionId - let selfNotFocuskEventSubscriptionId - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - menuItem.finalize() + let thisObject = { + container: undefined, + isDeployed: undefined, + internalClick: internalClick, + physics: physics, + invisiblePhysics: invisiblePhysics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - menuItems = undefined - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME, 'Circle') + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 - function initialize (menuItemsInitialValues, payload) { -/* Create the array of Menu Items */ + let menuItems = [] - let iconAndTextArray = [] - let iconOnlyArray - let ringsArray = [[], [], [], []] + let selfFocusEventSubscriptionId + let selfNotFocuskEventSubscriptionId - for (let i = 0; i < menuItemsInitialValues.length; i++) { - let menuItem = newCircularMenuItem() - let menuItemInitialValue = menuItemsInitialValues[i] + return thisObject - menuItem.action = menuItemInitialValue.action - menuItem.actionFunction = menuItemInitialValue.actionFunction - menuItem.actionStatus = menuItemInitialValue.actionStatus - menuItem.label = menuItemInitialValue.label - menuItem.workingLabel = menuItemInitialValue.workingLabel - menuItem.workDoneLabel = menuItemInitialValue.workDoneLabel - menuItem.workFailedLabel = menuItemInitialValue.workFailedLabel - menuItem.secondaryAction = menuItemInitialValue.secondaryAction - menuItem.secondaryLabel = menuItemInitialValue.secondaryLabel - menuItem.secondaryWorkingLabel = menuItemInitialValue.secondaryWorkingLabel - menuItem.secondaryWorkDoneLabel = menuItemInitialValue.secondaryWorkDoneLabel - menuItem.secondaryWorkFailedLabel = menuItemInitialValue.secondaryWorkFailedLabel - menuItem.secondaryIcon = menuItemInitialValue.secondaryIcon - menuItem.visible = menuItemInitialValue.visible - menuItem.iconPathOn = menuItemInitialValue.iconPathOn - menuItem.iconPathOff = menuItemInitialValue.iconPathOff - menuItem.rawRadius = menuItemInitialValue.rawRadius - menuItem.targetRadius = menuItemInitialValue.label - menuItem.currentRadius = menuItemInitialValue.currentRadius - menuItem.angle = menuItemInitialValue.angle - menuItem.currentStatus = menuItemInitialValue.currentStatus - menuItem.relatedUiObject = menuItemInitialValue.relatedUiObject - menuItem.dontShowAtFullscreen = menuItemInitialValue.dontShowAtFullscreen - menuItem.askConfirmation = menuItemInitialValue.askConfirmation - menuItem.confirmationLabel = menuItemInitialValue.confirmationLabel - menuItem.disableIfPropertyIsDefined = menuItemInitialValue.disableIfPropertyIsDefined - menuItem.propertyToCheckFor = menuItemInitialValue.propertyToCheckFor - menuItem.ring = menuItemInitialValue.ring - menuItem.icons = menuItemInitialValue.icons + function finalize() { + thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId) - if (menuItem.label === undefined) { - menuItem.type = 'Icon Only' + thisObject.container.finalize() + thisObject.container = undefined - if (menuItem.ring === undefined) { - menutItem.ring = 1 + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + menuItem.finalize() } - iconOnlyArray = ringsArray[menuItem.ring - 1] - iconOnlyArray.push(menuItem) - } else { - menuItem.type = 'Icon & Text' - iconAndTextArray.push(menuItem) - } - menuItem.initialize(payload) - menuItem.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) - menuItems.push(menuItem) + menuItems = undefined } - /* There are 4 possible rings of icons, we will go through each of them here. */ - let amplitudeArray = [80, 50, 40, 80] - let initialAngleArray = [220, 205, 200, 180] - for (let j = 1; j < ringsArray.length + 1; j++) { - let iconOnlyArray = ringsArray[j - 1] - /* Here we calculate the angles for each menu item, and then apply it if it was not previously defined. */ - let amplitude = amplitudeArray[j - 1] - let initialAngle = initialAngleArray[j - 1] - let step = amplitude / (iconOnlyArray.length - 1) - if (iconOnlyArray.length === 1) { - step = 0 - } + function initialize(menuItemsInitialValues, payload) { + /* Create the array of Menu Items */ - for (let i = 0; i < iconOnlyArray.length; i++) { - let menuItem = iconOnlyArray[i] - let angle = initialAngle - step * i - if (menuItem.angle === undefined) { - menuItem.angle = angle + let iconAndTextArray = [] + let iconOnlyArray + let ringsArray = [[], [], [], []] + + for (let i = 0; i < menuItemsInitialValues.length; i++) { + let menuItem = newCircularMenuItem() + let menuItemInitialValue = menuItemsInitialValues[i] + + menuItem.action = menuItemInitialValue.action + menuItem.actionFunction = menuItemInitialValue.actionFunction + menuItem.actionStatus = menuItemInitialValue.actionStatus + menuItem.label = menuItemInitialValue.label + menuItem.workingLabel = menuItemInitialValue.workingLabel + menuItem.workDoneLabel = menuItemInitialValue.workDoneLabel + menuItem.workFailedLabel = menuItemInitialValue.workFailedLabel + menuItem.secondaryAction = menuItemInitialValue.secondaryAction + menuItem.secondaryLabel = menuItemInitialValue.secondaryLabel + menuItem.secondaryWorkingLabel = menuItemInitialValue.secondaryWorkingLabel + menuItem.secondaryWorkDoneLabel = menuItemInitialValue.secondaryWorkDoneLabel + menuItem.secondaryWorkFailedLabel = menuItemInitialValue.secondaryWorkFailedLabel + menuItem.secondaryIcon = menuItemInitialValue.secondaryIcon + menuItem.visible = menuItemInitialValue.visible + menuItem.iconPathOn = menuItemInitialValue.iconPathOn + menuItem.iconPathOff = menuItemInitialValue.iconPathOff + menuItem.rawRadius = menuItemInitialValue.rawRadius + menuItem.targetRadius = menuItemInitialValue.label + menuItem.currentRadius = menuItemInitialValue.currentRadius + menuItem.angle = menuItemInitialValue.angle + menuItem.currentStatus = menuItemInitialValue.currentStatus + menuItem.relatedUiObject = menuItemInitialValue.relatedUiObject + menuItem.dontShowAtFullscreen = menuItemInitialValue.dontShowAtFullscreen + menuItem.askConfirmation = menuItemInitialValue.askConfirmation + menuItem.confirmationLabel = menuItemInitialValue.confirmationLabel + menuItem.disableIfPropertyIsDefined = menuItemInitialValue.disableIfPropertyIsDefined + menuItem.propertyToCheckFor = menuItemInitialValue.propertyToCheckFor + menuItem.ring = menuItemInitialValue.ring + menuItem.icons = menuItemInitialValue.icons + + if (menuItem.label === undefined) { + menuItem.type = 'Icon Only' + + if (menuItem.ring === undefined) { + menutItem.ring = 1 + } + iconOnlyArray = ringsArray[menuItem.ring - 1] + iconOnlyArray.push(menuItem) + } else { + menuItem.type = 'Icon & Text' + iconAndTextArray.push(menuItem) + } + + menuItem.initialize(payload) + menuItem.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) + menuItems.push(menuItem) } - } - } - /* Text and Icon */ - let amplitude = 140 - let initialAngle = -70 - step = amplitude / 7 - let currentItem = (7 - iconAndTextArray.length) / 2 + 1 - for (let i = 0; i < iconAndTextArray.length; i++) { - let menuItem = iconAndTextArray[i] - let angle = initialAngle + step * (currentItem - 0.5) - currentItem++ - if (menuItem.angle === undefined) { - menuItem.angle = angle - } - } - iconOnlyArray = undefined - iconAndTextArray = undefined + /* There are 4 possible rings of icons, we will go through each of them here. */ + let amplitudeArray = [80, 50, 40, 80] + let initialAngleArray = [220, 205, 200, 180] + for (let j = 1; j < ringsArray.length + 1; j++) { + let iconOnlyArray = ringsArray[j - 1] + /* Here we calculate the angles for each menu item, and then apply it if it was not previously defined. */ + let amplitude = amplitudeArray[j - 1] + let initialAngle = initialAngleArray[j - 1] + let step = amplitude / (iconOnlyArray.length - 1) + if (iconOnlyArray.length === 1) { + step = 0 + } - /* Listen to events */ - selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) - selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) - } - - function getContainer (point) { - let container - - if (thisObject.isDeployed === true) { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - if (menuItem.visible === true) { - container = menuItem.getContainer(point) + for (let i = 0; i < iconOnlyArray.length; i++) { + let menuItem = iconOnlyArray[i] + let angle = initialAngle - step * i + if (menuItem.angle === undefined) { + menuItem.angle = angle + } + } } - if (container !== undefined) { return container } - } - } - } - - function internalClick (action) { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - if (menuItem.visible === true) { - if (menuItem.nextAction === action) { - menuItem.internalClick() + /* Text and Icon */ + let amplitude = 140 + let initialAngle = -70 + step = amplitude / 7 + let currentItem = (7 - iconAndTextArray.length) / 2 + 1 + for (let i = 0; i < iconAndTextArray.length; i++) { + let menuItem = iconAndTextArray[i] + let angle = initialAngle + step * (currentItem - 0.5) + currentItem++ + if (menuItem.angle === undefined) { + menuItem.angle = angle + } } - } - } - } - function invisiblePhysics () { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - menuItem.invisiblePhysics() - } - } + iconOnlyArray = undefined + iconAndTextArray = undefined - function physics () { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - menuItem.physics() + /* Listen to events */ + selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) + selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) } - } - function onFocus () { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - menuItem.targetRadius = menuItem.rawRadius * 1.5 - menuItem.isDeployed = true - } - thisObject.isDeployed = true - } + function getContainer(point) { + let container - function onNotFocus () { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - menuItem.targetRadius = menuItem.rawRadius * 0 - i * 1.5 - menuItem.isDeployed = false + if (thisObject.isDeployed === true) { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + if (menuItem.visible === true) { + container = menuItem.getContainer(point) + } + if (container !== undefined) { return container } + } + } } - thisObject.isDeployed = false - } - function drawBackground (pFloatingObject) { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - if (menuItem.visible === true) { - menuItem.drawBackground() - } + function internalClick(action) { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + if (menuItem.visible === true) { + if (menuItem.nextAction === action) { + menuItem.internalClick() + } + } + } } - } - function drawForeground (pFloatingObject) { - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i] - if (menuItem.visible === true) { - menuItem.drawForeground() - } + function invisiblePhysics() { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + menuItem.invisiblePhysics() + } + } + + function physics() { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + menuItem.physics() + } + } + + function onFocus() { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + menuItem.targetRadius = menuItem.rawRadius * 1.5 + menuItem.isDeployed = true + } + thisObject.isDeployed = true + } + + function onNotFocus() { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + menuItem.targetRadius = menuItem.rawRadius * 0 - i * 1.5 + menuItem.isDeployed = false + } + thisObject.isDeployed = false + } + + function drawBackground(pFloatingObject) { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + if (menuItem.visible === true) { + menuItem.drawBackground() + } + } + } + + function drawForeground(pFloatingObject) { + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + if (menuItem.visible === true) { + menuItem.drawForeground() + } + } } - } } diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index e344d69fc..dd32c595a 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -1,469 +1,469 @@ -function newCircularMenuItem () { - const MODULE_NAME = 'Circular Menu Iem' +function newCircularMenuItem() { + const MODULE_NAME = 'Circular Menu Iem' - let thisObject = { - type: undefined, - isDeployed: undefined, - askConfirmation: undefined, - confirmationLabel: undefined, - iconOn: undefined, - iconOff: undefined, - icons: undefined, - currentIcon: undefined, - disableIfPropertyIsDefined: undefined, - propertyToCheckFor: undefined, - action: undefined, - actionFunction: undefined, - actionStatus: undefined, - label: undefined, - workingLabel: undefined, - workDoneLabel: undefined, - workFailedLabel: undefined, - secondaryAction: undefined, - secondaryLabel: undefined, - secondaryWorkingLabel: undefined, - secondaryWorkDoneLabel: undefined, - secondaryWorkFailedLabel: undefined, - secondaryIcon: undefined, - nextAction: undefined, - visible: false, - iconPathOn: undefined, - iconPathOff: undefined, - rawRadius: undefined, - targetRadius: undefined, - currentRadius: undefined, - angle: undefined, - container: undefined, - payload: undefined, - relatedUiObject: undefined, - dontShowAtFullscreen: undefined, - isEnabled: true, - shorcutNumber: undefined, - internalClick: internalClick, - physics: physics, - invisiblePhysics: invisiblePhysics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = true - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = 0 - thisObject.container.frame.height = 40 - - let isMouseOver = false - - let selfMouseOverEventSubscriptionId - let selfMouseClickEventSubscriptionId - let selfMouseNotOverEventSubscriptionId - - let labelToPrint = '' - let defaultBackgroudColor = UI_COLOR.RED - let backgroundColorToUse = UI_COLOR.RED - let temporaryStatus = 0 - let temporaryStatusCounter = 0 - - const EXTRA_MOUSE_OVER_ICON_SIZE = 6 - - const STATUS_NO_ACTION_TAKEN_YET = 0 - const STATUS_PRIMARY_ACTION_WORKING = -1 - const STATUS_SECONDARY_ACTION_WORKING = -2 - const STATUS_PRIMARY_WORK_DONE = -3 - const STATUS_PRIMARY_WORK_FAILED = -4 - const STATUS_WAITING_CONFIRMATION = -5 - const STATUS_SECONDARY_WORK_DONE = -6 - const STATUS_SECONDARY_WORK_FAILED = -7 - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.iconOn = undefined - thisObject.iconOff = undefined - thisObject.icons = undefined - thisObject.currentIcon = undefined - thisObject.payload = undefined - thisObject.actionFunction = undefined - thisObject.actionStatus = undefined - thisObject.disableIfPropertyIsDefined = undefined - thisObject.propertyToCheckFor = undefined - } - - function initialize (pPayload) { - thisObject.payload = pPayload - - iconPhysics() - - selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - - if (thisObject.type === 'Icon & Text') { - thisObject.container.frame.width = 220 - } else { - thisObject.container.frame.width = 50 + let thisObject = { + type: undefined, + isDeployed: undefined, + askConfirmation: undefined, + confirmationLabel: undefined, + iconOn: undefined, + iconOff: undefined, + icons: undefined, + currentIcon: undefined, + disableIfPropertyIsDefined: undefined, + propertyToCheckFor: undefined, + action: undefined, + actionFunction: undefined, + actionStatus: undefined, + label: undefined, + workingLabel: undefined, + workDoneLabel: undefined, + workFailedLabel: undefined, + secondaryAction: undefined, + secondaryLabel: undefined, + secondaryWorkingLabel: undefined, + secondaryWorkDoneLabel: undefined, + secondaryWorkFailedLabel: undefined, + secondaryIcon: undefined, + nextAction: undefined, + visible: false, + iconPathOn: undefined, + iconPathOff: undefined, + rawRadius: undefined, + targetRadius: undefined, + currentRadius: undefined, + angle: undefined, + container: undefined, + payload: undefined, + relatedUiObject: undefined, + dontShowAtFullscreen: undefined, + isEnabled: true, + shorcutNumber: undefined, + internalClick: internalClick, + physics: physics, + invisiblePhysics: invisiblePhysics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - thisObject.nextAction = thisObject.action - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + thisObject.container.frame.width = 0 + thisObject.container.frame.height = 40 - function getContainer (point) { - if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } + let isMouseOver = false - let container - if (thisObject.isDeployed === true) { - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - return thisObject.container - } else { - return undefined - } - } - } + let selfMouseOverEventSubscriptionId + let selfMouseClickEventSubscriptionId + let selfMouseNotOverEventSubscriptionId - function invisiblePhysics () { - temporaryStatusPhysics() - } + let labelToPrint = '' + let defaultBackgroudColor = UI_COLOR.RED + let backgroundColorToUse = UI_COLOR.RED + let temporaryStatus = 0 + let temporaryStatusCounter = 0 - function temporaryStatusPhysics () { - /* Temporary Status impacts on the label to use and the background of that label */ - if (temporaryStatusCounter > 0) { - temporaryStatusCounter-- + const EXTRA_MOUSE_OVER_ICON_SIZE = 6 + + const STATUS_NO_ACTION_TAKEN_YET = 0 + const STATUS_PRIMARY_ACTION_WORKING = -1 + const STATUS_SECONDARY_ACTION_WORKING = -2 + const STATUS_PRIMARY_WORK_DONE = -3 + const STATUS_PRIMARY_WORK_FAILED = -4 + const STATUS_WAITING_CONFIRMATION = -5 + const STATUS_SECONDARY_WORK_DONE = -6 + const STATUS_SECONDARY_WORK_FAILED = -7 + + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.iconOn = undefined + thisObject.iconOff = undefined + thisObject.icons = undefined + thisObject.currentIcon = undefined + thisObject.payload = undefined + thisObject.actionFunction = undefined + thisObject.actionStatus = undefined + thisObject.disableIfPropertyIsDefined = undefined + thisObject.propertyToCheckFor = undefined } - if (temporaryStatusCounter === 0) { - temporaryStatus = STATUS_NO_ACTION_TAKEN_YET - labelToPrint = thisObject.label - backgroundColorToUse = defaultBackgroudColor - thisObject.nextAction = thisObject.action - } - } + function initialize(pPayload) { + thisObject.payload = pPayload - function physics () { - if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } + iconPhysics() - let INCREASE_STEP = 2 // (thisObject.targetRadius - thisObject.rawRadius) / 4 - // if (INCREASE_STEP === 0) { INCREASE_STEP = 2 } + selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= INCREASE_STEP) { - if (thisObject.currentRadius < thisObject.targetRadius) { - thisObject.currentRadius = thisObject.currentRadius + INCREASE_STEP - } else { - thisObject.currentRadius = thisObject.currentRadius - INCREASE_STEP - } - } - - let radiusGrowthFactor - if (thisObject.type === 'Icon Only') { - switch (thisObject.ring) { - case 1: { - radiusGrowthFactor = 5.5 - break - } - case 2: { - radiusGrowthFactor = 4.0 - break - } - case 3: { - radiusGrowthFactor = 3.0 - break - } - case 4: { - radiusGrowthFactor = 2.0 - break - } - } - } else { - radiusGrowthFactor = 4 - } - - thisObject.container.frame.position.x = thisObject.payload.floatingObject.targetRadius * radiusGrowthFactor / 7 * Math.cos(toRadians(thisObject.angle)) - thisObject.currentRadius * 1.5 - thisObject.container.frame.position.y = thisObject.payload.floatingObject.targetRadius * radiusGrowthFactor / 7 * Math.sin(toRadians(thisObject.angle)) - thisObject.container.frame.height / 2 - - temporaryStatusPhysics() - - /* Here we will check if we need to monitor a property that influences the status of the Menu Item. */ - if (thisObject.disableIfPropertyIsDefined === true) { - if (thisObject.payload.node[thisObject.propertyToCheckFor] === undefined) { - /* This menu item is enabled. */ - thisObject.isEnabled = true - } else { - /* This menu item is disabled. */ - thisObject.isEnabled = false - } - } - iconPhysics() - } - - function iconPhysics () { - if ( - ( - temporaryStatus === STATUS_PRIMARY_WORK_DONE || - temporaryStatus === STATUS_SECONDARY_ACTION_WORKING || - temporaryStatus === STATUS_SECONDARY_WORK_DONE || - temporaryStatus === STATUS_SECONDARY_WORK_FAILED - ) && thisObject.secondaryAction !== undefined - ) { - thisObject.iconOn = canvas.designSpace.iconCollection.get(thisObject.secondaryIcon) - thisObject.iconOff = canvas.designSpace.iconCollection.get(thisObject.secondaryIcon) - } else { - if (thisObject.relatedUiObject !== undefined) { - thisObject.iconOn = canvas.designSpace.iconByUiObjectType.get(thisObject.relatedUiObject) - thisObject.iconOff = canvas.designSpace.iconByUiObjectType.get(thisObject.relatedUiObject) - } else { - if (thisObject.iconPathOn !== undefined && thisObject.iconPathOff !== undefined) { - thisObject.iconOn = canvas.designSpace.iconCollection.get(thisObject.iconPathOn) - thisObject.iconOff = canvas.designSpace.iconCollection.get(thisObject.iconPathOff) + if (thisObject.type === 'Icon & Text') { + thisObject.container.frame.width = 220 } else { - thisObject.iconOn = canvas.designSpace.iconCollection.get(thisObject.icons[thisObject.actionStatus()]) - thisObject.iconOff = canvas.designSpace.iconCollection.get(thisObject.icons[thisObject.actionStatus()]) + thisObject.container.frame.width = 50 } - } + + thisObject.nextAction = thisObject.action } - /* Current Status might be linked to some other object status */ + function getContainer(point) { + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } - if (thisObject.actionStatus !== undefined) { - thisObject.currentStatus = thisObject.actionStatus() + let container + if (thisObject.isDeployed === true) { + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + return thisObject.container + } else { + return undefined + } + } } - /* Current Status sets the icon to be used */ - - if (thisObject.currentStatus === true) { - thisObject.icon = thisObject.iconOn - } else { - thisObject.icon = thisObject.iconOff - } - } - - function onMouseOver (point) { - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - isMouseOver = true - } else { - isMouseOver = false - } - MENU_ITEM_ON_FOCUS = thisObject - } - - function onMouseNotOver (point) { - isMouseOver = false - MENU_ITEM_ON_FOCUS = undefined - } - - function internalClick () { - if (thisObject.shorcutNumber !== undefined) { - let label = thisObject.payload.node.name + ' ' + labelToPrint - canvas.cockpitSpace.setStatus(label, 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) + function invisiblePhysics() { + temporaryStatusPhysics() } - onMouseClick() - } + function temporaryStatusPhysics() { + /* Temporary Status impacts on the label to use and the background of that label */ + if (temporaryStatusCounter > 0) { + temporaryStatusCounter-- + } - function onMouseClick () { - if (thisObject.isEnabled === false) { return } - - if (thisObject.label === undefined) { - /* This is what we have in the case of menu items that are only Icons. In this situation there is no complex logic, just execute the specified action. */ - thisObject.actionFunction(thisObject.payload, thisObject.action, thisObject.relatedUiObject) - return + if (temporaryStatusCounter === 0) { + temporaryStatus = STATUS_NO_ACTION_TAKEN_YET + labelToPrint = thisObject.label + backgroundColorToUse = defaultBackgroudColor + thisObject.nextAction = thisObject.action + } } - if (thisObject.askConfirmation !== true) { /* No confirmation is needed */ - if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET || temporaryStatus === STATUS_PRIMARY_WORK_DONE) { - executeAction() - } // Any click out of those states is ignored - } else { - /* Confirmation is needed */ + function physics() { + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } - /* The first click ask for confirmation. */ - if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET) { - setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 250, STATUS_WAITING_CONFIRMATION) - return - } - /* A Click during confirmation executes the pre-defined action. */ - if (temporaryStatus === STATUS_WAITING_CONFIRMATION || temporaryStatus === STATUS_PRIMARY_WORK_DONE) { - executeAction() - if (thisObject.workDoneLabel !== undefined) { - setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + let INCREASE_STEP = 2 // (thisObject.targetRadius - thisObject.rawRadius) / 4 + // if (INCREASE_STEP === 0) { INCREASE_STEP = 2 } + + if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= INCREASE_STEP) { + if (thisObject.currentRadius < thisObject.targetRadius) { + thisObject.currentRadius = thisObject.currentRadius + INCREASE_STEP + } else { + thisObject.currentRadius = thisObject.currentRadius - INCREASE_STEP + } + } + + let radiusGrowthFactor + if (thisObject.type === 'Icon Only') { + switch (thisObject.ring) { + case 1: { + radiusGrowthFactor = 5.5 + break + } + case 2: { + radiusGrowthFactor = 4.0 + break + } + case 3: { + radiusGrowthFactor = 3.0 + break + } + case 4: { + radiusGrowthFactor = 2.0 + break + } + } } else { - setStatus('Done', UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + radiusGrowthFactor = 4 } - return - } + + thisObject.container.frame.position.x = thisObject.payload.floatingObject.targetRadius * radiusGrowthFactor / 7 * Math.cos(toRadians(thisObject.angle)) - thisObject.currentRadius * 1.5 + thisObject.container.frame.position.y = thisObject.payload.floatingObject.targetRadius * radiusGrowthFactor / 7 * Math.sin(toRadians(thisObject.angle)) - thisObject.container.frame.height / 2 + + temporaryStatusPhysics() + + /* Here we will check if we need to monitor a property that influences the status of the Menu Item. */ + if (thisObject.disableIfPropertyIsDefined === true) { + if (thisObject.payload.node[thisObject.propertyToCheckFor] === undefined) { + /* This menu item is enabled. */ + thisObject.isEnabled = true + } else { + /* This menu item is disabled. */ + thisObject.isEnabled = false + } + } + iconPhysics() } - function executeAction () { - if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET || temporaryStatus === STATUS_WAITING_CONFIRMATION) { - /* We need to execute the main Action */ - /* If there is a working label defined, we use it here. */ - if (thisObject.workingLabel !== undefined) { - setStatus(thisObject.workingLabel, UI_COLOR.GREY, undefined, STATUS_PRIMARY_ACTION_WORKING) // Status will not expire, will only change with a callback. Mouse Clicks will be ignored. + function iconPhysics() { + if ( + ( + temporaryStatus === STATUS_PRIMARY_WORK_DONE || + temporaryStatus === STATUS_SECONDARY_ACTION_WORKING || + temporaryStatus === STATUS_SECONDARY_WORK_DONE || + temporaryStatus === STATUS_SECONDARY_WORK_FAILED + ) && thisObject.secondaryAction !== undefined + ) { + thisObject.iconOn = canvas.designSpace.iconCollection.get(thisObject.secondaryIcon) + thisObject.iconOff = canvas.designSpace.iconCollection.get(thisObject.secondaryIcon) + } else { + if (thisObject.relatedUiObject !== undefined) { + thisObject.iconOn = canvas.designSpace.iconByUiObjectType.get(thisObject.relatedUiObject) + thisObject.iconOff = canvas.designSpace.iconByUiObjectType.get(thisObject.relatedUiObject) + } else { + if (thisObject.iconPathOn !== undefined && thisObject.iconPathOff !== undefined) { + thisObject.iconOn = canvas.designSpace.iconCollection.get(thisObject.iconPathOn) + thisObject.iconOff = canvas.designSpace.iconCollection.get(thisObject.iconPathOff) + } else { + thisObject.iconOn = canvas.designSpace.iconCollection.get(thisObject.icons[thisObject.actionStatus()]) + thisObject.iconOff = canvas.designSpace.iconCollection.get(thisObject.icons[thisObject.actionStatus()]) + } + } } - /* Execute the action and wait for callbacks to update our statuus. */ - thisObject.actionFunction(thisObject.payload, thisObject.action, thisObject.relatedUiObject, onPrimaryCallBack) - return - } - if (temporaryStatus === STATUS_PRIMARY_WORK_DONE && thisObject.secondaryAction !== undefined) { - /* We need to execute the secondary action. */ - if (thisObject.secondaryWorkingLabel !== undefined) { - setStatus(thisObject.secondaryWorkingLabel, UI_COLOR.GREY, undefined, STATUS_SECONDARY_ACTION_WORKING) // Status will not expire, will only change with a callback. Mouse Clicks will be ignored. + /* Current Status might be linked to some other object status */ + + if (thisObject.actionStatus !== undefined) { + thisObject.currentStatus = thisObject.actionStatus() } - /* Execute the action and wait for callbacks to update our statuus. */ - thisObject.actionFunction(thisObject.payload, thisObject.secondaryAction, thisObject.relatedUiObject, onSecondaryCallBack) - return - } + /* Current Status sets the icon to be used */ - function onPrimaryCallBack (err, event) { - /* While the primary action is being executed some event might have happen. Following we process the ones we can */ + if (thisObject.currentStatus === true) { + thisObject.icon = thisObject.iconOn + } else { + thisObject.icon = thisObject.iconOff + } + } - if (event !== undefined) { - if (event.type === 'Secondary Action Already Executed') { - setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + function onMouseOver(point) { + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + isMouseOver = true + } else { + isMouseOver = false + } + MENU_ITEM_ON_FOCUS = thisObject + } + + function onMouseNotOver(point) { + isMouseOver = false + MENU_ITEM_ON_FOCUS = undefined + } + + function internalClick() { + if (thisObject.shorcutNumber !== undefined) { + let label = thisObject.payload.node.name + ' ' + labelToPrint + canvas.cockpitSpace.setStatus(label, 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) + } + + onMouseClick() + } + + function onMouseClick() { + if (thisObject.isEnabled === false) { return } + + if (thisObject.label === undefined) { + /* This is what we have in the case of menu items that are only Icons. In this situation there is no complex logic, just execute the specified action. */ + thisObject.actionFunction(thisObject.payload, thisObject.action, thisObject.relatedUiObject) return - } } - /* If there is a secondary action we will act different that if there is not */ - if (thisObject.secondaryAction === undefined) { // This means there are no more possible actions. - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - if (thisObject.workDoneLabel !== undefined) { - setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_PRIMARY_WORK_DONE) - } - } else { - if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED) - } - } + if (thisObject.askConfirmation !== true) { /* No confirmation is needed */ + if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET || temporaryStatus === STATUS_PRIMARY_WORK_DONE) { + executeAction() + } // Any click out of those states is ignored } else { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - if (thisObject.workDoneLabel !== undefined) { - thisObject.nextAction = thisObject.secondaryAction - setStatus(thisObject.secondaryLabel, defaultBackgroudColor, undefined, STATUS_PRIMARY_WORK_DONE) + /* Confirmation is needed */ + + /* The first click ask for confirmation. */ + if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET) { + setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 250, STATUS_WAITING_CONFIRMATION) + return } - } else { - if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED) + /* A Click during confirmation executes the pre-defined action. */ + if (temporaryStatus === STATUS_WAITING_CONFIRMATION || temporaryStatus === STATUS_PRIMARY_WORK_DONE) { + executeAction() + if (thisObject.workDoneLabel !== undefined) { + setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + } else { + setStatus('Done', UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + } + return } - } - } - } - function onSecondaryCallBack (err) { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - if (thisObject.secondaryWorkDoneLabel !== undefined) { - setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) - } - } else { - if (thisObject.secondaryWorkFailedLabel != undefined) { - setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_SECONDARY_WORK_FAILED) - } - } - } - } - } - - function setStatus (text, backgroundColor, waitingCycles, newStatus) { - labelToPrint = text - backgroundColorToUse = backgroundColor - temporaryStatus = newStatus - temporaryStatusCounter = newStatus // This will often put this into negatives numbers, which will disable the counting back and automatic reseting. - if (waitingCycles !== undefined) { // This will override the often negative value with a positive one that will tend to zero onto the default state. - temporaryStatusCounter = waitingCycles - } - } - - function drawBackground () { - if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } - - if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) { - if (thisObject.type === 'Icon & Text') { - let backgroundColor = backgroundColorToUse - if (thisObject.isEnabled === false) { - backgroundColor = UI_COLOR.GREY - } - let params = { - cornerRadius: 5, - lineWidth: 0.1, - container: thisObject.container, - borderColor: UI_COLOR.DARK, - backgroundColor: backgroundColor, - castShadow: false, - xOffset: 60 } - if (isMouseOver === true) { - params.opacity = 1 - } else { - params.opacity = 0.8 + function executeAction() { + if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET || temporaryStatus === STATUS_WAITING_CONFIRMATION) { + /* We need to execute the main Action */ + /* If there is a working label defined, we use it here. */ + if (thisObject.workingLabel !== undefined) { + setStatus(thisObject.workingLabel, UI_COLOR.GREY, undefined, STATUS_PRIMARY_ACTION_WORKING) // Status will not expire, will only change with a callback. Mouse Clicks will be ignored. + } + + /* Execute the action and wait for callbacks to update our statuus. */ + thisObject.actionFunction(thisObject.payload, thisObject.action, thisObject.relatedUiObject, onPrimaryCallBack) + return + } + if (temporaryStatus === STATUS_PRIMARY_WORK_DONE && thisObject.secondaryAction !== undefined) { + /* We need to execute the secondary action. */ + if (thisObject.secondaryWorkingLabel !== undefined) { + setStatus(thisObject.secondaryWorkingLabel, UI_COLOR.GREY, undefined, STATUS_SECONDARY_ACTION_WORKING) // Status will not expire, will only change with a callback. Mouse Clicks will be ignored. + } + + /* Execute the action and wait for callbacks to update our statuus. */ + thisObject.actionFunction(thisObject.payload, thisObject.secondaryAction, thisObject.relatedUiObject, onSecondaryCallBack) + return + } + + function onPrimaryCallBack(err, event) { + /* While the primary action is being executed some event might have happen. Following we process the ones we can */ + + if (event !== undefined) { + if (event.type === 'Secondary Action Already Executed') { + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + return + } + } + + /* If there is a secondary action we will act different that if there is not */ + if (thisObject.secondaryAction === undefined) { // This means there are no more possible actions. + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + if (thisObject.workDoneLabel !== undefined) { + setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_PRIMARY_WORK_DONE) + } + } else { + if (thisObject.workFailedLabel != undefined) { + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED) + } + } + } else { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + if (thisObject.workDoneLabel !== undefined) { + thisObject.nextAction = thisObject.secondaryAction + setStatus(thisObject.secondaryLabel, defaultBackgroudColor, undefined, STATUS_PRIMARY_WORK_DONE) + } + } else { + if (thisObject.workFailedLabel != undefined) { + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED) + } + } + } + } + function onSecondaryCallBack(err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + if (thisObject.secondaryWorkDoneLabel !== undefined) { + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + } + } else { + if (thisObject.secondaryWorkFailedLabel != undefined) { + setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_SECONDARY_WORK_FAILED) + } + } + } } - - roundedCornersBackground(params) - } - } - } - - function drawForeground () { - if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } - - let menuPosition = { - x: thisObject.currentRadius * 1.5, - y: thisObject.container.frame.height / 2 } - menuPosition = thisObject.container.frame.frameThisPoint(menuPosition) + function setStatus(text, backgroundColor, waitingCycles, newStatus) { + labelToPrint = text + backgroundColorToUse = backgroundColor + temporaryStatus = newStatus + temporaryStatusCounter = newStatus // This will often put this into negatives numbers, which will disable the counting back and automatic reseting. + if (waitingCycles !== undefined) { // This will override the often negative value with a positive one that will tend to zero onto the default state. + temporaryStatusCounter = waitingCycles + } + } + + function drawBackground() { + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } + + if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) { + if (thisObject.type === 'Icon & Text') { + let backgroundColor = backgroundColorToUse + if (thisObject.isEnabled === false) { + backgroundColor = UI_COLOR.GREY + } + let params = { + cornerRadius: 5, + lineWidth: 0.1, + container: thisObject.container, + borderColor: UI_COLOR.DARK, + backgroundColor: backgroundColor, + castShadow: false, + xOffset: 60 + } + + if (isMouseOver === true) { + params.opacity = 1 + } else { + params.opacity = 0.8 + } + + roundedCornersBackground(params) + } + } + } + + function drawForeground() { + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } + + let menuPosition = { + x: thisObject.currentRadius * 1.5, + y: thisObject.container.frame.height / 2 + } + + menuPosition = thisObject.container.frame.frameThisPoint(menuPosition) /* Menu Item */ - let iconSize - if (isMouseOver === true) { - iconSize = thisObject.currentRadius + EXTRA_MOUSE_OVER_ICON_SIZE - } else { - iconSize = thisObject.currentRadius - } - - if (thisObject.icon === undefined) { return } - if (thisObject.icon.canDrawIcon === true && thisObject.currentRadius > 1 && thisObject.isDeployed === true) { - browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - iconSize, menuPosition.y - iconSize, iconSize * 2, iconSize * 2) - - /* Menu Label */ - - if (thisObject.type === 'Icon & Text') { - label = labelToPrint - if (thisObject.shorcutNumber !== undefined) { - label = '' + thisObject.shorcutNumber + '- ' + labelToPrint + let iconSize + if (isMouseOver === true) { + iconSize = thisObject.currentRadius + EXTRA_MOUSE_OVER_ICON_SIZE + } else { + iconSize = thisObject.currentRadius } - let labelPoint - let fontSize = 15 + if (thisObject.icon === undefined) { return } + if (thisObject.icon.canDrawIcon === true && thisObject.currentRadius > 1 && thisObject.isDeployed === true) { + browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - iconSize, menuPosition.y - iconSize, iconSize * 2, iconSize * 2) - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + /* Menu Label */ - if (thisObject.currentRadius >= thisObject.targetRadius) { - labelPoint = { - x: menuPosition.x + thisObject.currentRadius + 25, - y: menuPosition.y + fontSize * FONT_ASPECT_RATIO - } + if (thisObject.type === 'Icon & Text') { + label = labelToPrint + if (thisObject.shorcutNumber !== undefined) { + label = '' + thisObject.shorcutNumber + '- ' + labelToPrint + } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + let labelPoint + let fontSize = 15 + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + + if (thisObject.currentRadius >= thisObject.targetRadius) { + labelPoint = { + x: menuPosition.x + thisObject.currentRadius + 25, + y: menuPosition.y + fontSize * FONT_ASPECT_RATIO + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } } - } } - } } diff --git a/FloatingSpace/CircularProgressBar.js b/FloatingSpace/CircularProgressBar.js index d662589c8..070f55e22 100644 --- a/FloatingSpace/CircularProgressBar.js +++ b/FloatingSpace/CircularProgressBar.js @@ -1,146 +1,146 @@ -function newCircularProgressBar () { - const MODULE_NAME = 'Circular Progress Bar' +function newCircularProgressBar() { + const MODULE_NAME = 'Circular Progress Bar' - let thisObject = { - container: undefined, - isDeployed: undefined, - physics: physics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME, 'Circle') - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let opacityCounters = [] - let eventSubscriptionIdHeartbeat - let needToDrawRing = true - let eventsServerClient - - return thisObject - - function finalize () { - finalizeEventsServerClient() - - thisObject.container = undefined - thisObject.payload = undefined - thisObject.fitFunction = undefined - } - - function finalizeEventsServerClient () { - if (eventsServerClient !== undefined) { - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - if (eventSubscriptionIdHeartbeat !== undefined) { - eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat) - } - } - } - - function initialize (payload, pEventsServerClient) { - thisObject.payload = payload - - finalizeEventsServerClient() - eventsServerClient = pEventsServerClient - - for (let i = 0; i < 60; i++) { - opacityCounters.push(0) + let thisObject = { + container: undefined, + isDeployed: undefined, + physics: physics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Heartbeat', undefined, key, onResponse, onHeartBeat) + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME, 'Circle') + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 - function onResponse (message) { - eventSubscriptionIdHeartbeat = message.eventSubscriptionId - } - } + let opacityCounters = [] + let eventSubscriptionIdHeartbeat + let needToDrawRing = true + let eventsServerClient - function onHeartBeat (message) { - if (thisObject.payload === undefined) { return } - if (thisObject.payload.uiObject === undefined) { return } - opacityCounters[message.event.seconds] = 2000 - if (message.event.processingDate !== undefined) { - thisObject.payload.uiObject.setValue(message.event.processingDate, 2000) - } - if (message.event.percentage !== undefined) { - thisObject.payload.uiObject.setPercentage(message.event.percentage, 2000) - } - if (message.event.status !== undefined) { - needToDrawRing = false - thisObject.payload.uiObject.setStatus(message.event.status, 200000) + return thisObject + + function finalize() { + finalizeEventsServerClient() + + thisObject.container = undefined + thisObject.payload = undefined + thisObject.fitFunction = undefined } - thisObject.payload.uiObject.heartBeat() - } - - function getContainer (point) { - if (canvas.floatingSpace.inMapMode === true) { return } - let container - - for (let i = 0; i < menuItems.length; i++) { - let menutItem = menuItems[i] - container = menutItem.getContainer(point) - if (container !== undefined) { return container } - } - } - - function physics () { - for (let i = 0; i < 60; i++) { - opacityCounters[i] = opacityCounters[i] - 2 - - if (opacityCounters[i] < 0) { - opacityCounters[i] = 0 - } - } - } - - function drawForeground (pFloatingObject) { - - } - - function drawBackground (pFloatingObject) { - if (canvas.floatingSpace.inMapMode === true) { return } - if (needToDrawRing !== true) { return } - - const VISIBLE_RADIUS = thisObject.container.frame.radius * 2 - - let visiblePosition = { - x: thisObject.container.frame.position.x, - y: thisObject.container.frame.position.y + function finalizeEventsServerClient() { + if (eventsServerClient !== undefined) { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + if (eventSubscriptionIdHeartbeat !== undefined) { + eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat) + } + } } - visiblePosition = thisObject.container.frame.frameThisPoint(visiblePosition) - visiblePosition = thisObject.fitFunction(visiblePosition) + function initialize(payload, pEventsServerClient) { + thisObject.payload = payload - for (let i = 0; i < 60; i++) { - let OPACITY = opacityCounters[i] / 1000 + finalizeEventsServerClient() + eventsServerClient = pEventsServerClient - if (OPACITY === 0) { continue } + for (let i = 0; i < 60; i++) { + opacityCounters.push(0) + } - let initialAngle = Math.PI * 2 / 60 * i - Math.PI / 2 - let finalAngle = Math.PI * 2 / 60 * (i + 1) - Math.PI / 2 + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Heartbeat', undefined, key, onResponse, onHeartBeat) - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, initialAngle, finalAngle, false) - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY * 2 + ')' - browserCanvasContext.lineWidth = 6 + opacityCounters[i] / 100 / 2 - browserCanvasContext.setLineDash([3, 4]) - browserCanvasContext.stroke() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 0 + opacityCounters[i] / 100 / 2 - browserCanvasContext.setLineDash([3, 4]) - browserCanvasContext.stroke() + function onResponse(message) { + eventSubscriptionIdHeartbeat = message.eventSubscriptionId + } + } + + function onHeartBeat(message) { + if (thisObject.payload === undefined) { return } + if (thisObject.payload.uiObject === undefined) { return } + opacityCounters[message.event.seconds] = 2000 + if (message.event.processingDate !== undefined) { + thisObject.payload.uiObject.setValue(message.event.processingDate, 2000) + } + if (message.event.percentage !== undefined) { + thisObject.payload.uiObject.setPercentage(message.event.percentage, 2000) + } + if (message.event.status !== undefined) { + needToDrawRing = false + thisObject.payload.uiObject.setStatus(message.event.status, 200000) + } + + thisObject.payload.uiObject.heartBeat() + } + + function getContainer(point) { + if (canvas.floatingSpace.inMapMode === true) { return } + let container + + for (let i = 0; i < menuItems.length; i++) { + let menutItem = menuItems[i] + container = menutItem.getContainer(point) + if (container !== undefined) { return container } + } + } + + function physics() { + for (let i = 0; i < 60; i++) { + opacityCounters[i] = opacityCounters[i] - 2 + + if (opacityCounters[i] < 0) { + opacityCounters[i] = 0 + } + } + } + + function drawForeground(pFloatingObject) { + + } + + function drawBackground(pFloatingObject) { + if (canvas.floatingSpace.inMapMode === true) { return } + if (needToDrawRing !== true) { return } + + const VISIBLE_RADIUS = thisObject.container.frame.radius * 2 + + let visiblePosition = { + x: thisObject.container.frame.position.x, + y: thisObject.container.frame.position.y + } + + visiblePosition = thisObject.container.frame.frameThisPoint(visiblePosition) + visiblePosition = thisObject.fitFunction(visiblePosition) + + for (let i = 0; i < 60; i++) { + let OPACITY = opacityCounters[i] / 1000 + + if (OPACITY === 0) { continue } + + let initialAngle = Math.PI * 2 / 60 * i - Math.PI / 2 + let finalAngle = Math.PI * 2 / 60 * (i + 1) - Math.PI / 2 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, initialAngle, finalAngle, false) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY * 2 + ')' + browserCanvasContext.lineWidth = 6 + opacityCounters[i] / 100 / 2 + browserCanvasContext.setLineDash([3, 4]) + browserCanvasContext.stroke() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 0 + opacityCounters[i] / 100 / 2 + browserCanvasContext.setLineDash([3, 4]) + browserCanvasContext.stroke() + } } - } } diff --git a/FloatingSpace/CodeEditor.js b/FloatingSpace/CodeEditor.js index 4dea3fb0c..6ab244702 100644 --- a/FloatingSpace/CodeEditor.js +++ b/FloatingSpace/CodeEditor.js @@ -1,199 +1,199 @@ -function newCodeEditor () { - const MODULE_NAME = 'Code Editor' +function newCodeEditor() { + const MODULE_NAME = 'Code Editor' - let thisObject = { - isVisibleFunction: undefined, - visible: false, - imagePathOK: undefined, - imagePathNOT_OK: undefined, - rawRadius: undefined, - targetRadius: undefined, - currentRadius: undefined, - container: undefined, - payload: undefined, - deactivate: deactivate, - activate: activate, - physics: physics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let isMouseOver = false - let SIZE_FACTOR = 1.4 - - return thisObject - - function finalize () { - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.isVisibleFunction = undefined - } - - function initialize () { - - } - - function deactivate () { - if (thisObject.visible === true) { - thisObject.visible = false - let textArea = document.getElementById('textArea') - textArea.style.display = 'none' - thisObject.payload.node.code = textArea.value - } - EDITOR_ON_FOCUS = false - } - - function activate (payload) { - thisObject.visible = true - thisObject.payload = payload - thisObject.rawRadius = 8 - thisObject.targetRadius = thisObject.container.frame.radius - thisObject.currentRadius = 0 - thisObject.payload.uiObject.setErrorMessage('', 0) - - let textArea = document.getElementById('textArea') - textArea.value = payload.node.code - textArea.style = 'resize: none;' + - ' border: none;' + - ' outline: none;' + - 'box-shadow: none;' + - 'overflow:hidden;' + - 'font-family: ' + UI_FONT.PRIMARY + ';' + - 'font-size: 14px;' + - 'background-color: rgb(' + UI_COLOR.RUSTED_RED + ');' + - 'color:rgb(255, 255, 255);' + - 'width: ' + thisObject.container.frame.width + 'px;' + - 'height: ' + thisObject.container.frame.height + 'px' - textArea.style.display = 'block' - textArea.focus() - EDITOR_ON_FOCUS = true - } - - function getContainer (point) { - let container - if (thisObject.visible === true) { - if (point.x === VERY_LARGE_NUMBER) { - /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that - anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is - triggered. We compensate recognizing this coordinate and returning our container. */ - return thisObject.container - } - - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - return thisObject.container - } else { - return undefined - } - } - } - - function physics () { - if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { - if (thisObject.currentRadius < thisObject.targetRadius) { - thisObject.currentRadius = thisObject.currentRadius + 0.5 - } else { - thisObject.currentRadius = thisObject.currentRadius - 0.5 - } + let thisObject = { + isVisibleFunction: undefined, + visible: false, + imagePathOK: undefined, + imagePathNOT_OK: undefined, + rawRadius: undefined, + targetRadius: undefined, + currentRadius: undefined, + container: undefined, + payload: undefined, + deactivate: deactivate, + activate: activate, + physics: physics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = false + thisObject.container.frame.radius = 0 thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR - thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR + let isMouseOver = false + let SIZE_FACTOR = 1.4 - let textAreaPosition = { - x: 0 - thisObject.container.frame.width / 2, - y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN + return thisObject + + function finalize() { + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.isVisibleFunction = undefined } - textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) - if (thisObject.visible === true) { - let checkPosition = { - x: textAreaPosition.x, - y: textAreaPosition.y - CURRENT_TOP_MARGIN - } - if (thisObject.isVisibleFunction(checkPosition) === false) { - deactivate() - } - } - if (thisObject.visible === true) { - let textAreaDiv = document.getElementById('textAreaDiv') - textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; ' - } - } + function initialize() { - function drawBackground () { - if (thisObject.visible === true) { - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - let radius = thisObject.container.frame.radius * SIZE_FACTOR - - if (radius > 0.5) { - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' - browserCanvasContext.fill() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + 1 + ')' - browserCanvasContext.fill() - } - } - } - function drawForeground () { - let iconPosition = { - x: 0, - y: thisObject.currentRadius * 1.5 } - iconPosition = thisObject.container.frame.frameThisPoint(iconPosition) + function deactivate() { + if (thisObject.visible === true) { + thisObject.visible = false + let textArea = document.getElementById('textArea') + textArea.style.display = 'none' + thisObject.payload.node.code = textArea.value + } + EDITOR_ON_FOCUS = false + } - /* Menu Item */ + function activate(payload) { + thisObject.visible = true + thisObject.payload = payload + thisObject.rawRadius = 8 + thisObject.targetRadius = thisObject.container.frame.radius + thisObject.currentRadius = 0 + thisObject.payload.uiObject.setErrorMessage('', 0) - if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) { - browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + let textArea = document.getElementById('textArea') + textArea.value = payload.node.code + textArea.style = 'resize: none;' + + ' border: none;' + + ' outline: none;' + + 'box-shadow: none;' + + 'overflow:hidden;' + + 'font-family: ' + UI_FONT.PRIMARY + ';' + + 'font-size: 14px;' + + 'background-color: rgb(' + UI_COLOR.RUSTED_RED + ');' + + 'color:rgb(255, 255, 255);' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + textArea.style.display = 'block' + textArea.focus() + EDITOR_ON_FOCUS = true + } - /* Menu Label */ + function getContainer(point) { + let container + if (thisObject.visible === true) { + if (point.x === VERY_LARGE_NUMBER) { + /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that + anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is + triggered. We compensate recognizing this coordinate and returning our container. */ + return thisObject.container + } - let label = 'Code looks good!' - let labelPoint - let fontSize = 10 + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + return thisObject.container + } else { + return undefined + } + } + } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - - if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) { - labelPoint = { - x: iconPosition.x + thisObject.currentRadius + 10, - y: iconPosition.y + fontSize * FONT_ASPECT_RATIO + function physics() { + if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { + if (thisObject.currentRadius < thisObject.targetRadius) { + thisObject.currentRadius = thisObject.currentRadius + 0.5 + } else { + thisObject.currentRadius = thisObject.currentRadius - 0.5 + } } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + + thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR + thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR + + let textAreaPosition = { + x: 0 - thisObject.container.frame.width / 2, + y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN + } + + textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) + if (thisObject.visible === true) { + let checkPosition = { + x: textAreaPosition.x, + y: textAreaPosition.y - CURRENT_TOP_MARGIN + } + if (thisObject.isVisibleFunction(checkPosition) === false) { + deactivate() + } + } + if (thisObject.visible === true) { + let textAreaDiv = document.getElementById('textAreaDiv') + textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; ' + } + } + + function drawBackground() { + if (thisObject.visible === true) { + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + let radius = thisObject.container.frame.radius * SIZE_FACTOR + + if (radius > 0.5) { + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' + browserCanvasContext.fill() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + 1 + ')' + browserCanvasContext.fill() + } + } + } + function drawForeground() { + let iconPosition = { + x: 0, + y: thisObject.currentRadius * 1.5 + } + + iconPosition = thisObject.container.frame.frameThisPoint(iconPosition) + + /* Menu Item */ + + if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) { + browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + + /* Menu Label */ + + let label = 'Code looks good!' + let labelPoint + let fontSize = 10 + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + + if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) { + labelPoint = { + x: iconPosition.x + thisObject.currentRadius + 10, + y: iconPosition.y + fontSize * FONT_ASPECT_RATIO + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } } - } } diff --git a/FloatingSpace/ConditionEditor.js b/FloatingSpace/ConditionEditor.js index 5b22ff07e..443c9f231 100644 --- a/FloatingSpace/ConditionEditor.js +++ b/FloatingSpace/ConditionEditor.js @@ -1,1198 +1,1198 @@ -function newConditionEditor () { - const MODULE_NAME = 'Condition Editor' +function newConditionEditor() { + const MODULE_NAME = 'Condition Editor' - let thisObject = { - isVisibleFunction: undefined, - visible: false, - imagePathOK: undefined, - imagePathNOT_OK: undefined, - container: undefined, - payload: undefined, - deactivate: deactivate, - activate: activate, - physics: physics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME, 'Circle') - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = false - thisObject.container.frame.radius = 750 - thisObject.container.frame.width = thisObject.container.frame.radius * 2 - thisObject.container.frame.height = thisObject.container.frame.radius * 2 - thisObject.container.frame.containerName = MODULE_NAME - - let isMouseOver = false - let conditionStructure - let scanResult - - let timeFrameIcon - let dataMineIcon - let botIcon - let whenIcon - let productIcon - let propertyIcon - let operationIcon - let valueIcon - - const PICKER_WIDTH = 150 - const PICKER_HEIGHT = 60 - - return thisObject - - function finalize () { - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.isVisibleFunction = undefined - - conditionStructure = undefined - scanResult = undefined - - timeFrameIcon = undefined - dataMineIcon = undefined - whenIcon = undefined - botIcon = undefined - productIcon = undefined - operationIcon = undefined - propertyIcon = undefined - valueIcon = undefined - } - - function initialize () { - timeFrameIcon = canvas.designSpace.iconCollection.get('time-period') - dataMineIcon = canvas.designSpace.iconCollection.get('data-mine') - botIcon = canvas.designSpace.iconCollection.get('bot-indicator') - whenIcon = canvas.designSpace.iconCollection.get('chronometer') - productIcon = canvas.designSpace.iconCollection.get('product-definition') - propertyIcon = canvas.designSpace.iconCollection.get('record-property') - operationIcon = canvas.designSpace.iconCollection.get('headphones') - valueIcon = canvas.designSpace.iconCollection.get('competition') - } - - function activate (payload) { - thisObject.visible = true - thisObject.payload = payload - thisObject.payload.uiObject.setErrorMessage('', 0) - - conditionStructure = { - code: '', - logicOperands: [] + let thisObject = { + isVisibleFunction: undefined, + visible: false, + imagePathOK: undefined, + imagePathNOT_OK: undefined, + container: undefined, + payload: undefined, + deactivate: deactivate, + activate: activate, + physics: physics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - scanDataMines() - loadFromCode() - EDITOR_ON_FOCUS = true - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME, 'Circle') + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = false + thisObject.container.frame.radius = 750 + thisObject.container.frame.width = thisObject.container.frame.radius * 2 + thisObject.container.frame.height = thisObject.container.frame.radius * 2 + thisObject.container.frame.containerName = MODULE_NAME - function deactivate () { - convertToCode() - finalizePickers() + let isMouseOver = false + let conditionStructure + let scanResult - conditionStructure = undefined + let timeFrameIcon + let dataMineIcon + let botIcon + let whenIcon + let productIcon + let propertyIcon + let operationIcon + let valueIcon - if (thisObject.visible === true) { - thisObject.visible = false - } - EDITOR_ON_FOCUS = false - } + const PICKER_WIDTH = 150 + const PICKER_HEIGHT = 60 - function loadFromCode () { - if (thisObject.payload.node.code === undefined) { thisObject.payload.node.code = '' } - conditionStructure.code = thisObject.payload.node.code.replace(/ /g, '') + return thisObject - /* LOGICAL ORs */ - let orArray = conditionStructure.code.split('||') - for (let j = 0; j < 3; j++) { - let logicOperand = { - code: orArray[j], - index: j, - comparison: {}, - visible: false - } + function finalize() { + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.isVisibleFunction = undefined - if (logicOperand.code !== undefined) { - logicOperand.visible = true - if (orArray[j + 1] !== undefined) { - logicOperand.operator = '||' - } - } else { - logicOperand.code = '' - } + conditionStructure = undefined + scanResult = undefined - checkComparison(logicOperand, j) - conditionStructure.logicOperands.push(logicOperand) + timeFrameIcon = undefined + dataMineIcon = undefined + whenIcon = undefined + botIcon = undefined + productIcon = undefined + operationIcon = undefined + propertyIcon = undefined + valueIcon = undefined } - function checkComparison (logicOperand) { - /* We are going to decompose the code into 2 comparison operators */ - logicOperand.comparison.operandA = { - index: 0, - code: '' - } - logicOperand.comparison.operandB = { - index: 1, - code: '' - } - - if (logicOperand.code.indexOf('>') > 0) { - let codeArray = logicOperand.code.split('>') - logicOperand.comparison.operandA.code = codeArray[0] - logicOperand.comparison.operandB.code = codeArray[1] - logicOperand.comparison.operator = '>' - logicOperand.comparison.operatorIndex = 0 - } - - if (logicOperand.code.indexOf('<') > 0) { - let codeArray = logicOperand.code.split('<') - logicOperand.comparison.operandA.code = codeArray[0] - logicOperand.comparison.operandB.code = codeArray[1] - logicOperand.comparison.operator = '<' - logicOperand.comparison.operatorIndex = 1 - } - - if (logicOperand.code.indexOf('>=') > 0) { - let codeArray = logicOperand.code.split('>=') - logicOperand.comparison.operandA.code = codeArray[0] - logicOperand.comparison.operandB.code = codeArray[1] - logicOperand.comparison.operator = '>=' - logicOperand.comparison.operatorIndex = 2 - } - - if (logicOperand.code.indexOf('<=') > 0) { - let codeArray = logicOperand.code.split('<=') - logicOperand.comparison.operandA.code = codeArray[0] - logicOperand.comparison.operandB.code = codeArray[1] - logicOperand.comparison.operator = '<=' - logicOperand.comparison.operatorIndex = 3 - } - - if (logicOperand.code.indexOf('===') > 0) { - let codeArray = logicOperand.code.split('===') - logicOperand.comparison.operandA.code = codeArray[0] - logicOperand.comparison.operandB.code = codeArray[1] - logicOperand.comparison.operator = '===' - logicOperand.comparison.operatorIndex = 4 - } - - /* Each comparison code may have one or more algebra operators */ - checkAlgebra(logicOperand, logicOperand.comparison.operandA) - checkAlgebra(logicOperand, logicOperand.comparison.operandB) + function initialize() { + timeFrameIcon = canvas.designSpace.iconCollection.get('time-period') + dataMineIcon = canvas.designSpace.iconCollection.get('data-mine') + botIcon = canvas.designSpace.iconCollection.get('bot-indicator') + whenIcon = canvas.designSpace.iconCollection.get('chronometer') + productIcon = canvas.designSpace.iconCollection.get('product-definition') + propertyIcon = canvas.designSpace.iconCollection.get('record-property') + operationIcon = canvas.designSpace.iconCollection.get('headphones') + valueIcon = canvas.designSpace.iconCollection.get('competition') } - function checkAlgebra (logicOperand, comparisonOperand) { - comparisonOperand.algebra = { - operandA: { index: 0}, - operandB: { index: 1} - } + function activate(payload) { + thisObject.visible = true + thisObject.payload = payload + thisObject.payload.uiObject.setErrorMessage('', 0) - /* The default situation is that there is no algebra operation, meaning we will setup a algebra operation only with operandA */ - comparisonOperand.algebra.operandA.code = comparisonOperand.code - comparisonOperand.algebra.operandB.code = '' - comparisonOperand.algebra.operator = '...' - comparisonOperand.algebra.operatorIndex = 0 + conditionStructure = { + code: '', + logicOperands: [] + } - if (comparisonOperand.code.indexOf('+') > 0) { - let codeArray = comparisonOperand.code.split('+') - comparisonOperand.algebra.operandA.code = codeArray[0] - comparisonOperand.algebra.operandB.code = codeArray[1] - comparisonOperand.algebra.operator = '+' - comparisonOperand.algebra.operatorIndex = 1 - } - - if (comparisonOperand.code.indexOf('-') > 0) { - let codeArray = comparisonOperand.code.split('-') - comparisonOperand.algebra.operandA.code = codeArray[0] - comparisonOperand.algebra.operandB.code = codeArray[1] - comparisonOperand.algebra.operator = '-' - comparisonOperand.algebra.operatorIndex = 2 - } - - if (comparisonOperand.code.indexOf('*') > 0) { - let codeArray = comparisonOperand.code.split('*') - comparisonOperand.algebra.operandA.code = codeArray[0] - comparisonOperand.algebra.operandB.code = codeArray[1] - comparisonOperand.algebra.operator = '*' - comparisonOperand.algebra.operatorIndex = 3 - } - - if (comparisonOperand.code.indexOf('/') > 0) { - let codeArray = comparisonOperand.code.split('/') - comparisonOperand.algebra.operandA.code = codeArray[0] - comparisonOperand.algebra.operandB.code = codeArray[1] - comparisonOperand.algebra.operator = '/' - comparisonOperand.algebra.operatorIndex = 4 - } - - initializePickersSet(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA) - initializePickersSet(logicOperand, comparisonOperand, comparisonOperand.algebra.operandB) - updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA) - updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandB) + scanDataMines() + loadFromCode() + EDITOR_ON_FOCUS = true } - function initializePickersSet (logicOperand, comparisonOperand, algebraOperand) { - const ALGEBRA_SEPARATION = PICKER_HEIGHT - const COMPARISON_SEPARATION = ALGEBRA_SEPARATION * 2 - const LOGIC_SEPARATION = COMPARISON_SEPARATION * 2 + function deactivate() { + convertToCode() + finalizePickers() - let properties - let parent - let current - let yOffset = (logicOperand.index - 1) * LOGIC_SEPARATION + (comparisonOperand.index - 0.5) * COMPARISON_SEPARATION + (algebraOperand.index - 0.5) * ALGEBRA_SEPARATION + conditionStructure = undefined - if (algebraOperand.index === 0) { - comparisonOperand.algebra.picker = newPicker() - let picker = comparisonOperand.algebra.picker - picker.name = 'Algebra' - picker.container.connectToParent(thisObject.container) - picker.container.frame.position.x = 0 - picker.container.frame.width / 2 + picker.container.frame.width * 2.5 - picker.container.frame.position.y = 0 - picker.container.frame.height / 2 + yOffset - current = ['...', 'Plus', 'Minus', 'Times', 'Divided by'] - picker.initialize(current, current) - switch (comparisonOperand.algebra.operator) { - case '+': { - picker.setSelected(undefined, undefined, undefined, 1) - break - } - case '-': { - picker.setSelected(undefined, undefined, undefined, 2) - break - } - case '*': { - picker.setSelected(undefined, undefined, undefined, 3) - break - } - case '/': { - picker.setSelected(undefined, undefined, undefined, 4) - break - } + if (thisObject.visible === true) { + thisObject.visible = false } - picker.visible = true - let structureBranch = { - logicOperand: logicOperand, - comparisonOperand: comparisonOperand, - algebraOperand: algebraOperand, - pickerName: 'Algebra' - } - picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged, structureBranch) - } - - if (comparisonOperand.index === 0 && algebraOperand.index === 1) { - logicOperand.comparison.picker = newPicker() - let picker = logicOperand.comparison.picker - picker.name = 'Comparison' - picker.container.connectToParent(thisObject.container) - picker.container.frame.position.x = 0 - picker.container.frame.width / 2 + picker.container.frame.width * 2.5 - picker.container.frame.position.y = 0 - picker.container.frame.height / 2 + yOffset - let optionsList = ['Greater Than', 'Less Than', 'Greater or Equal Than', 'Less or Equal Than', 'Equal To'] - picker.initialize(optionsList) - switch (logicOperand.comparison.operator) { - case '>': { - picker.setSelected(undefined, undefined, undefined, 0) - break - } - case '<': { - picker.setSelected(undefined, undefined, undefined, 1) - break - } - case '>=': { - picker.setSelected(undefined, undefined, undefined, 2) - break - } - case '<=': { - picker.setSelected(undefined, undefined, undefined, 3) - break - } - case '===': { - picker.setSelected(undefined, undefined, undefined, 4) - break - } - } - picker.visible = true - let structureBranch = { - logicOperand: logicOperand, - comparisonOperand: comparisonOperand, - algebraOperand: algebraOperand, - pickerName: 'Comparison' - } - picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged, structureBranch) - } - - if (comparisonOperand.index === 1 && algebraOperand.index === 1 && logicOperand.index <= 1) { - logicOperand.picker = newPicker() - let picker = logicOperand.picker - picker.name = 'Logic' - picker.container.connectToParent(thisObject.container) - picker.container.frame.position.x = 0 - picker.container.frame.width / 2 + picker.container.frame.width * 2.5 - picker.container.frame.position.y = 0 - picker.container.frame.height / 2 + yOffset - let optionsList = ['...', 'OR'] - picker.initialize(optionsList) - if (logicOperand.operator === '||') { - picker.setSelected(undefined, undefined, undefined, 1) - } - picker.visible = true - let structureBranch = { - logicOperand: logicOperand, - comparisonOperand: comparisonOperand, - algebraOperand: algebraOperand, - pickerName: 'Logic' - } - picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged, structureBranch) - } - - let visible = true - if (algebraOperand.index === 1 && comparisonOperand.algebra.picker.getSelected() === '...') { visible = false } - if (logicOperand.comparison.picker !== undefined && comparisonOperand.index === 1 && logicOperand.comparison.picker.getSelected() === 'Equal To') { visible = false } - - algebraOperand.whenPicker = newPicker() - algebraOperand.whenPicker.name = 'When' - algebraOperand.whenPicker.container.connectToParent(thisObject.container) - algebraOperand.whenPicker.container.frame.position.x = 0 - algebraOperand.whenPicker.container.frame.width / 2 - algebraOperand.whenPicker.container.frame.width * 0.5 - algebraOperand.whenPicker.container.frame.position.y = 0 - algebraOperand.whenPicker.container.frame.height / 2 + yOffset - current = ['Current', '1 Previous', '2 Previous', '3 Previous', '4 Previous', '5 Previous'] - algebraOperand.whenPicker.initialize(current, current) - algebraOperand.whenPicker.visible = visible - - algebraOperand.dataMinePicker = newPicker() - algebraOperand.dataMinePicker.name = 'Data Mine' - algebraOperand.dataMinePicker.container.connectToParent(thisObject.container) - algebraOperand.dataMinePicker.container.frame.position.x = 0 - algebraOperand.dataMinePicker.container.frame.width / 2 - algebraOperand.dataMinePicker.container.frame.width * 2.5 - algebraOperand.dataMinePicker.container.frame.position.y = 0 - algebraOperand.dataMinePicker.container.frame.height / 2 + yOffset - current = scanResult - properties = Object.keys(current) - algebraOperand.dataMinePicker.initialize(properties, current) - parent = current - algebraOperand.dataMinePicker.visible = visible - - algebraOperand.botPicker = newPicker() - algebraOperand.botPicker.name = 'Bot' - algebraOperand.botPicker.container.connectToParent(thisObject.container) - algebraOperand.botPicker.container.frame.position.x = 0 - algebraOperand.botPicker.container.frame.width / 2 - algebraOperand.botPicker.container.frame.width * 1.5 - algebraOperand.botPicker.container.frame.position.y = 0 - algebraOperand.botPicker.container.frame.height / 2 + yOffset - current = parent[properties[0]] - properties = Object.keys(current) - algebraOperand.botPicker.initialize(properties, current, parent) - parent = current - algebraOperand.botPicker.visible = visible - - algebraOperand.productPicker = newPicker() - algebraOperand.productPicker.name = 'Product' - algebraOperand.productPicker.container.connectToParent(thisObject.container) - algebraOperand.productPicker.container.frame.position.x = 0 - algebraOperand.productPicker.container.frame.width / 2 + algebraOperand.productPicker.container.frame.width * 0.5 - algebraOperand.productPicker.container.frame.position.y = 0 - algebraOperand.productPicker.container.frame.height / 2 + yOffset - current = parent[properties[0]] - properties = Object.keys(current) - algebraOperand.productPicker.initialize(properties, current, parent) - parent = current - algebraOperand.productPicker.visible = visible - - let productParent = parent - let productProperties = properties - - algebraOperand.propertyPicker = newPicker() - algebraOperand.propertyPicker.name = 'Property' - algebraOperand.propertyPicker.container.connectToParent(thisObject.container) - algebraOperand.propertyPicker.container.frame.position.x = 0 - algebraOperand.propertyPicker.container.frame.width / 2 + algebraOperand.propertyPicker.container.frame.width * 1.5 - algebraOperand.propertyPicker.container.frame.position.y = 0 - algebraOperand.propertyPicker.container.frame.height / 2 + yOffset - current = productParent[productProperties[0]] - current = current.properties - properties = Object.keys(current) - algebraOperand.propertyPicker.initialize(properties, current, productParent, 'properties') - parent = current - algebraOperand.propertyPicker.visible = visible - - algebraOperand.valuePicker = newPicker() - algebraOperand.valuePicker.name = 'Value' - algebraOperand.valuePicker.container.connectToParent(thisObject.container) - algebraOperand.valuePicker.container.frame.position.x = 0 - algebraOperand.valuePicker.container.frame.width / 2 + algebraOperand.valuePicker.container.frame.width * 3.5 - algebraOperand.valuePicker.container.frame.position.y = 0 - algebraOperand.valuePicker.container.frame.height / 2 + yOffset + ALGEBRA_SEPARATION - current = parent[properties[0]] - properties = current.possibleValues - algebraOperand.valuePicker.initialize(properties, current, parent, 'possibleValues') - parent = current - algebraOperand.valuePicker.visible = false - if (logicOperand.comparison.picker !== undefined && logicOperand.comparison.picker.getSelected() === 'Equal To') { - comparisonOperand.algebra.operandA.valuePicker.visible = true - } - - algebraOperand.timeFramePicker = newPicker() - algebraOperand.timeFramePicker.name = 'Time Frame' - algebraOperand.timeFramePicker.container.connectToParent(thisObject.container) - algebraOperand.timeFramePicker.container.frame.position.x = 0 - algebraOperand.timeFramePicker.container.frame.width / 2 - algebraOperand.timeFramePicker.container.frame.width * 3.0 - algebraOperand.timeFramePicker.container.frame.position.y = 0 - algebraOperand.timeFramePicker.container.frame.height / 2 + yOffset - algebraOperand.timeFramePicker.container.frame.width = algebraOperand.timeFramePicker.container.frame.width / 2 - current = productParent[productProperties[0]] - properties = current.validTimeFrames - algebraOperand.timeFramePicker.initialize(properties, current, productParent, 'validTimeFrames') - parent = current - algebraOperand.timeFramePicker.visible = visible - - algebraOperand.botPicker.eventSuscriptionId = algebraOperand.dataMinePicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.botPicker.onParentChanged) - algebraOperand.productPicker.eventSuscriptionId = algebraOperand.botPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.productPicker.onParentChanged) - algebraOperand.propertyPicker.eventSuscriptionId = algebraOperand.productPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.propertyPicker.onParentChanged) - algebraOperand.valuePicker.eventSuscriptionId = algebraOperand.propertyPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.valuePicker.onParentChanged) - algebraOperand.timeFramePicker.eventSuscriptionId = algebraOperand.productPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.timeFramePicker.onParentChanged) + EDITOR_ON_FOCUS = false } - function updatePickers (logicOperand, comparisonOperand, algebraOperand) { - let codeArray = algebraOperand.code.split('.') + function loadFromCode() { + if (thisObject.payload.node.code === undefined) { thisObject.payload.node.code = '' } + conditionStructure.code = thisObject.payload.node.code.replace(/ /g, '') - let codeTimeFrame - if (codeArray[1] !== undefined) { - codeTimeFrame = codeArray[1].substring(2, 4) + '-' + codeArray[1].substring(4, 7) - } + /* LOGICAL ORs */ + let orArray = conditionStructure.code.split('||') + for (let j = 0; j < 3; j++) { + let logicOperand = { + code: orArray[j], + index: j, + comparison: {}, + visible: false + } - let codeProduct - if (codeArray[2] !== undefined) { - codeProduct = codeArray[2] - } + if (logicOperand.code !== undefined) { + logicOperand.visible = true + if (orArray[j + 1] !== undefined) { + logicOperand.operator = '||' + } + } else { + logicOperand.code = '' + } - /* Parse When */ - let propertyDisplacement = 0 - let codeWhen = 'Current' - if (codeArray[3] === 'previous') { - propertyDisplacement++ - codeWhen = '1 Previous' - } - if (codeArray[4] === 'previous') { - propertyDisplacement++ - codeWhen = '2 Previous' - } - if (codeArray[5] === 'previous') { - propertyDisplacement++ - codeWhen = '3 Previous' - } - if (codeArray[6] === 'previous') { - propertyDisplacement++ - codeWhen = '4 Previous' - } - if (codeArray[7] === 'previous') { - propertyDisplacement++ - codeWhen = '5 Previous' - } - algebraOperand.whenPicker.setSelected(undefined, undefined, undefined, propertyDisplacement) + checkComparison(logicOperand, j) + conditionStructure.logicOperands.push(logicOperand) + } - let codeProperty - if (codeArray[3 + propertyDisplacement] !== undefined) { - codeProperty = codeArray[3 + propertyDisplacement] - } + function checkComparison(logicOperand) { + /* We are going to decompose the code into 2 comparison operators */ + logicOperand.comparison.operandA = { + index: 0, + code: '' + } + logicOperand.comparison.operandB = { + index: 1, + code: '' + } - let codeValue = logicOperand.comparison.operandB.code.replace('"', '').replace('"', '') + if (logicOperand.code.indexOf('>') > 0) { + let codeArray = logicOperand.code.split('>') + logicOperand.comparison.operandA.code = codeArray[0] + logicOperand.comparison.operandB.code = codeArray[1] + logicOperand.comparison.operator = '>' + logicOperand.comparison.operatorIndex = 0 + } - let dataMines = Object.keys(scanResult) - for (let i = 0; i < dataMines.length; i++) { - let dataMine = dataMines[i] - let dataMineObject = scanResult[dataMine] - let bots = Object.keys(dataMineObject) - for (let j = 0; j < bots.length; j++) { - let bot = bots[j] - let botObject = dataMineObject[bot] - let products = Object.keys(botObject) - for (let k = 0; k < products.length; k++) { - let product = products[k] - let productObject = botObject[product] - if (codeProduct === product) { - algebraOperand.dataMinePicker.setSelected(dataMines, scanResult, undefined, i) - algebraOperand.botPicker.setSelected(bots, dataMineObject, scanResult, j) - algebraOperand.productPicker.setSelected(products, botObject, dataMineObject, k) - let properties = Object.keys(productObject.properties) - for (let m = 0; m < properties.length; m++) { - let property = properties[m] - let propertyObject = productObject.properties[property] - if (codeProperty === property) { - algebraOperand.propertyPicker.setSelected(properties, productObject.properties, botObject, m) - let values = propertyObject.possibleValues - for (let n = 0; n < values.length; n++) { - let value = values[n] - let valueObject = propertyObject[value] - if (codeValue === value) { - algebraOperand.valuePicker.setSelected(values, propertyObject, productObject, n) + if (logicOperand.code.indexOf('<') > 0) { + let codeArray = logicOperand.code.split('<') + logicOperand.comparison.operandA.code = codeArray[0] + logicOperand.comparison.operandB.code = codeArray[1] + logicOperand.comparison.operator = '<' + logicOperand.comparison.operatorIndex = 1 + } + + if (logicOperand.code.indexOf('>=') > 0) { + let codeArray = logicOperand.code.split('>=') + logicOperand.comparison.operandA.code = codeArray[0] + logicOperand.comparison.operandB.code = codeArray[1] + logicOperand.comparison.operator = '>=' + logicOperand.comparison.operatorIndex = 2 + } + + if (logicOperand.code.indexOf('<=') > 0) { + let codeArray = logicOperand.code.split('<=') + logicOperand.comparison.operandA.code = codeArray[0] + logicOperand.comparison.operandB.code = codeArray[1] + logicOperand.comparison.operator = '<=' + logicOperand.comparison.operatorIndex = 3 + } + + if (logicOperand.code.indexOf('===') > 0) { + let codeArray = logicOperand.code.split('===') + logicOperand.comparison.operandA.code = codeArray[0] + logicOperand.comparison.operandB.code = codeArray[1] + logicOperand.comparison.operator = '===' + logicOperand.comparison.operatorIndex = 4 + } + + /* Each comparison code may have one or more algebra operators */ + checkAlgebra(logicOperand, logicOperand.comparison.operandA) + checkAlgebra(logicOperand, logicOperand.comparison.operandB) + } + + function checkAlgebra(logicOperand, comparisonOperand) { + comparisonOperand.algebra = { + operandA: { index: 0 }, + operandB: { index: 1 } + } + + /* The default situation is that there is no algebra operation, meaning we will setup a algebra operation only with operandA */ + comparisonOperand.algebra.operandA.code = comparisonOperand.code + comparisonOperand.algebra.operandB.code = '' + comparisonOperand.algebra.operator = '...' + comparisonOperand.algebra.operatorIndex = 0 + + if (comparisonOperand.code.indexOf('+') > 0) { + let codeArray = comparisonOperand.code.split('+') + comparisonOperand.algebra.operandA.code = codeArray[0] + comparisonOperand.algebra.operandB.code = codeArray[1] + comparisonOperand.algebra.operator = '+' + comparisonOperand.algebra.operatorIndex = 1 + } + + if (comparisonOperand.code.indexOf('-') > 0) { + let codeArray = comparisonOperand.code.split('-') + comparisonOperand.algebra.operandA.code = codeArray[0] + comparisonOperand.algebra.operandB.code = codeArray[1] + comparisonOperand.algebra.operator = '-' + comparisonOperand.algebra.operatorIndex = 2 + } + + if (comparisonOperand.code.indexOf('*') > 0) { + let codeArray = comparisonOperand.code.split('*') + comparisonOperand.algebra.operandA.code = codeArray[0] + comparisonOperand.algebra.operandB.code = codeArray[1] + comparisonOperand.algebra.operator = '*' + comparisonOperand.algebra.operatorIndex = 3 + } + + if (comparisonOperand.code.indexOf('/') > 0) { + let codeArray = comparisonOperand.code.split('/') + comparisonOperand.algebra.operandA.code = codeArray[0] + comparisonOperand.algebra.operandB.code = codeArray[1] + comparisonOperand.algebra.operator = '/' + comparisonOperand.algebra.operatorIndex = 4 + } + + initializePickersSet(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA) + initializePickersSet(logicOperand, comparisonOperand, comparisonOperand.algebra.operandB) + updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA) + updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandB) + } + + function initializePickersSet(logicOperand, comparisonOperand, algebraOperand) { + const ALGEBRA_SEPARATION = PICKER_HEIGHT + const COMPARISON_SEPARATION = ALGEBRA_SEPARATION * 2 + const LOGIC_SEPARATION = COMPARISON_SEPARATION * 2 + + let properties + let parent + let current + let yOffset = (logicOperand.index - 1) * LOGIC_SEPARATION + (comparisonOperand.index - 0.5) * COMPARISON_SEPARATION + (algebraOperand.index - 0.5) * ALGEBRA_SEPARATION + + if (algebraOperand.index === 0) { + comparisonOperand.algebra.picker = newPicker() + let picker = comparisonOperand.algebra.picker + picker.name = 'Algebra' + picker.container.connectToParent(thisObject.container) + picker.container.frame.position.x = 0 - picker.container.frame.width / 2 + picker.container.frame.width * 2.5 + picker.container.frame.position.y = 0 - picker.container.frame.height / 2 + yOffset + current = ['...', 'Plus', 'Minus', 'Times', 'Divided by'] + picker.initialize(current, current) + switch (comparisonOperand.algebra.operator) { + case '+': { + picker.setSelected(undefined, undefined, undefined, 1) + break + } + case '-': { + picker.setSelected(undefined, undefined, undefined, 2) + break + } + case '*': { + picker.setSelected(undefined, undefined, undefined, 3) + break + } + case '/': { + picker.setSelected(undefined, undefined, undefined, 4) + break } - } } - } - let timeFrames = productObject.validTimeFrames - for (let m = 0; m < timeFrames.length; m++) { - let timeFrame = timeFrames[m] - let timeFrameObject = productObject.validTimeFrames[timeFrame] - if (codeTimeFrame === timeFrame) { - algebraOperand.timeFramePicker.setSelected(timeFrames, productObject, botObject, m) + picker.visible = true + let structureBranch = { + logicOperand: logicOperand, + comparisonOperand: comparisonOperand, + algebraOperand: algebraOperand, + pickerName: 'Algebra' } - } + picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged, structureBranch) } - } - } - } - } - } - function scanDataMines () { - let selector = {} - - let workspace = canvas.designSpace.workspace.workspaceNode - - for (let i = 0; i < workspace.rootNodes.length; i++) { - let rootNode = workspace.rootNodes[i] - if (rootNode.type !== 'Data Mine') { continue } - let dataMine = rootNode - let dataMineName = loadPropertyFromNodeConfig(dataMine.payload, 'codeName') - selector[dataMineName] = {} - let bots = dataMine.sensorBots.concat(dataMine.indicatorBots) - for (let j = 0; j < bots.length; j++) { - let bot = bots[j] - let botName = loadPropertyFromNodeConfig(bot.payload, 'codeName') - let selectorDataMine = selector[dataMineName] - selectorDataMine[botName] = {} - for (let k = 0; k < bot.products.length; k++) { - let product = bot.products[k] - let productName = loadPropertyFromNodeConfig(product.payload, 'singularVariableName') - if (productName === undefined) { continue } - let selectorProduct = selectorDataMine[botName] - selectorProduct[productName] = { - properties: {} - } - if (product.record === undefined) { continue } - for (let m = 0; m < product.record.properties.length; m++) { - let property = product.record.properties[m] - let propertyName = loadPropertyFromNodeConfig(property.payload, 'codeName') - let selectorProperty = selectorProduct[productName] - selectorProperty = selectorProperty.properties - selectorProperty[propertyName] = {} - let possibleValues = loadPropertyFromNodeConfig(property.payload, 'possibleValues') - if (possibleValues === undefined) { possibleValues = [] } - let selectorPossibleValue = selectorProperty[propertyName] - selectorPossibleValue.possibleValues = possibleValues - } - let allPossibleTimeFrames = [] - for (let m = 0; m < product.datasets.length; m++) { - let dataset = product.datasets[m] - let validTimeFrames = loadPropertyFromNodeConfig(dataset.payload, 'validTimeFrames') - if (validTimeFrames !== undefined) { - allPossibleTimeFrames = allPossibleTimeFrames.concat(validTimeFrames) + if (comparisonOperand.index === 0 && algebraOperand.index === 1) { + logicOperand.comparison.picker = newPicker() + let picker = logicOperand.comparison.picker + picker.name = 'Comparison' + picker.container.connectToParent(thisObject.container) + picker.container.frame.position.x = 0 - picker.container.frame.width / 2 + picker.container.frame.width * 2.5 + picker.container.frame.position.y = 0 - picker.container.frame.height / 2 + yOffset + let optionsList = ['Greater Than', 'Less Than', 'Greater or Equal Than', 'Less or Equal Than', 'Equal To'] + picker.initialize(optionsList) + switch (logicOperand.comparison.operator) { + case '>': { + picker.setSelected(undefined, undefined, undefined, 0) + break + } + case '<': { + picker.setSelected(undefined, undefined, undefined, 1) + break + } + case '>=': { + picker.setSelected(undefined, undefined, undefined, 2) + break + } + case '<=': { + picker.setSelected(undefined, undefined, undefined, 3) + break + } + case '===': { + picker.setSelected(undefined, undefined, undefined, 4) + break + } + } + picker.visible = true + let structureBranch = { + logicOperand: logicOperand, + comparisonOperand: comparisonOperand, + algebraOperand: algebraOperand, + pickerName: 'Comparison' + } + picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged, structureBranch) } - } - let selectorValidTimeFrames = selectorProduct[productName] - selectorValidTimeFrames.validTimeFrames = allPossibleTimeFrames - let productKeys = Object.keys(selectorProduct[productName]) - if (productKeys.length === 0) { - selectorProduct[productName] = undefined - } - } - let botKeys = Object.keys(selectorDataMine[botName]) - if (botKeys.length === 0) { - selectorDataMine[botName] = undefined - } - } - let dataMineKeys = Object.keys(selector[dataMineName]) - if (dataMineKeys.length === 0) { - selector[dataMineName] = undefined - } - } - scanResult = JSON.parse(JSON.stringify(selector)) - } + if (comparisonOperand.index === 1 && algebraOperand.index === 1 && logicOperand.index <= 1) { + logicOperand.picker = newPicker() + let picker = logicOperand.picker + picker.name = 'Logic' + picker.container.connectToParent(thisObject.container) + picker.container.frame.position.x = 0 - picker.container.frame.width / 2 + picker.container.frame.width * 2.5 + picker.container.frame.position.y = 0 - picker.container.frame.height / 2 + yOffset + let optionsList = ['...', 'OR'] + picker.initialize(optionsList) + if (logicOperand.operator === '||') { + picker.setSelected(undefined, undefined, undefined, 1) + } + picker.visible = true + let structureBranch = { + logicOperand: logicOperand, + comparisonOperand: comparisonOperand, + algebraOperand: algebraOperand, + pickerName: 'Logic' + } + picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged, structureBranch) + } - function convertToCode () { - if (conditionStructure === undefined) { return } + let visible = true + if (algebraOperand.index === 1 && comparisonOperand.algebra.picker.getSelected() === '...') { visible = false } + if (logicOperand.comparison.picker !== undefined && comparisonOperand.index === 1 && logicOperand.comparison.picker.getSelected() === 'Equal To') { visible = false } - // chart.at01hs.bollingerSubChannel.previous.previous.slope=== "Extreme" + algebraOperand.whenPicker = newPicker() + algebraOperand.whenPicker.name = 'When' + algebraOperand.whenPicker.container.connectToParent(thisObject.container) + algebraOperand.whenPicker.container.frame.position.x = 0 - algebraOperand.whenPicker.container.frame.width / 2 - algebraOperand.whenPicker.container.frame.width * 0.5 + algebraOperand.whenPicker.container.frame.position.y = 0 - algebraOperand.whenPicker.container.frame.height / 2 + yOffset + current = ['Current', '1 Previous', '2 Previous', '3 Previous', '4 Previous', '5 Previous'] + algebraOperand.whenPicker.initialize(current, current) + algebraOperand.whenPicker.visible = visible - let code = '' + algebraOperand.dataMinePicker = newPicker() + algebraOperand.dataMinePicker.name = 'Data Mine' + algebraOperand.dataMinePicker.container.connectToParent(thisObject.container) + algebraOperand.dataMinePicker.container.frame.position.x = 0 - algebraOperand.dataMinePicker.container.frame.width / 2 - algebraOperand.dataMinePicker.container.frame.width * 2.5 + algebraOperand.dataMinePicker.container.frame.position.y = 0 - algebraOperand.dataMinePicker.container.frame.height / 2 + yOffset + current = scanResult + properties = Object.keys(current) + algebraOperand.dataMinePicker.initialize(properties, current) + parent = current + algebraOperand.dataMinePicker.visible = visible - for (let i = 0; i < conditionStructure.logicOperands.length; i++) { - let logicOperand = conditionStructure.logicOperands[i] - logicOperandToCode(logicOperand) - if (logicOperand.picker.getSelected() !== 'OR') { - break - } else { - code = code + ' || ' - } - } + algebraOperand.botPicker = newPicker() + algebraOperand.botPicker.name = 'Bot' + algebraOperand.botPicker.container.connectToParent(thisObject.container) + algebraOperand.botPicker.container.frame.position.x = 0 - algebraOperand.botPicker.container.frame.width / 2 - algebraOperand.botPicker.container.frame.width * 1.5 + algebraOperand.botPicker.container.frame.position.y = 0 - algebraOperand.botPicker.container.frame.height / 2 + yOffset + current = parent[properties[0]] + properties = Object.keys(current) + algebraOperand.botPicker.initialize(properties, current, parent) + parent = current + algebraOperand.botPicker.visible = visible - thisObject.payload.node.code = code + algebraOperand.productPicker = newPicker() + algebraOperand.productPicker.name = 'Product' + algebraOperand.productPicker.container.connectToParent(thisObject.container) + algebraOperand.productPicker.container.frame.position.x = 0 - algebraOperand.productPicker.container.frame.width / 2 + algebraOperand.productPicker.container.frame.width * 0.5 + algebraOperand.productPicker.container.frame.position.y = 0 - algebraOperand.productPicker.container.frame.height / 2 + yOffset + current = parent[properties[0]] + properties = Object.keys(current) + algebraOperand.productPicker.initialize(properties, current, parent) + parent = current + algebraOperand.productPicker.visible = visible - function logicOperandToCode (logicOperand) { - algebraOperandToCode(logicOperand.comparison.operandA.algebra.operandA) - if (logicOperand.comparison.operandA.algebra.picker.getSelected() !== '...') { - insertAlgebraOperator(logicOperand.comparison.operandA.algebra) - algebraOperandToCode(logicOperand.comparison.operandA.algebra.operandB) - } + let productParent = parent + let productProperties = properties - switch (logicOperand.comparison.picker.getSelected()) { - case 'Greater Than': { - code = code + ' > ' - break - } - case 'Less Than': { - code = code + ' < ' - break - } - case 'Greater or Equal Than': { - code = code + ' >= ' - break - } - case 'Less or Equal Than': { - code = code + ' <= ' - break - } - case 'Equal To': { - code = code + ' === ' - break - } - } + algebraOperand.propertyPicker = newPicker() + algebraOperand.propertyPicker.name = 'Property' + algebraOperand.propertyPicker.container.connectToParent(thisObject.container) + algebraOperand.propertyPicker.container.frame.position.x = 0 - algebraOperand.propertyPicker.container.frame.width / 2 + algebraOperand.propertyPicker.container.frame.width * 1.5 + algebraOperand.propertyPicker.container.frame.position.y = 0 - algebraOperand.propertyPicker.container.frame.height / 2 + yOffset + current = productParent[productProperties[0]] + current = current.properties + properties = Object.keys(current) + algebraOperand.propertyPicker.initialize(properties, current, productParent, 'properties') + parent = current + algebraOperand.propertyPicker.visible = visible - if (logicOperand.comparison.picker.getSelected() === 'Equal To') { - code = code + '"' + logicOperand.comparison.operandA.algebra.operandA.valuePicker.getSelected() + '"' - } else { - algebraOperandToCode(logicOperand.comparison.operandB.algebra.operandA) - if (logicOperand.comparison.operandB.algebra.picker.getSelected() !== '...') { - insertAlgebraOperator(logicOperand.comparison.operandB.algebra) - algebraOperandToCode(logicOperand.comparison.operandB.algebra.operandB) - } - } + algebraOperand.valuePicker = newPicker() + algebraOperand.valuePicker.name = 'Value' + algebraOperand.valuePicker.container.connectToParent(thisObject.container) + algebraOperand.valuePicker.container.frame.position.x = 0 - algebraOperand.valuePicker.container.frame.width / 2 + algebraOperand.valuePicker.container.frame.width * 3.5 + algebraOperand.valuePicker.container.frame.position.y = 0 - algebraOperand.valuePicker.container.frame.height / 2 + yOffset + ALGEBRA_SEPARATION + current = parent[properties[0]] + properties = current.possibleValues + algebraOperand.valuePicker.initialize(properties, current, parent, 'possibleValues') + parent = current + algebraOperand.valuePicker.visible = false + if (logicOperand.comparison.picker !== undefined && logicOperand.comparison.picker.getSelected() === 'Equal To') { + comparisonOperand.algebra.operandA.valuePicker.visible = true + } - function algebraOperandToCode (algebraOperand) { - if (algebraOperand.timeFramePicker.getSelected() === 'Any Time Frame') { - code = code + 'chart.atAnyTimeFrame' - } else { - code = code + 'chart.at' + algebraOperand.timeFramePicker.getSelected().replace('-', '') + algebraOperand.timeFramePicker = newPicker() + algebraOperand.timeFramePicker.name = 'Time Frame' + algebraOperand.timeFramePicker.container.connectToParent(thisObject.container) + algebraOperand.timeFramePicker.container.frame.position.x = 0 - algebraOperand.timeFramePicker.container.frame.width / 2 - algebraOperand.timeFramePicker.container.frame.width * 3.0 + algebraOperand.timeFramePicker.container.frame.position.y = 0 - algebraOperand.timeFramePicker.container.frame.height / 2 + yOffset + algebraOperand.timeFramePicker.container.frame.width = algebraOperand.timeFramePicker.container.frame.width / 2 + current = productParent[productProperties[0]] + properties = current.validTimeFrames + algebraOperand.timeFramePicker.initialize(properties, current, productParent, 'validTimeFrames') + parent = current + algebraOperand.timeFramePicker.visible = visible + + algebraOperand.botPicker.eventSuscriptionId = algebraOperand.dataMinePicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.botPicker.onParentChanged) + algebraOperand.productPicker.eventSuscriptionId = algebraOperand.botPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.productPicker.onParentChanged) + algebraOperand.propertyPicker.eventSuscriptionId = algebraOperand.productPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.propertyPicker.onParentChanged) + algebraOperand.valuePicker.eventSuscriptionId = algebraOperand.propertyPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.valuePicker.onParentChanged) + algebraOperand.timeFramePicker.eventSuscriptionId = algebraOperand.productPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.timeFramePicker.onParentChanged) } - code = code + '.' + algebraOperand.productPicker.getSelected() - insertWhen(algebraOperand) - code = code + '.' + algebraOperand.propertyPicker.getSelected() - } + function updatePickers(logicOperand, comparisonOperand, algebraOperand) { + let codeArray = algebraOperand.code.split('.') - function insertAlgebraOperator (algebra) { - switch (algebra.picker.getSelected()) { - case '...': { - return - } - case 'Plus': { - code = code + ' + ' - return - } - case 'Minus': { - code = code + ' - ' - return - } - case 'Times': { - code = code + ' * ' - return - } - case 'Divided by': { - code = code + ' / ' - return - } + let codeTimeFrame + if (codeArray[1] !== undefined) { + codeTimeFrame = codeArray[1].substring(2, 4) + '-' + codeArray[1].substring(4, 7) + } + + let codeProduct + if (codeArray[2] !== undefined) { + codeProduct = codeArray[2] + } + + /* Parse When */ + let propertyDisplacement = 0 + let codeWhen = 'Current' + if (codeArray[3] === 'previous') { + propertyDisplacement++ + codeWhen = '1 Previous' + } + if (codeArray[4] === 'previous') { + propertyDisplacement++ + codeWhen = '2 Previous' + } + if (codeArray[5] === 'previous') { + propertyDisplacement++ + codeWhen = '3 Previous' + } + if (codeArray[6] === 'previous') { + propertyDisplacement++ + codeWhen = '4 Previous' + } + if (codeArray[7] === 'previous') { + propertyDisplacement++ + codeWhen = '5 Previous' + } + algebraOperand.whenPicker.setSelected(undefined, undefined, undefined, propertyDisplacement) + + let codeProperty + if (codeArray[3 + propertyDisplacement] !== undefined) { + codeProperty = codeArray[3 + propertyDisplacement] + } + + let codeValue = logicOperand.comparison.operandB.code.replace('"', '').replace('"', '') + + let dataMines = Object.keys(scanResult) + for (let i = 0; i < dataMines.length; i++) { + let dataMine = dataMines[i] + let dataMineObject = scanResult[dataMine] + let bots = Object.keys(dataMineObject) + for (let j = 0; j < bots.length; j++) { + let bot = bots[j] + let botObject = dataMineObject[bot] + let products = Object.keys(botObject) + for (let k = 0; k < products.length; k++) { + let product = products[k] + let productObject = botObject[product] + if (codeProduct === product) { + algebraOperand.dataMinePicker.setSelected(dataMines, scanResult, undefined, i) + algebraOperand.botPicker.setSelected(bots, dataMineObject, scanResult, j) + algebraOperand.productPicker.setSelected(products, botObject, dataMineObject, k) + let properties = Object.keys(productObject.properties) + for (let m = 0; m < properties.length; m++) { + let property = properties[m] + let propertyObject = productObject.properties[property] + if (codeProperty === property) { + algebraOperand.propertyPicker.setSelected(properties, productObject.properties, botObject, m) + let values = propertyObject.possibleValues + for (let n = 0; n < values.length; n++) { + let value = values[n] + let valueObject = propertyObject[value] + if (codeValue === value) { + algebraOperand.valuePicker.setSelected(values, propertyObject, productObject, n) + } + } + } + } + let timeFrames = productObject.validTimeFrames + for (let m = 0; m < timeFrames.length; m++) { + let timeFrame = timeFrames[m] + let timeFrameObject = productObject.validTimeFrames[timeFrame] + if (codeTimeFrame === timeFrame) { + algebraOperand.timeFramePicker.setSelected(timeFrames, productObject, botObject, m) + } + } + } + } + } + } } - } - function insertWhen (algebraOperand) { - switch (algebraOperand.whenPicker.getSelected()) { - case 'Current': { - return - } - case '1 Previous': { - code = code + '.previous' - return - } - case '2 Previous': { - code = code + '.previous.previous' - return - } - case '3 Previous': { - code = code + '.previous.previous.previous' - return - } - case '4 Previous': { - code = code + '.previous.previous.previous.previous' - return - } - case '5 Previous': { - code = code + '.previous.previous.previous.previous.previous' - return - } + } + + function scanDataMines() { + let selector = {} + + let workspace = canvas.designSpace.workspace.workspaceNode + + for (let i = 0; i < workspace.rootNodes.length; i++) { + let rootNode = workspace.rootNodes[i] + if (rootNode.type !== 'Data Mine') { continue } + let dataMine = rootNode + let dataMineName = loadPropertyFromNodeConfig(dataMine.payload, 'codeName') + selector[dataMineName] = {} + let bots = dataMine.sensorBots.concat(dataMine.indicatorBots) + for (let j = 0; j < bots.length; j++) { + let bot = bots[j] + let botName = loadPropertyFromNodeConfig(bot.payload, 'codeName') + let selectorDataMine = selector[dataMineName] + selectorDataMine[botName] = {} + for (let k = 0; k < bot.products.length; k++) { + let product = bot.products[k] + let productName = loadPropertyFromNodeConfig(product.payload, 'singularVariableName') + if (productName === undefined) { continue } + let selectorProduct = selectorDataMine[botName] + selectorProduct[productName] = { + properties: {} + } + if (product.record === undefined) { continue } + for (let m = 0; m < product.record.properties.length; m++) { + let property = product.record.properties[m] + let propertyName = loadPropertyFromNodeConfig(property.payload, 'codeName') + let selectorProperty = selectorProduct[productName] + selectorProperty = selectorProperty.properties + selectorProperty[propertyName] = {} + let possibleValues = loadPropertyFromNodeConfig(property.payload, 'possibleValues') + if (possibleValues === undefined) { possibleValues = [] } + let selectorPossibleValue = selectorProperty[propertyName] + selectorPossibleValue.possibleValues = possibleValues + } + let allPossibleTimeFrames = [] + for (let m = 0; m < product.datasets.length; m++) { + let dataset = product.datasets[m] + let validTimeFrames = loadPropertyFromNodeConfig(dataset.payload, 'validTimeFrames') + if (validTimeFrames !== undefined) { + allPossibleTimeFrames = allPossibleTimeFrames.concat(validTimeFrames) + } + } + let selectorValidTimeFrames = selectorProduct[productName] + selectorValidTimeFrames.validTimeFrames = allPossibleTimeFrames + + let productKeys = Object.keys(selectorProduct[productName]) + if (productKeys.length === 0) { + selectorProduct[productName] = undefined + } + } + let botKeys = Object.keys(selectorDataMine[botName]) + if (botKeys.length === 0) { + selectorDataMine[botName] = undefined + } + } + let dataMineKeys = Object.keys(selector[dataMineName]) + if (dataMineKeys.length === 0) { + selector[dataMineName] = undefined + } } - } - } - } - - function finalizePickers () { - if (conditionStructure === undefined) { return } - for (let i = 0; i < conditionStructure.logicOperands.length; i++) { - let logicOperand = conditionStructure.logicOperands[i] - finalizeOperator(logicOperand.comparison.operandA.algebra.operandA) - finalizeOperator(logicOperand.comparison.operandA.algebra.operandB) - finalizeOperator(logicOperand.comparison.operandB.algebra.operandA) - finalizeOperator(logicOperand.comparison.operandB.algebra.operandB) - - if (logicOperand.comparison.operandA.algebra.picker !== undefined) { - logicOperand.comparison.operandA.algebra.picker.container.eventHandler.stopListening(logicOperand.comparison.operandA.algebra.picker.eventSuscriptionId) - logicOperand.comparison.operandA.algebra.picker.finalize() - } - - if (logicOperand.comparison.operandB.algebra.picker !== undefined) { - logicOperand.comparison.operandB.algebra.picker.container.eventHandler.stopListening(logicOperand.comparison.operandB.algebra.picker.eventSuscriptionId) - logicOperand.comparison.operandB.algebra.picker.finalize() - } - - if (logicOperand.comparison.picker !== undefined) { - logicOperand.comparison.picker.container.eventHandler.stopListening(logicOperand.comparison.picker.eventSuscriptionId) - logicOperand.comparison.picker.finalize() - } - - if (logicOperand.picker !== undefined) { - logicOperand.picker.container.eventHandler.stopListening(logicOperand.picker.eventSuscriptionId) - logicOperand.picker.finalize() - } - } - } - - function finalizeOperator (operand) { - if (operand === undefined) { return } - - if (operand.whenPicker !== undefined) { - operand.whenPicker.finalize() - operand.whenPicker = undefined + scanResult = JSON.parse(JSON.stringify(selector)) } - if (operand.dataMinePicker !== undefined) { - operand.dataMinePicker.container.eventHandler.stopListening(operand.botPicker.eventSuscriptionId) - operand.dataMinePicker.finalize() - operand.dataMinePicker = undefined - } + function convertToCode() { + if (conditionStructure === undefined) { return } - if (operand.botPicker !== undefined) { - operand.botPicker.container.eventHandler.stopListening(operand.productPicker.eventSuscriptionId) - operand.botPicker.finalize() - operand.botPicker = undefined - } + // chart.at01hs.bollingerSubChannel.previous.previous.slope=== "Extreme" - if (operand.productPicker !== undefined) { - operand.productPicker.container.eventHandler.stopListening(operand.propertyPicker.eventSuscriptionId) - operand.productPicker.container.eventHandler.stopListening(operand.timeFramePicker.eventSuscriptionId) - operand.productPicker.finalize() - operand.productPicker = undefined - } + let code = '' - if (operand.propertyPicker !== undefined) { - operand.propertyPicker.container.eventHandler.stopListening(operand.valuePicker.eventSuscriptionId) - operand.propertyPicker.finalize() - operand.propertyPicker = undefined - } - - if (operand.valuePicker !== undefined) { - operand.valuePicker.finalize() - operand.valuePicker = undefined - } - - if (operand.timeFramePicker !== undefined) { - operand.timeFramePicker.finalize() - operand.timeFramePicker = undefined - } - } - - function onParentChanged (event, structureBranch) { - let logicOperand = structureBranch.logicOperand - - if (structureBranch.pickerName === 'Logic') { - if (event.selected === 0) { - if (logicOperand.index === 0) { - conditionStructure.logicOperands[1].visible = false - conditionStructure.logicOperands[2].visible = false - } - if (logicOperand.index === 1) { - conditionStructure.logicOperands[2].visible = false - } - } else { - if (logicOperand.index === 0) { - conditionStructure.logicOperands[1].visible = true - - if (conditionStructure.logicOperands[1].picker.getSelected() !== '...') { - conditionStructure.logicOperands[2].visible = true - } - } - if (logicOperand.index === 1) { - conditionStructure.logicOperands[2].visible = true - } - } - } - - if (structureBranch.pickerName === 'Algebra') { - if (event.selected === 0) { - setVisibility(structureBranch.comparisonOperand.algebra.operandB, false) - } else { - setVisibility(structureBranch.comparisonOperand.algebra.operandB, true) - } - } - - if (structureBranch.pickerName === 'Comparison') { - if (event.selected === 4) { - // this means Equal To - - logicOperand.comparison.operandA.algebra.operandA.valuePicker.visible = true - logicOperand.comparison.operandA.algebra.picker.visible = false - logicOperand.comparison.operandB.algebra.picker.visible = false - setVisibility(logicOperand.comparison.operandA.algebra.operandB, false) - setVisibility(logicOperand.comparison.operandB.algebra.operandA, false) - setVisibility(logicOperand.comparison.operandB.algebra.operandB, false) - } else { - logicOperand.comparison.operandA.algebra.operandA.valuePicker.visible = false - logicOperand.comparison.operandA.algebra.picker.visible = true - logicOperand.comparison.operandB.algebra.picker.visible = true - if (logicOperand.comparison.operandA.algebra.picker.getSelected() !== '...') { - setVisibility(logicOperand.comparison.operandA.algebra.operandB, true) + for (let i = 0; i < conditionStructure.logicOperands.length; i++) { + let logicOperand = conditionStructure.logicOperands[i] + logicOperandToCode(logicOperand) + if (logicOperand.picker.getSelected() !== 'OR') { + break + } else { + code = code + ' || ' + } } - if (logicOperand.comparison.picker.getSelected() !== 'Equal To') { - setVisibility(logicOperand.comparison.operandB.algebra.operandA, true) + thisObject.payload.node.code = code + + function logicOperandToCode(logicOperand) { + algebraOperandToCode(logicOperand.comparison.operandA.algebra.operandA) + if (logicOperand.comparison.operandA.algebra.picker.getSelected() !== '...') { + insertAlgebraOperator(logicOperand.comparison.operandA.algebra) + algebraOperandToCode(logicOperand.comparison.operandA.algebra.operandB) + } + + switch (logicOperand.comparison.picker.getSelected()) { + case 'Greater Than': { + code = code + ' > ' + break + } + case 'Less Than': { + code = code + ' < ' + break + } + case 'Greater or Equal Than': { + code = code + ' >= ' + break + } + case 'Less or Equal Than': { + code = code + ' <= ' + break + } + case 'Equal To': { + code = code + ' === ' + break + } + } + + if (logicOperand.comparison.picker.getSelected() === 'Equal To') { + code = code + '"' + logicOperand.comparison.operandA.algebra.operandA.valuePicker.getSelected() + '"' + } else { + algebraOperandToCode(logicOperand.comparison.operandB.algebra.operandA) + if (logicOperand.comparison.operandB.algebra.picker.getSelected() !== '...') { + insertAlgebraOperator(logicOperand.comparison.operandB.algebra) + algebraOperandToCode(logicOperand.comparison.operandB.algebra.operandB) + } + } + + function algebraOperandToCode(algebraOperand) { + if (algebraOperand.timeFramePicker.getSelected() === 'Any Time Frame') { + code = code + 'chart.atAnyTimeFrame' + } else { + code = code + 'chart.at' + algebraOperand.timeFramePicker.getSelected().replace('-', '') + } + + code = code + '.' + algebraOperand.productPicker.getSelected() + insertWhen(algebraOperand) + code = code + '.' + algebraOperand.propertyPicker.getSelected() + } + + function insertAlgebraOperator(algebra) { + switch (algebra.picker.getSelected()) { + case '...': { + return + } + case 'Plus': { + code = code + ' + ' + return + } + case 'Minus': { + code = code + ' - ' + return + } + case 'Times': { + code = code + ' * ' + return + } + case 'Divided by': { + code = code + ' / ' + return + } + } + } + function insertWhen(algebraOperand) { + switch (algebraOperand.whenPicker.getSelected()) { + case 'Current': { + return + } + case '1 Previous': { + code = code + '.previous' + return + } + case '2 Previous': { + code = code + '.previous.previous' + return + } + case '3 Previous': { + code = code + '.previous.previous.previous' + return + } + case '4 Previous': { + code = code + '.previous.previous.previous.previous' + return + } + case '5 Previous': { + code = code + '.previous.previous.previous.previous.previous' + return + } + } + } + } + } + + function finalizePickers() { + if (conditionStructure === undefined) { return } + for (let i = 0; i < conditionStructure.logicOperands.length; i++) { + let logicOperand = conditionStructure.logicOperands[i] + finalizeOperator(logicOperand.comparison.operandA.algebra.operandA) + finalizeOperator(logicOperand.comparison.operandA.algebra.operandB) + finalizeOperator(logicOperand.comparison.operandB.algebra.operandA) + finalizeOperator(logicOperand.comparison.operandB.algebra.operandB) + + if (logicOperand.comparison.operandA.algebra.picker !== undefined) { + logicOperand.comparison.operandA.algebra.picker.container.eventHandler.stopListening(logicOperand.comparison.operandA.algebra.picker.eventSuscriptionId) + logicOperand.comparison.operandA.algebra.picker.finalize() + } + + if (logicOperand.comparison.operandB.algebra.picker !== undefined) { + logicOperand.comparison.operandB.algebra.picker.container.eventHandler.stopListening(logicOperand.comparison.operandB.algebra.picker.eventSuscriptionId) + logicOperand.comparison.operandB.algebra.picker.finalize() + } + + if (logicOperand.comparison.picker !== undefined) { + logicOperand.comparison.picker.container.eventHandler.stopListening(logicOperand.comparison.picker.eventSuscriptionId) + logicOperand.comparison.picker.finalize() + } + + if (logicOperand.picker !== undefined) { + logicOperand.picker.container.eventHandler.stopListening(logicOperand.picker.eventSuscriptionId) + logicOperand.picker.finalize() + } + } + } + + function finalizeOperator(operand) { + if (operand === undefined) { return } + + if (operand.whenPicker !== undefined) { + operand.whenPicker.finalize() + operand.whenPicker = undefined } - if (logicOperand.comparison.operandB.algebra.picker.getSelected() !== '...') { - setVisibility(logicOperand.comparison.operandB.algebra.operandB, true) - } - } - } - - function setLogicOperanVisibility (logicOperand, isVisible) { - - } - - function setVisibility (algebraOperand, isVisible) { - algebraOperand.whenPicker.visible = isVisible - algebraOperand.dataMinePicker.visible = isVisible - algebraOperand.botPicker.visible = isVisible - algebraOperand.productPicker.visible = isVisible - algebraOperand.propertyPicker.visible = isVisible - algebraOperand.timeFramePicker.visible = isVisible - } - } - - function getContainer (point) { - let container - if (thisObject.visible === true) { - if (conditionStructure === undefined) { return } - - for (let i = 0; i < conditionStructure.logicOperands.length; i++) { - let logicOperand = conditionStructure.logicOperands[i] - if (logicOperand.visible !== true) { continue } - - container = operandGetContainer(point, logicOperand.comparison.operandA.algebra.operandA) - if (container !== undefined) { return container } - container = operandGetContainer(point, logicOperand.comparison.operandA.algebra.operandB) - if (container !== undefined) { return container } - container = operandGetContainer(point, logicOperand.comparison.operandB.algebra.operandA) - if (container !== undefined) { return container } - container = operandGetContainer(point, logicOperand.comparison.operandB.algebra.operandB) - if (container !== undefined) { return container } - - if (container = logicOperand.comparison.operandA.algebra.picker !== undefined) { - if (container = logicOperand.comparison.operandA.algebra.picker.visible === true) { - container = logicOperand.comparison.operandA.algebra.picker.getContainer(point) - if (container !== undefined) { return container } - } + if (operand.dataMinePicker !== undefined) { + operand.dataMinePicker.container.eventHandler.stopListening(operand.botPicker.eventSuscriptionId) + operand.dataMinePicker.finalize() + operand.dataMinePicker = undefined } - if (logicOperand.comparison.operandB.algebra.picker !== undefined) { - if (container = logicOperand.comparison.operandB.algebra.picker.visible === true) { - container = logicOperand.comparison.operandB.algebra.picker.getContainer(point) - if (container !== undefined) { return container } - } + if (operand.botPicker !== undefined) { + operand.botPicker.container.eventHandler.stopListening(operand.productPicker.eventSuscriptionId) + operand.botPicker.finalize() + operand.botPicker = undefined } - if (container = logicOperand.comparison.picker !== undefined) { - if (container = logicOperand.comparison.picker.visible === true) { - container = logicOperand.comparison.picker.getContainer(point) - if (container !== undefined) { return container } - } + if (operand.productPicker !== undefined) { + operand.productPicker.container.eventHandler.stopListening(operand.propertyPicker.eventSuscriptionId) + operand.productPicker.container.eventHandler.stopListening(operand.timeFramePicker.eventSuscriptionId) + operand.productPicker.finalize() + operand.productPicker = undefined } - if (container = logicOperand.picker !== undefined) { - if (container = logicOperand.picker.visible === true) { - container = logicOperand.picker.getContainer(point) - if (container !== undefined) { return container } - } + if (operand.propertyPicker !== undefined) { + operand.propertyPicker.container.eventHandler.stopListening(operand.valuePicker.eventSuscriptionId) + operand.propertyPicker.finalize() + operand.propertyPicker = undefined } - } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - } - - function operandGetContainer (point, operand) { - let container - if (operand.whenPicker !== undefined) { - if (operand.whenPicker.visible === true) { - container = operand.whenPicker.getContainer(point) - if (container !== undefined) { return container } - } - } - - if (operand.dataMinePicker !== undefined) { - if (operand.dataMinePicker.visible === true) { - container = operand.dataMinePicker.getContainer(point) - if (container !== undefined) { return container } - } - } - - if (operand.botPicker !== undefined) { - if (operand.botPicker.visible === true) { - container = operand.botPicker.getContainer(point) - if (container !== undefined) { return container } - } - } - - if (operand.productPicker !== undefined) { - if (operand.productPicker.visible === true) { - container = operand.productPicker.getContainer(point) - if (container !== undefined) { return container } - } - } - - if (operand.propertyPicker !== undefined) { - if (operand.propertyPicker.visible === true) { - container = operand.propertyPicker.getContainer(point) - if (container !== undefined) { return container } - } - } - - if (operand.valuePicker !== undefined) { - if (operand.valuePicker.visible === true) { - container = operand.valuePicker.getContainer(point) - if (container !== undefined) { return container } - } - } - - if (operand.timeFramePicker !== undefined) { - if (operand.timeFramePicker.visible === true) { - container = operand.timeFramePicker.getContainer(point) - if (container !== undefined) { return container } - } - } - } - - function physics () { - - } - - function drawBackground () { - thisObjectDrawBackground() - childrenDrawBackground() - } - - function childrenDrawBackground () { - if (conditionStructure === undefined) { return } - - for (let i = 0; i < conditionStructure.logicOperands.length; i++) { - let logicOperand = conditionStructure.logicOperands[i] - if (logicOperand.visible !== true) { continue } - - operandDrawBackground(logicOperand.comparison.operandA.algebra.operandA) - operandDrawBackground(logicOperand.comparison.operandA.algebra.operandB) - operandDrawBackground(logicOperand.comparison.operandB.algebra.operandA) - operandDrawBackground(logicOperand.comparison.operandB.algebra.operandB) - - if (logicOperand.comparison.operandA.algebra.picker !== undefined) { - if (logicOperand.comparison.operandA.algebra.picker.visible === true) { - logicOperand.comparison.operandA.algebra.picker.drawBackground() + if (operand.valuePicker !== undefined) { + operand.valuePicker.finalize() + operand.valuePicker = undefined } - } - if (logicOperand.comparison.operandB.algebra.picker !== undefined) { - if (logicOperand.comparison.operandB.algebra.picker.visible === true) { - logicOperand.comparison.operandB.algebra.picker.drawBackground() + + if (operand.timeFramePicker !== undefined) { + operand.timeFramePicker.finalize() + operand.timeFramePicker = undefined } - } - if (logicOperand.comparison.picker !== undefined) { - if (logicOperand.comparison.picker.visible === true) { - logicOperand.comparison.picker.drawBackground() + } + + function onParentChanged(event, structureBranch) { + let logicOperand = structureBranch.logicOperand + + if (structureBranch.pickerName === 'Logic') { + if (event.selected === 0) { + if (logicOperand.index === 0) { + conditionStructure.logicOperands[1].visible = false + conditionStructure.logicOperands[2].visible = false + } + if (logicOperand.index === 1) { + conditionStructure.logicOperands[2].visible = false + } + } else { + if (logicOperand.index === 0) { + conditionStructure.logicOperands[1].visible = true + + if (conditionStructure.logicOperands[1].picker.getSelected() !== '...') { + conditionStructure.logicOperands[2].visible = true + } + } + if (logicOperand.index === 1) { + conditionStructure.logicOperands[2].visible = true + } + } } - } - if (logicOperand.picker !== undefined) { - if (logicOperand.picker.visible === true) { - logicOperand.picker.drawBackground() + + if (structureBranch.pickerName === 'Algebra') { + if (event.selected === 0) { + setVisibility(structureBranch.comparisonOperand.algebra.operandB, false) + } else { + setVisibility(structureBranch.comparisonOperand.algebra.operandB, true) + } } - } - } - } - function operandDrawBackground (operand) { - if (operand === undefined) { return } + if (structureBranch.pickerName === 'Comparison') { + if (event.selected === 4) { + // this means Equal To - if (operand.whenPicker !== undefined) { - if (operand.whenPicker.visible === true) { - operand.whenPicker.drawBackground() - } - } + logicOperand.comparison.operandA.algebra.operandA.valuePicker.visible = true + logicOperand.comparison.operandA.algebra.picker.visible = false + logicOperand.comparison.operandB.algebra.picker.visible = false + setVisibility(logicOperand.comparison.operandA.algebra.operandB, false) + setVisibility(logicOperand.comparison.operandB.algebra.operandA, false) + setVisibility(logicOperand.comparison.operandB.algebra.operandB, false) + } else { + logicOperand.comparison.operandA.algebra.operandA.valuePicker.visible = false + logicOperand.comparison.operandA.algebra.picker.visible = true + logicOperand.comparison.operandB.algebra.picker.visible = true + if (logicOperand.comparison.operandA.algebra.picker.getSelected() !== '...') { + setVisibility(logicOperand.comparison.operandA.algebra.operandB, true) + } - if (operand.dataMinePicker !== undefined) { - if (operand.dataMinePicker.visible === true) { - operand.dataMinePicker.drawBackground() - } - } + if (logicOperand.comparison.picker.getSelected() !== 'Equal To') { + setVisibility(logicOperand.comparison.operandB.algebra.operandA, true) + } - if (operand.botPicker !== undefined) { - if (operand.botPicker.visible === true) { - operand.botPicker.drawBackground() - } - } - - if (operand.productPicker !== undefined) { - if (operand.productPicker.visible === true) { - operand.productPicker.drawBackground() - } - } - - if (operand.propertyPicker !== undefined) { - if (operand.propertyPicker.visible === true) { - operand.propertyPicker.drawBackground() - } - } - - if (operand.valuePicker !== undefined) { - if (operand.valuePicker.visible === true) { - operand.valuePicker.drawBackground() - } - } - - if (operand.timeFramePicker !== undefined) { - if (operand.timeFramePicker.visible === true) { - operand.timeFramePicker.drawBackground() - } - } - } - - function thisObjectDrawBackground () { - if (thisObject.visible === true) { - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - let radius = thisObject.container.frame.radius - - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius + 3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' - browserCanvasContext.fill() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')' - browserCanvasContext.fill() - } - } - - function drawForeground () { - thisObjectDrawForeground() - childrenDrawForeground() - } - - function childrenDrawForeground () { - if (conditionStructure === undefined) { return } - - for (let i = 0; i < conditionStructure.logicOperands.length; i++) { - let logicOperand = conditionStructure.logicOperands[i] - if (logicOperand.visible !== true) { continue } - - operandDrawForeground(logicOperand.comparison.operandA.algebra.operandA) - operandDrawForeground(logicOperand.comparison.operandA.algebra.operandB) - operandDrawForeground(logicOperand.comparison.operandB.algebra.operandA) - operandDrawForeground(logicOperand.comparison.operandB.algebra.operandB) - - if (logicOperand.comparison.operandA.algebra.picker !== undefined) { - if (logicOperand.comparison.operandA.algebra.picker.visible === true) { - logicOperand.comparison.operandA.algebra.picker.drawForeground() + if (logicOperand.comparison.operandB.algebra.picker.getSelected() !== '...') { + setVisibility(logicOperand.comparison.operandB.algebra.operandB, true) + } + } } - } - if (logicOperand.comparison.operandB.algebra.picker !== undefined) { - if (logicOperand.comparison.operandB.algebra.picker.visible === true) { - logicOperand.comparison.operandB.algebra.picker.drawForeground() + + function setLogicOperanVisibility(logicOperand, isVisible) { + } - } - if (logicOperand.comparison.picker !== undefined) { - if (logicOperand.comparison.picker.visible === true) { - logicOperand.comparison.picker.drawForeground() + + function setVisibility(algebraOperand, isVisible) { + algebraOperand.whenPicker.visible = isVisible + algebraOperand.dataMinePicker.visible = isVisible + algebraOperand.botPicker.visible = isVisible + algebraOperand.productPicker.visible = isVisible + algebraOperand.propertyPicker.visible = isVisible + algebraOperand.timeFramePicker.visible = isVisible } - } - if (logicOperand.picker !== undefined) { - if (logicOperand.picker.visible === true) { - logicOperand.picker.drawForeground() + } + + function getContainer(point) { + let container + if (thisObject.visible === true) { + if (conditionStructure === undefined) { return } + + for (let i = 0; i < conditionStructure.logicOperands.length; i++) { + let logicOperand = conditionStructure.logicOperands[i] + if (logicOperand.visible !== true) { continue } + + container = operandGetContainer(point, logicOperand.comparison.operandA.algebra.operandA) + if (container !== undefined) { return container } + container = operandGetContainer(point, logicOperand.comparison.operandA.algebra.operandB) + if (container !== undefined) { return container } + container = operandGetContainer(point, logicOperand.comparison.operandB.algebra.operandA) + if (container !== undefined) { return container } + container = operandGetContainer(point, logicOperand.comparison.operandB.algebra.operandB) + if (container !== undefined) { return container } + + if (container = logicOperand.comparison.operandA.algebra.picker !== undefined) { + if (container = logicOperand.comparison.operandA.algebra.picker.visible === true) { + container = logicOperand.comparison.operandA.algebra.picker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (logicOperand.comparison.operandB.algebra.picker !== undefined) { + if (container = logicOperand.comparison.operandB.algebra.picker.visible === true) { + container = logicOperand.comparison.operandB.algebra.picker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (container = logicOperand.comparison.picker !== undefined) { + if (container = logicOperand.comparison.picker.visible === true) { + container = logicOperand.comparison.picker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (container = logicOperand.picker !== undefined) { + if (container = logicOperand.picker.visible === true) { + container = logicOperand.picker.getContainer(point) + if (container !== undefined) { return container } + } + } + } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } } - } - } - } - - function operandDrawForeground (operand) { - if (operand === undefined) { return } - - if (operand.whenPicker !== undefined) { - if (operand.whenPicker.visible === true) { - operand.whenPicker.drawForeground() - } } - if (operand.dataMinePicker !== undefined) { - if (operand.dataMinePicker.visible === true) { - operand.dataMinePicker.drawForeground() - } + function operandGetContainer(point, operand) { + let container + if (operand.whenPicker !== undefined) { + if (operand.whenPicker.visible === true) { + container = operand.whenPicker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (operand.dataMinePicker !== undefined) { + if (operand.dataMinePicker.visible === true) { + container = operand.dataMinePicker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (operand.botPicker !== undefined) { + if (operand.botPicker.visible === true) { + container = operand.botPicker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (operand.productPicker !== undefined) { + if (operand.productPicker.visible === true) { + container = operand.productPicker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (operand.propertyPicker !== undefined) { + if (operand.propertyPicker.visible === true) { + container = operand.propertyPicker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (operand.valuePicker !== undefined) { + if (operand.valuePicker.visible === true) { + container = operand.valuePicker.getContainer(point) + if (container !== undefined) { return container } + } + } + + if (operand.timeFramePicker !== undefined) { + if (operand.timeFramePicker.visible === true) { + container = operand.timeFramePicker.getContainer(point) + if (container !== undefined) { return container } + } + } } - if (operand.botPicker !== undefined) { - if (operand.botPicker.visible === true) { - operand.botPicker.drawForeground() - } + function physics() { + } - if (operand.productPicker !== undefined) { - if (operand.productPicker.visible === true) { - operand.productPicker.drawForeground() - } + function drawBackground() { + thisObjectDrawBackground() + childrenDrawBackground() } - if (operand.propertyPicker !== undefined) { - if (operand.propertyPicker.visible === true) { - operand.propertyPicker.drawForeground() - } + function childrenDrawBackground() { + if (conditionStructure === undefined) { return } + + for (let i = 0; i < conditionStructure.logicOperands.length; i++) { + let logicOperand = conditionStructure.logicOperands[i] + if (logicOperand.visible !== true) { continue } + + operandDrawBackground(logicOperand.comparison.operandA.algebra.operandA) + operandDrawBackground(logicOperand.comparison.operandA.algebra.operandB) + operandDrawBackground(logicOperand.comparison.operandB.algebra.operandA) + operandDrawBackground(logicOperand.comparison.operandB.algebra.operandB) + + if (logicOperand.comparison.operandA.algebra.picker !== undefined) { + if (logicOperand.comparison.operandA.algebra.picker.visible === true) { + logicOperand.comparison.operandA.algebra.picker.drawBackground() + } + } + if (logicOperand.comparison.operandB.algebra.picker !== undefined) { + if (logicOperand.comparison.operandB.algebra.picker.visible === true) { + logicOperand.comparison.operandB.algebra.picker.drawBackground() + } + } + if (logicOperand.comparison.picker !== undefined) { + if (logicOperand.comparison.picker.visible === true) { + logicOperand.comparison.picker.drawBackground() + } + } + if (logicOperand.picker !== undefined) { + if (logicOperand.picker.visible === true) { + logicOperand.picker.drawBackground() + } + } + } } - if (operand.valuePicker !== undefined) { - if (operand.valuePicker.visible === true) { - operand.valuePicker.drawForeground() - } + function operandDrawBackground(operand) { + if (operand === undefined) { return } + + if (operand.whenPicker !== undefined) { + if (operand.whenPicker.visible === true) { + operand.whenPicker.drawBackground() + } + } + + if (operand.dataMinePicker !== undefined) { + if (operand.dataMinePicker.visible === true) { + operand.dataMinePicker.drawBackground() + } + } + + if (operand.botPicker !== undefined) { + if (operand.botPicker.visible === true) { + operand.botPicker.drawBackground() + } + } + + if (operand.productPicker !== undefined) { + if (operand.productPicker.visible === true) { + operand.productPicker.drawBackground() + } + } + + if (operand.propertyPicker !== undefined) { + if (operand.propertyPicker.visible === true) { + operand.propertyPicker.drawBackground() + } + } + + if (operand.valuePicker !== undefined) { + if (operand.valuePicker.visible === true) { + operand.valuePicker.drawBackground() + } + } + + if (operand.timeFramePicker !== undefined) { + if (operand.timeFramePicker.visible === true) { + operand.timeFramePicker.drawBackground() + } + } } - if (operand.timeFramePicker !== undefined) { - if (operand.timeFramePicker.visible === true) { - operand.timeFramePicker.drawForeground() - } - } - } + function thisObjectDrawBackground() { + if (thisObject.visible === true) { + let position = { + x: 0, + y: 0 + } - function thisObjectDrawForeground () { - if (thisObject.visible === true) { - const SIZE = 36 - drawIcon(timeFrameIcon, 0, 0, -PICKER_WIDTH * 3.25, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(dataMineIcon, 0, 0, -PICKER_WIDTH * 2.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(botIcon, 0, 0, -PICKER_WIDTH * 1.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(whenIcon, 0, 0, -PICKER_WIDTH * 0.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(productIcon, 0, 0, PICKER_WIDTH * 0.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(propertyIcon, 0, 0, PICKER_WIDTH * 1.45, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(operationIcon, 0, 0, PICKER_WIDTH * 2.45, -PICKER_HEIGHT * 7, SIZE, thisObject.container) - drawIcon(valueIcon, 0, 0, PICKER_WIDTH * 3.45, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + position = thisObject.container.frame.frameThisPoint(position) + + let radius = thisObject.container.frame.radius + + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius + 3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' + browserCanvasContext.fill() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')' + browserCanvasContext.fill() + } + } + + function drawForeground() { + thisObjectDrawForeground() + childrenDrawForeground() + } + + function childrenDrawForeground() { + if (conditionStructure === undefined) { return } + + for (let i = 0; i < conditionStructure.logicOperands.length; i++) { + let logicOperand = conditionStructure.logicOperands[i] + if (logicOperand.visible !== true) { continue } + + operandDrawForeground(logicOperand.comparison.operandA.algebra.operandA) + operandDrawForeground(logicOperand.comparison.operandA.algebra.operandB) + operandDrawForeground(logicOperand.comparison.operandB.algebra.operandA) + operandDrawForeground(logicOperand.comparison.operandB.algebra.operandB) + + if (logicOperand.comparison.operandA.algebra.picker !== undefined) { + if (logicOperand.comparison.operandA.algebra.picker.visible === true) { + logicOperand.comparison.operandA.algebra.picker.drawForeground() + } + } + if (logicOperand.comparison.operandB.algebra.picker !== undefined) { + if (logicOperand.comparison.operandB.algebra.picker.visible === true) { + logicOperand.comparison.operandB.algebra.picker.drawForeground() + } + } + if (logicOperand.comparison.picker !== undefined) { + if (logicOperand.comparison.picker.visible === true) { + logicOperand.comparison.picker.drawForeground() + } + } + if (logicOperand.picker !== undefined) { + if (logicOperand.picker.visible === true) { + logicOperand.picker.drawForeground() + } + } + } + } + + function operandDrawForeground(operand) { + if (operand === undefined) { return } + + if (operand.whenPicker !== undefined) { + if (operand.whenPicker.visible === true) { + operand.whenPicker.drawForeground() + } + } + + if (operand.dataMinePicker !== undefined) { + if (operand.dataMinePicker.visible === true) { + operand.dataMinePicker.drawForeground() + } + } + + if (operand.botPicker !== undefined) { + if (operand.botPicker.visible === true) { + operand.botPicker.drawForeground() + } + } + + if (operand.productPicker !== undefined) { + if (operand.productPicker.visible === true) { + operand.productPicker.drawForeground() + } + } + + if (operand.propertyPicker !== undefined) { + if (operand.propertyPicker.visible === true) { + operand.propertyPicker.drawForeground() + } + } + + if (operand.valuePicker !== undefined) { + if (operand.valuePicker.visible === true) { + operand.valuePicker.drawForeground() + } + } + + if (operand.timeFramePicker !== undefined) { + if (operand.timeFramePicker.visible === true) { + operand.timeFramePicker.drawForeground() + } + } + } + + function thisObjectDrawForeground() { + if (thisObject.visible === true) { + const SIZE = 36 + drawIcon(timeFrameIcon, 0, 0, -PICKER_WIDTH * 3.25, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(dataMineIcon, 0, 0, -PICKER_WIDTH * 2.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(botIcon, 0, 0, -PICKER_WIDTH * 1.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(whenIcon, 0, 0, -PICKER_WIDTH * 0.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(productIcon, 0, 0, PICKER_WIDTH * 0.5, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(propertyIcon, 0, 0, PICKER_WIDTH * 1.45, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(operationIcon, 0, 0, PICKER_WIDTH * 2.45, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + drawIcon(valueIcon, 0, 0, PICKER_WIDTH * 3.45, -PICKER_HEIGHT * 7, SIZE, thisObject.container) + } } - } } diff --git a/FloatingSpace/ConfigEditor.js b/FloatingSpace/ConfigEditor.js index 8cb2ffb83..e62179f68 100644 --- a/FloatingSpace/ConfigEditor.js +++ b/FloatingSpace/ConfigEditor.js @@ -1,205 +1,205 @@ -function newConfigEditor () { - const MODULE_NAME = 'Config Editor' +function newConfigEditor() { + const MODULE_NAME = 'Config Editor' - let thisObject = { - isVisibleFunction: undefined, - visible: false, - imagePathOK: undefined, - imagePathNOT_OK: undefined, - rawRadius: undefined, - targetRadius: undefined, - currentRadius: undefined, - container: undefined, - payload: undefined, - deactivate: deactivate, - activate: activate, - physics: physics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let isMouseOver = false - let SIZE_FACTOR = 1 - - return thisObject - - function finalize () { - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.isVisibleFunction = undefined - } - - function initialize () { - - } - - function deactivate () { - if (thisObject.visible === true) { - thisObject.visible = false - let textArea = document.getElementById('textArea') - textArea.style.display = 'none' - thisObject.payload.node.config = textArea.value - - try { - let config = JSON.parse(thisObject.payload.node.config) - } catch (err) { - thisObject.payload.uiObject.setErrorMessage(err.message, 10) - } - } - EDITOR_ON_FOCUS = false - } - - function activate (payload) { - thisObject.visible = true - thisObject.payload = payload - thisObject.rawRadius = 8 - thisObject.targetRadius = thisObject.container.frame.radius - thisObject.currentRadius = 0 - thisObject.payload.uiObject.setErrorMessage('', 0) - - let textArea = document.getElementById('textArea') - textArea.value = payload.node.config - textArea.style = 'resize: none;' + - ' border: none;' + - ' outline: none;' + - 'box-shadow: none;' + - 'overflow:hidden;' + - 'font-family: ' + UI_FONT.PRIMARY + ';' + - 'font-size: 14px;' + - 'background-color: rgb(' + UI_COLOR.DARK_TURQUOISE + ');' + - 'color:rgb(255, 255, 255);' + - 'width: ' + thisObject.container.frame.width + 'px;' + - 'height: ' + thisObject.container.frame.height + 'px' - textArea.style.display = 'block' - textArea.focus() - EDITOR_ON_FOCUS = true - } - - function getContainer (point) { - let container - if (thisObject.visible === true) { - if (point.x === VERY_LARGE_NUMBER) { - /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that - anyone can react. In our case, the config editor has a text area that is not part of the canvas, so the event is - triggered. We compensate recognizing this coordinate and returning our container. */ - return thisObject.container - } - - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - return thisObject.container - } else { - return undefined - } - } - } - - function physics () { - if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { - if (thisObject.currentRadius < thisObject.targetRadius) { - thisObject.currentRadius = thisObject.currentRadius + 0.5 - } else { - thisObject.currentRadius = thisObject.currentRadius - 0.5 - } + let thisObject = { + isVisibleFunction: undefined, + visible: false, + imagePathOK: undefined, + imagePathNOT_OK: undefined, + rawRadius: undefined, + targetRadius: undefined, + currentRadius: undefined, + container: undefined, + payload: undefined, + deactivate: deactivate, + activate: activate, + physics: physics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = false + thisObject.container.frame.radius = 0 thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR - thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR + let isMouseOver = false + let SIZE_FACTOR = 1 - let textAreaPosition = { - x: 0 - thisObject.container.frame.width / 2, - y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN + return thisObject + + function finalize() { + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.isVisibleFunction = undefined } - textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) - if (thisObject.visible === true) { - let checkPosition = { - x: textAreaPosition.x, - y: textAreaPosition.y - CURRENT_TOP_MARGIN - } - if (thisObject.isVisibleFunction(checkPosition) === false) { - deactivate() - } - } - if (thisObject.visible === true) { - let textAreaDiv = document.getElementById('textAreaDiv') - textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; ' - } - } + function initialize() { - function drawBackground () { - if (thisObject.visible === true) { - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - let radius = thisObject.container.frame.radius * SIZE_FACTOR - - if (radius > 0.5) { - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' - browserCanvasContext.fill() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + 1 + ')' - browserCanvasContext.fill() - } - } - } - function drawForeground () { - let iconPosition = { - x: 0, - y: thisObject.currentRadius * 1.5 } - iconPosition = thisObject.container.frame.frameThisPoint(iconPosition) + function deactivate() { + if (thisObject.visible === true) { + thisObject.visible = false + let textArea = document.getElementById('textArea') + textArea.style.display = 'none' + thisObject.payload.node.config = textArea.value - /* Menu Item */ + try { + let config = JSON.parse(thisObject.payload.node.config) + } catch (err) { + thisObject.payload.uiObject.setErrorMessage(err.message, 10) + } + } + EDITOR_ON_FOCUS = false + } - if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) { - browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + function activate(payload) { + thisObject.visible = true + thisObject.payload = payload + thisObject.rawRadius = 8 + thisObject.targetRadius = thisObject.container.frame.radius + thisObject.currentRadius = 0 + thisObject.payload.uiObject.setErrorMessage('', 0) - /* Menu Label */ + let textArea = document.getElementById('textArea') + textArea.value = payload.node.config + textArea.style = 'resize: none;' + + ' border: none;' + + ' outline: none;' + + 'box-shadow: none;' + + 'overflow:hidden;' + + 'font-family: ' + UI_FONT.PRIMARY + ';' + + 'font-size: 14px;' + + 'background-color: rgb(' + UI_COLOR.DARK_TURQUOISE + ');' + + 'color:rgb(255, 255, 255);' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + textArea.style.display = 'block' + textArea.focus() + EDITOR_ON_FOCUS = true + } - let label = 'Code looks good!' - let labelPoint - let fontSize = 10 + function getContainer(point) { + let container + if (thisObject.visible === true) { + if (point.x === VERY_LARGE_NUMBER) { + /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that + anyone can react. In our case, the config editor has a text area that is not part of the canvas, so the event is + triggered. We compensate recognizing this coordinate and returning our container. */ + return thisObject.container + } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + return thisObject.container + } else { + return undefined + } + } + } - if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) { - labelPoint = { - x: iconPosition.x + thisObject.currentRadius + 10, - y: iconPosition.y + fontSize * FONT_ASPECT_RATIO + function physics() { + if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { + if (thisObject.currentRadius < thisObject.targetRadius) { + thisObject.currentRadius = thisObject.currentRadius + 0.5 + } else { + thisObject.currentRadius = thisObject.currentRadius - 0.5 + } } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + + thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR + thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR + + let textAreaPosition = { + x: 0 - thisObject.container.frame.width / 2, + y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN + } + + textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) + if (thisObject.visible === true) { + let checkPosition = { + x: textAreaPosition.x, + y: textAreaPosition.y - CURRENT_TOP_MARGIN + } + if (thisObject.isVisibleFunction(checkPosition) === false) { + deactivate() + } + } + if (thisObject.visible === true) { + let textAreaDiv = document.getElementById('textAreaDiv') + textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; ' + } + } + + function drawBackground() { + if (thisObject.visible === true) { + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + let radius = thisObject.container.frame.radius * SIZE_FACTOR + + if (radius > 0.5) { + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' + browserCanvasContext.fill() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + 1 + ')' + browserCanvasContext.fill() + } + } + } + function drawForeground() { + let iconPosition = { + x: 0, + y: thisObject.currentRadius * 1.5 + } + + iconPosition = thisObject.container.frame.frameThisPoint(iconPosition) + + /* Menu Item */ + + if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) { + browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + + /* Menu Label */ + + let label = 'Code looks good!' + let labelPoint + let fontSize = 10 + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + + if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) { + labelPoint = { + x: iconPosition.x + thisObject.currentRadius + 10, + y: iconPosition.y + fontSize * FONT_ASPECT_RATIO + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } } - } } diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index 4653bd532..bb59a9a7c 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -13,22 +13,22 @@ 3. UI Objects: These are small balls that represent parts of an strategy. */ -function newFloatingLayer () { - const MODULE_NAME = 'Floating Layer' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newFloatingLayer() { + const MODULE_NAME = 'Floating Layer' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - addFloatingObject: addFloatingObject, - removeFloatingObject: removeFloatingObject, - getFloatingObject: getFloatingObject, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } + let thisObject = { + addFloatingObject: addFloatingObject, + removeFloatingObject: removeFloatingObject, + getFloatingObject: getFloatingObject, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize + } /* When objects are added to this layer they are added to the invisibleFloatingObjects array and they stay there because they are invisible. @@ -38,7 +38,7 @@ function newFloatingLayer () { To save resources, the physics engine only apply its calculations to visible floating objects. */ - let invisibleFloatingObjects = [] + let invisibleFloatingObjects = [] /* Floating objects are accesible to plotters because they carry a "payload" object that was creted by them. This object includes the position @@ -48,206 +48,206 @@ function newFloatingLayer () { array. */ - let visibleFloatingObjects = [] + let visibleFloatingObjects = [] - let maxTargetRepulsionForce = 0.001 - let currentHandle = 0 + let maxTargetRepulsionForce = 0.001 + let currentHandle = 0 - return thisObject + return thisObject - function finalize () { - invisibleFloatingObjects = [] - visibleFloatingObjects = [] - } + function finalize() { + invisibleFloatingObjects = [] + visibleFloatingObjects = [] + } - function initialize () { + function initialize() { /* We dont need to initialize anything right now. */ - } - - function getContainer (point) { - let container - - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - container = floatingObject.getContainer(point) - if (container !== undefined) { return container } } - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - container = floatingObject.getContainer(point) - if (container !== undefined) { return container } + function getContainer(point) { + let container + + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + container = floatingObject.getContainer(point) + if (container !== undefined) { return container } + } + + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] + container = floatingObject.getContainer(point) + if (container !== undefined) { return container } + } + + return container } - return container - } - - function addFloatingObject (pFloatingObject) { - currentHandle++ - pFloatingObject.handle = currentHandle // Math.floor((Math.random() * 10000000) + 1); - visibleFloatingObjects.push(pFloatingObject) - } - - function removeFloatingObject (pFloatingObjectHandle) { - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - - if (floatingObject.handle === pFloatingObjectHandle) { - invisibleFloatingObjects.splice(i, 1) // Delete item from array. - return - } + function addFloatingObject(pFloatingObject) { + currentHandle++ + pFloatingObject.handle = currentHandle // Math.floor((Math.random() * 10000000) + 1); + visibleFloatingObjects.push(pFloatingObject) } - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] + function removeFloatingObject(pFloatingObjectHandle) { + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] - if (floatingObject.handle === pFloatingObjectHandle) { - visibleFloatingObjects.splice(i, 1) // Delete item from array. - return - } + if (floatingObject.handle === pFloatingObjectHandle) { + invisibleFloatingObjects.splice(i, 1) // Delete item from array. + return + } + } + + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + + if (floatingObject.handle === pFloatingObjectHandle) { + visibleFloatingObjects.splice(i, 1) // Delete item from array. + return + } + } } - } - function getFloatingObject (pFloatingObjectHandle, pFloatingObjectIndex) { + function getFloatingObject(pFloatingObjectHandle, pFloatingObjectIndex) { /* There are two ways to look for a floating object: by handle or by index. The search by handle is done on the visible and invisible array. The search by index is done only on the visible ones. The search by index is usually needed when mouse events occurs. In those cases only objects visible to the end usser matters. */ - try { - if (pFloatingObjectHandle !== undefined) { + try { + if (pFloatingObjectHandle !== undefined) { + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] + + if (floatingObject.handle === pFloatingObjectHandle) { + return floatingObject + } + } + + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + + if (floatingObject.handle === pFloatingObjectHandle) { + return floatingObject + } + } + } + + if (pFloatingObjectIndex !== undefined) { + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + + if (i === pFloatingObjectIndex) { + return floatingObject + } + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] getFloatingObject -> err= ' + err.stack) } + } + } + + function draw() { + drawInvisibleObjects() + drawVisibleObjects() + } + + function drawInvisibleObjects() { for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] + let floatingObject = invisibleFloatingObjects[i] + floatingObject.drawBackground() + } - if (floatingObject.handle === pFloatingObjectHandle) { - return floatingObject - } + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] + floatingObject.drawMiddleground() + } + + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[invisibleFloatingObjects.length - i - 1] + floatingObject.drawForeground() + } + } + + function drawVisibleObjects() { + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + floatingObject.drawBackground() } for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - - if (floatingObject.handle === pFloatingObjectHandle) { - return floatingObject - } + let floatingObject = visibleFloatingObjects[i] + floatingObject.drawMiddleground() } - } - if (pFloatingObjectIndex !== undefined) { for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - - if (i === pFloatingObjectIndex) { - return floatingObject - } + let floatingObject = visibleFloatingObjects[visibleFloatingObjects.length - i - 1] + floatingObject.drawForeground() } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] getFloatingObject -> err= ' + err.stack) } - } - } - function draw () { - drawInvisibleObjects() - drawVisibleObjects() - } + /* Invisible objects on focus (freezed) should still have some priority */ + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] + floatingObject.drawOnFocus() + } - function drawInvisibleObjects () { - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - floatingObject.drawBackground() + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + floatingObject.drawOnFocus() + } } - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - floatingObject.drawMiddleground() + function collapsePhysics(thisObject) { + let parent = thisObject.payload.chainParent + if (parent === undefined) { return } + if (parent.payload === undefined) { return } + if (parent.payload.floatingObject === undefined) { return } + + thisObject.isParentCollapsed = parent.payload.floatingObject.isCollapsed + if (thisObject.collapsedManually === false) { + thisObject.isCollapsed = parent.payload.floatingObject.isCollapsed + } } - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[invisibleFloatingObjects.length - i - 1] - floatingObject.drawForeground() - } - } + function makeVisible() { + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] - function drawVisibleObjects () { - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - floatingObject.drawBackground() + collapsePhysics(floatingObject) + + if (floatingObject.isParentCollapsed === false) { + visibleFloatingObjects.push(floatingObject) + invisibleFloatingObjects.splice(i, 1) // Delete item from array. + makeVisible() + return // Only one at the time. + } + } } - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - floatingObject.drawMiddleground() + function makeInvisible() { + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + + collapsePhysics(floatingObject) + + if (floatingObject.isParentCollapsed === true) { + invisibleFloatingObjects.push(floatingObject) + visibleFloatingObjects.splice(i, 1) // Delete item from array. + makeInvisible() + return // Only one at the time. + } + } } - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[visibleFloatingObjects.length - i - 1] - floatingObject.drawForeground() - } - - /* Invisible objects on focus (freezed) should still have some priority */ - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - floatingObject.drawOnFocus() - } - - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - floatingObject.drawOnFocus() - } - } - - function collapsePhysics (thisObject) { - let parent = thisObject.payload.chainParent - if (parent === undefined) { return } - if (parent.payload === undefined) { return } - if (parent.payload.floatingObject === undefined) { return } - - thisObject.isParentCollapsed = parent.payload.floatingObject.isCollapsed - if (thisObject.collapsedManually === false) { - thisObject.isCollapsed = parent.payload.floatingObject.isCollapsed - } - } - - function makeVisible () { - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - - collapsePhysics(floatingObject) - - if (floatingObject.isParentCollapsed === false) { - visibleFloatingObjects.push(floatingObject) - invisibleFloatingObjects.splice(i, 1) // Delete item from array. - makeVisible() - return // Only one at the time. - } - } - } - - function makeInvisible () { - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - - collapsePhysics(floatingObject) - - if (floatingObject.isParentCollapsed === true) { - invisibleFloatingObjects.push(floatingObject) - visibleFloatingObjects.splice(i, 1) // Delete item from array. - makeInvisible() - return // Only one at the time. - } - } - } - /******************************************/ /* */ /* Physics Engine Follows */ /* */ /******************************************/ - function physics () { + function physics() { /* The Physics engine is hooked at the animation loop, so it executes very very often. According to this Physics engine, each floating object has a position and a speed. In fact, each floating object has two positions at the same time: @@ -262,483 +262,483 @@ function newFloatingLayer () { */ - try { - makeVisible() - makeInvisible() - invisiblePhysics() - visiblePhysics() - applyPhysics() + try { + makeVisible() + makeInvisible() + invisiblePhysics() + visiblePhysics() + applyPhysics() - function invisiblePhysics () { - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - floatingObject.invisiblePhysics() - } - } + function invisiblePhysics() { + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] + floatingObject.invisiblePhysics() + } + } - function visiblePhysics () { - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - floatingObject.physics() - } - } + function visiblePhysics() { + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + floatingObject.physics() + } + } - function applyPhysics () { + function applyPhysics() { /* This function makes all the calculations to apply phisycs on all visible floatingObjects in this layer. */ - try { - DEBUG.variable1 = 'Invisible Floating Objets: ' + invisibleFloatingObjects.length - DEBUG.variable2 = 'Visible Floating Objets: ' + visibleFloatingObjects.length + try { + DEBUG.variable1 = 'Invisible Floating Objets: ' + invisibleFloatingObjects.length + DEBUG.variable2 = 'Visible Floating Objets: ' + visibleFloatingObjects.length - for (let i = 0; i < visibleFloatingObjects.length; i++) { - let floatingObject = visibleFloatingObjects[i] - if (floatingObject.isFrozen === true) { continue } + for (let i = 0; i < visibleFloatingObjects.length; i++) { + let floatingObject = visibleFloatingObjects[i] + if (floatingObject.isFrozen === true) { continue } - /* From here on, only if they are not too far. */ - if (canvas.floatingSpace.isItFar(floatingObject.payload)) { continue } + /* From here on, only if they are not too far. */ + if (canvas.floatingSpace.isItFar(floatingObject.payload)) { continue } - if (floatingObject.positionLocked === false) { - floatingObject.container.frame.position.x = floatingObject.container.frame.position.x + floatingObject.currentSpeed.x - floatingObject.container.frame.position.y = floatingObject.container.frame.position.y + floatingObject.currentSpeed.y - } + if (floatingObject.positionLocked === false) { + floatingObject.container.frame.position.x = floatingObject.container.frame.position.x + floatingObject.currentSpeed.x + floatingObject.container.frame.position.y = floatingObject.container.frame.position.y + floatingObject.currentSpeed.y + } - if (floatingObject.friction < floatingObject.targetFriction) { - floatingObject.friction = floatingObject.friction + 0.00001 - } else { - floatingObject.friction = floatingObject.friction - 0.00001 - } + if (floatingObject.friction < floatingObject.targetFriction) { + floatingObject.friction = floatingObject.friction + 0.00001 + } else { + floatingObject.friction = floatingObject.friction - 0.00001 + } - floatingObject.currentSpeed.x = floatingObject.currentSpeed.x * floatingObject.friction // Desaceleration factor. - floatingObject.currentSpeed.y = floatingObject.currentSpeed.y * floatingObject.friction // Desaceleration factor. + floatingObject.currentSpeed.x = floatingObject.currentSpeed.x * floatingObject.friction // Desaceleration factor. + floatingObject.currentSpeed.y = floatingObject.currentSpeed.y * floatingObject.friction // Desaceleration factor. - let payload = { - position: undefined, - visible: false - } + let payload = { + position: undefined, + visible: false + } - switch (floatingObject.type) { - case 'UI Object': { - payload.targetPosition = floatingObject.payload.targetPosition - payload.visible = floatingObject.payload.visible - break - } - default: { - break - } - } + switch (floatingObject.type) { + case 'UI Object': { + payload.targetPosition = floatingObject.payload.targetPosition + payload.visible = floatingObject.payload.visible + break + } + default: { + break + } + } - if (floatingObject.container.frame.position.x < payload.targetPosition.x) { - floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + 0.005 - } else { - floatingObject.currentSpeed.x = floatingObject.currentSpeed.x - 0.005 - } + if (floatingObject.container.frame.position.x < payload.targetPosition.x) { + floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + 0.005 + } else { + floatingObject.currentSpeed.x = floatingObject.currentSpeed.x - 0.005 + } - if (floatingObject.container.frame.position.y < payload.targetPosition.y) { - floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + 0.005 - } else { - floatingObject.currentSpeed.y = floatingObject.currentSpeed.y - 0.005 - } + if (floatingObject.container.frame.position.y < payload.targetPosition.y) { + floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + 0.005 + } else { + floatingObject.currentSpeed.y = floatingObject.currentSpeed.y - 0.005 + } - const MAX_SPEED = 10 + const MAX_SPEED = 10 - if (floatingObject.currentSpeed.x > MAX_SPEED) { - floatingObject.currentSpeed.x = MAX_SPEED - } + if (floatingObject.currentSpeed.x > MAX_SPEED) { + floatingObject.currentSpeed.x = MAX_SPEED + } - if (floatingObject.currentSpeed.y > MAX_SPEED) { - floatingObject.currentSpeed.y = MAX_SPEED - } + if (floatingObject.currentSpeed.y > MAX_SPEED) { + floatingObject.currentSpeed.y = MAX_SPEED + } - if (floatingObject.currentSpeed.x < -MAX_SPEED) { - floatingObject.currentSpeed.x = -MAX_SPEED - } + if (floatingObject.currentSpeed.x < -MAX_SPEED) { + floatingObject.currentSpeed.x = -MAX_SPEED + } - if (floatingObject.currentSpeed.y < -MAX_SPEED) { - floatingObject.currentSpeed.y = -MAX_SPEED - } + if (floatingObject.currentSpeed.y < -MAX_SPEED) { + floatingObject.currentSpeed.y = -MAX_SPEED + } // We let the Floating Object animate the physics loops by itself. - checkBoundaries(floatingObject) + checkBoundaries(floatingObject) /* Collision Control */ - for (let k = i + 1; k < visibleFloatingObjects.length; k++) { - if (colliding(visibleFloatingObjects[i], visibleFloatingObjects[k])) { - resolveCollision(visibleFloatingObjects[k], visibleFloatingObjects[i]) - } - } + for (let k = i + 1; k < visibleFloatingObjects.length; k++) { + if (colliding(visibleFloatingObjects[i], visibleFloatingObjects[k])) { + resolveCollision(visibleFloatingObjects[k], visibleFloatingObjects[i]) + } + } /* Calculate repulsion force produced by all other floatingObjects */ - repulsionForceBetweenFloatingObjects(i) + repulsionForceBetweenFloatingObjects(i) - targetRepulsionForce(i) + targetRepulsionForce(i) - gravityForce(floatingObject, payload) + gravityForce(floatingObject, payload) - proximityBetweenFloatingObjects(i) - } + proximityBetweenFloatingObjects(i) + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] physics -> applyPhysics -> err= ' + err.stack) } + } + } } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] physics -> applyPhysics -> err= ' + err.stack) } + if (ERROR_LOG === true) { logger.write('[ERROR] physics -> err= ' + err.stack) } } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] physics -> err= ' + err.stack) } - } - } - - function checkBoundaries (floatingObject) { - if (floatingObject.container.frame.position.x - floatingObject.container.frame.radius < 0) { - floatingObject.container.frame.position.x = floatingObject.container.frame.radius - floatingObject.currentSpeed.x = -floatingObject.currentSpeed.x } - if (floatingObject.container.frame.position.x + floatingObject.container.frame.radius > canvas.floatingSpace.container.frame.width) { - floatingObject.container.frame.position.x = canvas.floatingSpace.container.frame.width - floatingObject.container.frame.radius - floatingObject.currentSpeed.x = -floatingObject.currentSpeed.x + function checkBoundaries(floatingObject) { + if (floatingObject.container.frame.position.x - floatingObject.container.frame.radius < 0) { + floatingObject.container.frame.position.x = floatingObject.container.frame.radius + floatingObject.currentSpeed.x = -floatingObject.currentSpeed.x + } + + if (floatingObject.container.frame.position.x + floatingObject.container.frame.radius > canvas.floatingSpace.container.frame.width) { + floatingObject.container.frame.position.x = canvas.floatingSpace.container.frame.width - floatingObject.container.frame.radius + floatingObject.currentSpeed.x = -floatingObject.currentSpeed.x + } + + if (floatingObject.container.frame.position.y - floatingObject.container.frame.radius < 0) { + floatingObject.container.frame.position.y = floatingObject.container.frame.radius + floatingObject.currentSpeed.y = -floatingObject.currentSpeed.y + } + + if (floatingObject.container.frame.position.y + floatingObject.container.frame.radius > canvas.floatingSpace.container.frame.height) { + floatingObject.container.frame.position.y = canvas.floatingSpace.container.frame.height - floatingObject.container.frame.radius + floatingObject.currentSpeed.y = -floatingObject.currentSpeed.y + } } - if (floatingObject.container.frame.position.y - floatingObject.container.frame.radius < 0) { - floatingObject.container.frame.position.y = floatingObject.container.frame.radius - floatingObject.currentSpeed.y = -floatingObject.currentSpeed.y - } - - if (floatingObject.container.frame.position.y + floatingObject.container.frame.radius > canvas.floatingSpace.container.frame.height) { - floatingObject.container.frame.position.y = canvas.floatingSpace.container.frame.height - floatingObject.container.frame.radius - floatingObject.currentSpeed.y = -floatingObject.currentSpeed.y - } - } - - function gravityForce (floatingObject, payload) { - try { + function gravityForce(floatingObject, payload) { + try { /* We simulate a kind of gravity towards the target point of each floatingObject. This force will make the floatingObject to keep pushing to reach that point. */ - const coulomb = 0.00001 - const minForce = 0.01 + const coulomb = 0.00001 + const minForce = 0.01 - let d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject.container.frame.position.y, 2)) // ... we calculate the distance ... + let d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject.container.frame.position.y, 2)) // ... we calculate the distance ... - let force = coulomb * d * d / floatingObject.currentMass // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects. + let force = coulomb * d * d / floatingObject.currentMass // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects. - if (force < minForce) { // We need this attraction force to overcome the friction we imposed to the system. - force = minForce - } + if (force < minForce) { // We need this attraction force to overcome the friction we imposed to the system. + force = minForce + } - let pos1 = { - x: floatingObject.container.frame.position.x, - y: floatingObject.container.frame.position.y - } + let pos1 = { + x: floatingObject.container.frame.position.x, + y: floatingObject.container.frame.position.y + } - let pos2 = { - x: payload.targetPosition.x, - y: payload.targetPosition.y - } + let pos2 = { + x: payload.targetPosition.x, + y: payload.targetPosition.y + } - let posDiff = { // Next we need the vector resulting from the 2 positions. - x: pos2.x - pos1.x, - y: pos2.y - pos1.y - } + let posDiff = { // Next we need the vector resulting from the 2 positions. + x: pos2.x - pos1.x, + y: pos2.y - pos1.y + } - if (d !== 0) { - let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector. - x: posDiff.x / d, - y: posDiff.y / d + if (d !== 0) { + let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector. + x: posDiff.x / d, + y: posDiff.y / d + } + + let forceVector = { + x: unitVector.x * force, + y: unitVector.y * force + } + + /* We add the force vector to the speed vector */ + if (isNaN(forceVector.x) === false && isNaN(forceVector.y) === false) { + floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + forceVector.x + floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + forceVector.y + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] gravityForce -> err= ' + err.stack) } } - - let forceVector = { - x: unitVector.x * force, - y: unitVector.y * force - } - - /* We add the force vector to the speed vector */ - if (isNaN(forceVector.x) === false && isNaN(forceVector.y) === false) { - floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + forceVector.x - floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + forceVector.y - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] gravityForce -> err= ' + err.stack) } } - } - function repulsionForceBetweenFloatingObjects (currentFloatingObject) { - try { + function repulsionForceBetweenFloatingObjects(currentFloatingObject) { + try { /* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */ - const coulomb = 2 + const coulomb = 2 - let floatingObject1 = visibleFloatingObjects[currentFloatingObject] + let floatingObject1 = visibleFloatingObjects[currentFloatingObject] - for (let i = 0; i < visibleFloatingObjects.length; i++) { - // The force to be applied is considering all other floatingObjects... + for (let i = 0; i < visibleFloatingObjects.length; i++) { + // The force to be applied is considering all other floatingObjects... - if (i !== currentFloatingObject) { - // ... except for the current one. + if (i !== currentFloatingObject) { + // ... except for the current one. - let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject... + let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject... - let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ... + let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ... - let force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force. + let force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force. /* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */ - if (force > 1) { - force = 1 - } + if (force > 1) { + force = 1 + } - let pos1 = { - x: floatingObject1.container.frame.position.x, - y: floatingObject1.container.frame.position.y - } + let pos1 = { + x: floatingObject1.container.frame.position.x, + y: floatingObject1.container.frame.position.y + } - let pos2 = { - x: floatingObject2.container.frame.position.x, - y: floatingObject2.container.frame.position.y - } + let pos2 = { + x: floatingObject2.container.frame.position.x, + y: floatingObject2.container.frame.position.y + } - let posDiff = { // Next we need the vector resulting from the 2 positions. - x: pos2.x - pos1.x, - y: pos2.y - pos1.y - } + let posDiff = { // Next we need the vector resulting from the 2 positions. + x: pos2.x - pos1.x, + y: pos2.y - pos1.y + } - let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector. - x: posDiff.x / d, - y: posDiff.y / d - } + let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector. + x: posDiff.x / d, + y: posDiff.y / d + } - let forceVector = { - x: unitVector.x * force, - y: unitVector.y * force - } + let forceVector = { + x: unitVector.x * force, + y: unitVector.y * force + } /* We substract the force vector to the speed vector of the current floatingObject */ - if (isNaN(forceVector.x) === false && isNaN(forceVector.y) === false) { - floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x - floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y - } - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] repulsionForceBetweenFloatingObjects -> err= ' + err.stack) } - } - } - - function proximityBetweenFloatingObjects (currentFloatingObject) { - try { - let floatingObject1 = visibleFloatingObjects[currentFloatingObject] - floatingObject1.nearbyFloatingObjects = [] - for (let i = 0; i < visibleFloatingObjects.length; i++) { - if (i !== currentFloatingObject) { - let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject... - - let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ... - - if (floatingObject1.nearbyFloatingObjects.length === 0) { - floatingObject1.nearbyFloatingObjects.push([d, floatingObject2]) - } else { - let recordAdded = false - for (let j = 0; j < floatingObject1.nearbyFloatingObjects.length; j++) { - let recordedDistance = floatingObject1.nearbyFloatingObjects[j][0] - if (d < recordedDistance) { - floatingObject1.nearbyFloatingObjects.splice(j, 0, [d, floatingObject2]) - recordAdded = true - break - } + if (isNaN(forceVector.x) === false && isNaN(forceVector.y) === false) { + floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x + floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y + } + } } - if (recordAdded === false) { - floatingObject1.nearbyFloatingObjects.push([d, floatingObject2]) - } - } - floatingObject1.nearbyFloatingObjects.splice(10, floatingObject1.nearbyFloatingObjects.length) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] repulsionForceBetweenFloatingObjects -> err= ' + err.stack) } } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] proximityBetweenFloatingObjects -> err= ' + err.stack) } } - } - function targetRepulsionForce (currentFloatingObject) { - try { + function proximityBetweenFloatingObjects(currentFloatingObject) { + try { + let floatingObject1 = visibleFloatingObjects[currentFloatingObject] + floatingObject1.nearbyFloatingObjects = [] + for (let i = 0; i < visibleFloatingObjects.length; i++) { + if (i !== currentFloatingObject) { + let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject... + + let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ... + + if (floatingObject1.nearbyFloatingObjects.length === 0) { + floatingObject1.nearbyFloatingObjects.push([d, floatingObject2]) + } else { + let recordAdded = false + for (let j = 0; j < floatingObject1.nearbyFloatingObjects.length; j++) { + let recordedDistance = floatingObject1.nearbyFloatingObjects[j][0] + if (d < recordedDistance) { + floatingObject1.nearbyFloatingObjects.splice(j, 0, [d, floatingObject2]) + recordAdded = true + break + } + } + if (recordAdded === false) { + floatingObject1.nearbyFloatingObjects.push([d, floatingObject2]) + } + } + floatingObject1.nearbyFloatingObjects.splice(10, floatingObject1.nearbyFloatingObjects.length) + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] proximityBetweenFloatingObjects -> err= ' + err.stack) } + } + } + + function targetRepulsionForce(currentFloatingObject) { + try { /* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */ - const coulomb = 2 + const coulomb = 2 - let floatingObject1 = visibleFloatingObjects[currentFloatingObject] + let floatingObject1 = visibleFloatingObjects[currentFloatingObject] - for (let i = 0; i < visibleFloatingObjects.length; i++) { - // The force to be applied is considering all other floatingObjects... + for (let i = 0; i < visibleFloatingObjects.length; i++) { + // The force to be applied is considering all other floatingObjects... - let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject... + let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject... - let payload = { - position: undefined - } + let payload = { + position: undefined + } - switch (floatingObject2.type) { - case 'UI Object': { - payload.targetPosition = floatingObject2.payload.targetPosition - break - } - default: { - break - } - } + switch (floatingObject2.type) { + case 'UI Object': { + payload.targetPosition = floatingObject2.payload.targetPosition + break + } + default: { + break + } + } - let d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject1.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ... + let d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject1.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ... - let force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force. + let force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force. /* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */ - if (force > maxTargetRepulsionForce) { - force = maxTargetRepulsionForce + if (force > maxTargetRepulsionForce) { + force = maxTargetRepulsionForce + } + + let pos1 = { + x: floatingObject1.container.frame.position.x, + y: floatingObject1.container.frame.position.y + } + + let pos2 = { + x: payload.targetPosition.x, + y: payload.targetPosition.y + } + + let posDiff = { // Next we need the vector resulting from the 2 positions. + x: pos2.x - pos1.x, + y: pos2.y - pos1.y + } + + if (d !== 0) { + let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector. + x: posDiff.x / d, + y: posDiff.y / d + } + + let forceVector = { + x: unitVector.x * force, + y: unitVector.y * force + } + + /* We substract the force vector to the speed vector of the current floatingObject */ + + if (isNaN(forceVector.x) === false && isNaN(forceVector.y) === false) { + floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x + floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y + } + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] targetRepulsionForce -> err= ' + err.stack) } } - - let pos1 = { - x: floatingObject1.container.frame.position.x, - y: floatingObject1.container.frame.position.y - } - - let pos2 = { - x: payload.targetPosition.x, - y: payload.targetPosition.y - } - - let posDiff = { // Next we need the vector resulting from the 2 positions. - x: pos2.x - pos1.x, - y: pos2.y - pos1.y - } - - if (d !== 0) { - let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector. - x: posDiff.x / d, - y: posDiff.y / d - } - - let forceVector = { - x: unitVector.x * force, - y: unitVector.y * force - } - - /* We substract the force vector to the speed vector of the current floatingObject */ - - if (isNaN(forceVector.x) === false && isNaN(forceVector.y) === false) { - floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x - floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y - } - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] targetRepulsionForce -> err= ' + err.stack) } } - } - function colliding (floatingObject1, floatingObject2) { - try { + function colliding(floatingObject1, floatingObject2) { + try { /* This function detects weather 2 floatingObjects collide with each other. */ - let r1 = floatingObject1.container.frame.radius - let r2 = floatingObject2.container.frame.radius + let r1 = floatingObject1.container.frame.radius + let r2 = floatingObject2.container.frame.radius - let distance = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) + let distance = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) - if (distance > (r1 + r2)) { + if (distance > (r1 + r2)) { // No solutions, the circles are too far apart. - return false - } else if (distance <= r1 + r2) { + return false + } else if (distance <= r1 + r2) { // One circle contains the other. - return true - } else if ((distance === 0) && (r1 === r2)) { + return true + } else if ((distance === 0) && (r1 === r2)) { // the circles coincide. - return true - } else return true - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] colliding -> err= ' + err.stack) } + return true + } else return true + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] colliding -> err= ' + err.stack) } + } } - } - function distance (x1, y1, x2, y2) { - return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) - } + function distance(x1, y1, x2, y2) { + return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) + } - function resolveCollision (floatingObject1, floatingObject2) { - try { + function resolveCollision(floatingObject1, floatingObject2) { + try { /* This function changes speed and position of floatingObjects that are in collision */ - let collisionision_angle = Math.atan2((floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y), (floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x)) + let collisionision_angle = Math.atan2((floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y), (floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x)) - let speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 1 - let speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 2 + let speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 1 + let speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 2 - let direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x) - let direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x) + let direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x) + let direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x) - let new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle) - let new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle) - let new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle) - let new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle) + let new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle) + let new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle) + let new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle) + let new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle) - let final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass) - let final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass) - let final_yspeed_1 = new_yspeed_1 - let final_yspeed_2 = new_yspeed_2 + let final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass) + let final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass) + let final_yspeed_1 = new_yspeed_1 + let final_yspeed_2 = new_yspeed_2 - let cosAngle = Math.cos(collisionision_angle) - let sinAngle = Math.sin(collisionision_angle) + let cosAngle = Math.cos(collisionision_angle) + let sinAngle = Math.sin(collisionision_angle) - floatingObject1.currentSpeed.x = cosAngle * final_xspeed_1 - sinAngle * final_yspeed_1 - floatingObject1.currentSpeed.y = sinAngle * final_xspeed_1 + cosAngle * final_yspeed_1 + floatingObject1.currentSpeed.x = cosAngle * final_xspeed_1 - sinAngle * final_yspeed_1 + floatingObject1.currentSpeed.y = sinAngle * final_xspeed_1 + cosAngle * final_yspeed_1 - floatingObject2.currentSpeed.x = cosAngle * final_xspeed_2 - sinAngle * final_yspeed_2 - floatingObject2.currentSpeed.y = sinAngle * final_xspeed_2 + cosAngle * final_yspeed_2 + floatingObject2.currentSpeed.x = cosAngle * final_xspeed_2 - sinAngle * final_yspeed_2 + floatingObject2.currentSpeed.y = sinAngle * final_xspeed_2 + cosAngle * final_yspeed_2 - let pos1 = { - x: floatingObject1.container.frame.position.x, - y: floatingObject1.container.frame.position.y - } + let pos1 = { + x: floatingObject1.container.frame.position.x, + y: floatingObject1.container.frame.position.y + } - let pos2 = { - x: floatingObject2.container.frame.position.x, - y: floatingObject2.container.frame.position.y - } + let pos2 = { + x: floatingObject2.container.frame.position.x, + y: floatingObject2.container.frame.position.y + } // get the mtd - let posDiff = { - x: pos1.x - pos2.x, - y: pos1.y - pos2.y - } + let posDiff = { + x: pos1.x - pos2.x, + y: pos1.y - pos2.y + } - let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) + let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // minimum translation distance to push floatingObjects apart after intersecting - let scalar = (((floatingObject1.container.frame.radius + floatingObject2.container.frame.radius) - d) / d) + let scalar = (((floatingObject1.container.frame.radius + floatingObject2.container.frame.radius) - d) / d) - let minTD = { - x: posDiff.x * scalar, - y: posDiff.y * scalar - } + let minTD = { + x: posDiff.x * scalar, + y: posDiff.y * scalar + } // resolve intersection -- // computing inverse mass quantities - let im1 = 1 / floatingObject1.currentMass - let im2 = 1 / floatingObject2.currentMass + let im1 = 1 / floatingObject1.currentMass + let im2 = 1 / floatingObject2.currentMass // push-pull them apart based off their mass - pos1.x = pos1.x + minTD.x * (im1 / (im1 + im2)) - pos1.y = pos1.y + minTD.y * (im1 / (im1 + im2)) - pos2.x = pos2.x - minTD.x * (im2 / (im1 + im2)) - pos2.y = pos2.y - minTD.y * (im2 / (im1 + im2)) + pos1.x = pos1.x + minTD.x * (im1 / (im1 + im2)) + pos1.y = pos1.y + minTD.y * (im1 / (im1 + im2)) + pos2.x = pos2.x - minTD.x * (im2 / (im1 + im2)) + pos2.y = pos2.y - minTD.y * (im2 / (im1 + im2)) - if (floatingObject1.positionLocked === false && isNaN(pos1.x) === false && isNaN(pos1.y) === false) { - floatingObject1.container.frame.position = pos1 - } - if (floatingObject2.positionLocked === false && isNaN(pos2.x) === false && isNaN(pos2.y) === false) { - floatingObject2.container.frame.position = pos2 - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] resolveCollision -> err= ' + err.stack) } + if (floatingObject1.positionLocked === false && isNaN(pos1.x) === false && isNaN(pos1.y) === false) { + floatingObject1.container.frame.position = pos1 + } + if (floatingObject2.positionLocked === false && isNaN(pos2.x) === false && isNaN(pos2.y) === false) { + floatingObject2.container.frame.position = pos2 + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] resolveCollision -> err= ' + err.stack) } + } } - } } diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 12cb186f6..7d15a19f3 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -1,715 +1,715 @@ -function newFloatingObject () { - const MODULE_NAME = 'Floating Object' - const ERROR_LOG = true +function newFloatingObject() { + const MODULE_NAME = 'Floating Object' + const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - fitFunction: undefined, - container: undefined, - positionLocked: false, - isOnFocus: false, - payload: undefined, // This is a reference to an object controlled by a Plotter. The plotter can change its internal value and we will see them from here. - type: undefined, // Currently there are two types of Floating Objects: Profile Balls, and Notes. - currentSpeed: 0, // This is the current speed of the floating object. - currentMass: 0, // This is the current mass of the floating object, including its zoom applied. - friction: 0, // This is a factor that will ultimatelly desacelerate the floating object. - targetFriction: 0, - rawMass: 0, // This is the mass value without zoom. - rawRadius: 0, // This is the radius of this floating object without zoom. - targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value. - isPinned: false, - isFrozen: false, - angleToParent: undefined, - distanceToParent: undefined, - arrangementStyle: ARRANGEMENT_STYLE.CONCAVE, - isCollapsed: false, - isParentCollapsed: false, - frozenManually: false, - collapsedManually: false, - getPinStatus: getPinStatus, - getFreezeStatus: getFreezeStatus, - getCollapseStatus: getCollapseStatus, - getAngleToParent: getAngleToParent, - getDistanceToParent: getDistanceToParent, - getArrangementStyle: getArrangementStyle, - nearbyFloatingObjects: [], - setPosition: setPosition, - pinToggle: pinToggle, - freezeToggle: freezeToggle, - collapseToggle: collapseToggle, - angleToParentToggle: angleToParentToggle, - distanceToParentToggle: distanceToParentToggle, - arrangementStyleToggle: arrangementStyleToggle, - physics: physics, - invisiblePhysics: invisiblePhysics, - initializeMass: initializeMass, - initializeRadius: initializeRadius, - initializeImageSize: initializeImageSize, - initializeFontSize: initializeFontSize, - initializeHierarchyRing: initializeHierarchyRing, - initializeCurrentPosition: initializeCurrentPosition, - radomizeCurrentSpeed: radomizeCurrentSpeed, - drawBackground: drawBackground, - drawMiddleground: drawMiddleground, - drawForeground: drawForeground, - drawOnFocus: drawOnFocus, - updateMass: updateMass, // Function to update the mass when the zoom level changed. - updateRadius: updateRadius, // Function to update the radius when the zoom level changed. - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME, 'Circle') - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = true - thisObject.container.detectMouseOver = true - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let selfMouseOverEventSubscriptionId - let selfMouseClickEventSubscriptionId - let spaceMouseOverEventSubscriptionId - let spaceFocusAquiredEventSubscriptionId - let lastParentAngle - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) - canvas.floatingSpace.container.eventHandler.stopListening(spaceMouseOverEventSubscriptionId) - canvas.floatingSpace.container.eventHandler.stopListening(spaceFocusAquiredEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.fitFunction = undefined - thisObject.nearbyFloatingObjects = undefined - } - - function initialize (type, payload) { - thisObject.payload = payload - thisObject.type = type - - selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - - /* To consider that this object lost the focus, we monitor the space for 2 key events */ - spaceMouseOverEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onMouseOver', mouseOverFlotingSpace) - spaceFocusAquiredEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus) - - /* Assign a position and speed */ - - thisObject.initializeCurrentPosition(thisObject.payload.targetPosition) - thisObject.radomizeCurrentSpeed() - } - - function getContainer (point) { - if (thisObject.payload === undefined) { return } - if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { return } - if (canvas.floatingSpace.inMapMode === true) { return } - let container - - container = thisObject.payload.uiObject.getContainer(point) - if (container !== undefined) { return container } - - if (thisObject.container.frame.isThisScreenPointHere(point) === true) { - return thisObject.container - } else { - return undefined - } - } - - function getPinStatus () { - return thisObject.isPinned - } - - function pinToggle () { - if (thisObject.isPinned !== true) { - thisObject.isPinned = true - thisObject.positionLocked = true - } else { - thisObject.isPinned = false - } - return thisObject.isPinned - } - - function getFreezeStatus () { - return thisObject.isFrozen - } - - function getCollapseStatus () { - return thisObject.isCollapsed - } - - function getAngleToParent () { - return thisObject.angleToParent - } - - function getDistanceToParent () { - return thisObject.distanceToParent - } - - function getArrangementStyle () { - return thisObject.arrangementStyle - } - - function freezeToggle () { - if (thisObject.isFrozen !== true) { - thisObject.isFrozen = true - thisObject.frozenManually = true - } else { - thisObject.isFrozen = false - thisObject.frozenManually = false - } - return thisObject.isFrozen - } - - function collapseToggle () { - if (thisObject.isCollapsed !== true) { - thisObject.isCollapsed = true - thisObject.collapsedManually = true - } else { - thisObject.isCollapsed = false - thisObject.collapsedManually = false - } - return thisObject.isCollapsed - } - - function angleToParentToggle () { - switch (thisObject.angleToParent) { - case ANGLE_TO_PARENT.NOT_FIXED: - thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_360 - break - case ANGLE_TO_PARENT.RANGE_360: - thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - break - case ANGLE_TO_PARENT.RANGE_180: - thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_90 - break - case ANGLE_TO_PARENT.RANGE_90: - thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 - break - case ANGLE_TO_PARENT.RANGE_45: - thisObject.angleToParent = ANGLE_TO_PARENT.NOT_FIXED - break + let thisObject = { + fitFunction: undefined, + container: undefined, + positionLocked: false, + isOnFocus: false, + payload: undefined, // This is a reference to an object controlled by a Plotter. The plotter can change its internal value and we will see them from here. + type: undefined, // Currently there are two types of Floating Objects: Profile Balls, and Notes. + currentSpeed: 0, // This is the current speed of the floating object. + currentMass: 0, // This is the current mass of the floating object, including its zoom applied. + friction: 0, // This is a factor that will ultimatelly desacelerate the floating object. + targetFriction: 0, + rawMass: 0, // This is the mass value without zoom. + rawRadius: 0, // This is the radius of this floating object without zoom. + targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value. + isPinned: false, + isFrozen: false, + angleToParent: undefined, + distanceToParent: undefined, + arrangementStyle: ARRANGEMENT_STYLE.CONCAVE, + isCollapsed: false, + isParentCollapsed: false, + frozenManually: false, + collapsedManually: false, + getPinStatus: getPinStatus, + getFreezeStatus: getFreezeStatus, + getCollapseStatus: getCollapseStatus, + getAngleToParent: getAngleToParent, + getDistanceToParent: getDistanceToParent, + getArrangementStyle: getArrangementStyle, + nearbyFloatingObjects: [], + setPosition: setPosition, + pinToggle: pinToggle, + freezeToggle: freezeToggle, + collapseToggle: collapseToggle, + angleToParentToggle: angleToParentToggle, + distanceToParentToggle: distanceToParentToggle, + arrangementStyleToggle: arrangementStyleToggle, + physics: physics, + invisiblePhysics: invisiblePhysics, + initializeMass: initializeMass, + initializeRadius: initializeRadius, + initializeImageSize: initializeImageSize, + initializeFontSize: initializeFontSize, + initializeHierarchyRing: initializeHierarchyRing, + initializeCurrentPosition: initializeCurrentPosition, + radomizeCurrentSpeed: radomizeCurrentSpeed, + drawBackground: drawBackground, + drawMiddleground: drawMiddleground, + drawForeground: drawForeground, + drawOnFocus: drawOnFocus, + updateMass: updateMass, // Function to update the mass when the zoom level changed. + updateRadius: updateRadius, // Function to update the radius when the zoom level changed. + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - return thisObject.angleToParent - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME, 'Circle') + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = true + thisObject.container.detectMouseOver = true + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 - function distanceToParentToggle () { - switch (thisObject.distanceToParent) { - case DISTANCE_TO_PARENT.NOT_FIXED: - thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X - break - case DISTANCE_TO_PARENT.PARENT_025X: - thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X - break - case DISTANCE_TO_PARENT.PARENT_050X: - thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X - break - case DISTANCE_TO_PARENT.PARENT_100X: - thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_150X - break - case DISTANCE_TO_PARENT.PARENT_150X: - thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_200X - break - case DISTANCE_TO_PARENT.PARENT_200X: - thisObject.distanceToParent = DISTANCE_TO_PARENT.NOT_FIXED - break + let selfMouseOverEventSubscriptionId + let selfMouseClickEventSubscriptionId + let spaceMouseOverEventSubscriptionId + let spaceFocusAquiredEventSubscriptionId + let lastParentAngle + + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + canvas.floatingSpace.container.eventHandler.stopListening(spaceMouseOverEventSubscriptionId) + canvas.floatingSpace.container.eventHandler.stopListening(spaceFocusAquiredEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.fitFunction = undefined + thisObject.nearbyFloatingObjects = undefined } - return thisObject.distanceToParent - } + function initialize(type, payload) { + thisObject.payload = payload + thisObject.type = type - function arrangementStyleToggle () { - switch (thisObject.arrangementStyle) { - case ARRANGEMENT_STYLE.CONCAVE: - thisObject.arrangementStyle = ARRANGEMENT_STYLE.CONVEX - break - case ARRANGEMENT_STYLE.CONVEX: - thisObject.arrangementStyle = ARRANGEMENT_STYLE.VERTICAL_RIGHT - break - case ARRANGEMENT_STYLE.VERTICAL_RIGHT: - thisObject.arrangementStyle = ARRANGEMENT_STYLE.VERTICAL_LEFT - break - case ARRANGEMENT_STYLE.VERTICAL_LEFT: - thisObject.arrangementStyle = ARRANGEMENT_STYLE.HORIZONTAL_BOTTOM - break - case ARRANGEMENT_STYLE.HORIZONTAL_BOTTOM: - thisObject.arrangementStyle = ARRANGEMENT_STYLE.HORIZONTAL_TOP - break - case ARRANGEMENT_STYLE.HORIZONTAL_TOP: - thisObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - break + selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + + /* To consider that this object lost the focus, we monitor the space for 2 key events */ + spaceMouseOverEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onMouseOver', mouseOverFlotingSpace) + spaceFocusAquiredEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus) + + /* Assign a position and speed */ + + thisObject.initializeCurrentPosition(thisObject.payload.targetPosition) + thisObject.radomizeCurrentSpeed() } - return thisObject.arrangementStyle - } + function getContainer(point) { + if (thisObject.payload === undefined) { return } + if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { return } + if (canvas.floatingSpace.inMapMode === true) { return } + let container - function invisiblePhysics () { - if (thisObject.payload.uiObject !== undefined) { - thisObject.payload.uiObject.invisiblePhysics() - } - } + container = thisObject.payload.uiObject.getContainer(point) + if (container !== undefined) { return container } - function physics () { - frozenPhysics() - /* From here on, only if they are not too far. */ - if (canvas.floatingSpace.isItFar(thisObject.payload)) { return } - thisObjectPhysics() - if (thisObject.payload.uiObject !== undefined) { - thisObject.payload.uiObject.physics() - } - positionContraintsPhysics() - } - - function frozenPhysics () { - if (thisObject.frozenManually !== false) { return } - if (thisObject.payload === undefined) { return } - let parent = thisObject.payload.chainParent - if (parent !== undefined) { - if (parent.payload !== undefined) { - if (parent.payload.floatingObject !== undefined) { - thisObject.isFrozen = parent.payload.floatingObject.isFrozen + if (thisObject.container.frame.isThisScreenPointHere(point) === true) { + return thisObject.container + } else { + return undefined } - } } - } - function positionContraintsPhysics () { - const MAX_DISTANCE_TO_PARENT = 5000 - const MIN_DISTANCE_TO_PARENT = 100 + function getPinStatus() { + return thisObject.isPinned + } - if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) { - let parent = thisObject.payload.chainParent - if (parent === undefined) { return } - if (parent.payload === undefined) { return } - if (parent.payload.position === undefined) { return } + function pinToggle() { + if (thisObject.isPinned !== true) { + thisObject.isPinned = true + thisObject.positionLocked = true + } else { + thisObject.isPinned = false + } + return thisObject.isPinned + } - let distanceToParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ... - let parentChildren = canvas.designSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node) - let axisCount = parentChildren.childrenCount - let axisIndex = parentChildren.childIndex - let baseAngle = 0 - let angleToParentAngle + function getFreezeStatus() { + return thisObject.isFrozen + } - if (parent.payload.distance !== undefined) { + function getCollapseStatus() { + return thisObject.isCollapsed + } + + function getAngleToParent() { + return thisObject.angleToParent + } + + function getDistanceToParent() { + return thisObject.distanceToParent + } + + function getArrangementStyle() { + return thisObject.arrangementStyle + } + + function freezeToggle() { + if (thisObject.isFrozen !== true) { + thisObject.isFrozen = true + thisObject.frozenManually = true + } else { + thisObject.isFrozen = false + thisObject.frozenManually = false + } + return thisObject.isFrozen + } + + function collapseToggle() { + if (thisObject.isCollapsed !== true) { + thisObject.isCollapsed = true + thisObject.collapsedManually = true + } else { + thisObject.isCollapsed = false + thisObject.collapsedManually = false + } + return thisObject.isCollapsed + } + + function angleToParentToggle() { + switch (thisObject.angleToParent) { + case ANGLE_TO_PARENT.NOT_FIXED: + thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_360 + break + case ANGLE_TO_PARENT.RANGE_360: + thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + break + case ANGLE_TO_PARENT.RANGE_180: + thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_90 + break + case ANGLE_TO_PARENT.RANGE_90: + thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 + break + case ANGLE_TO_PARENT.RANGE_45: + thisObject.angleToParent = ANGLE_TO_PARENT.NOT_FIXED + break + } + + return thisObject.angleToParent + } + + function distanceToParentToggle() { switch (thisObject.distanceToParent) { - case DISTANCE_TO_PARENT.PARENT_025X: - distanceToParent = parent.payload.distance / 4 - break - case DISTANCE_TO_PARENT.PARENT_050X: - distanceToParent = parent.payload.distance / 2 - break - case DISTANCE_TO_PARENT.PARENT_100X: - distanceToParent = parent.payload.distance - break - case DISTANCE_TO_PARENT.PARENT_150X: - distanceToParent = parent.payload.distance * 1.5 - break - case DISTANCE_TO_PARENT.PARENT_200X: - distanceToParent = parent.payload.distance * 2 - break + case DISTANCE_TO_PARENT.NOT_FIXED: + thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X + break + case DISTANCE_TO_PARENT.PARENT_025X: + thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X + break + case DISTANCE_TO_PARENT.PARENT_050X: + thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X + break + case DISTANCE_TO_PARENT.PARENT_100X: + thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_150X + break + case DISTANCE_TO_PARENT.PARENT_150X: + thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_200X + break + case DISTANCE_TO_PARENT.PARENT_200X: + thisObject.distanceToParent = DISTANCE_TO_PARENT.NOT_FIXED + break } - } - if (distanceToParent > MAX_DISTANCE_TO_PARENT) { - distanceToParent = MAX_DISTANCE_TO_PARENT - } + return thisObject.distanceToParent + } - if (distanceToParent < MIN_DISTANCE_TO_PARENT) { - distanceToParent = MIN_DISTANCE_TO_PARENT - } - - switch (thisObject.angleToParent) { - case ANGLE_TO_PARENT.RANGE_360: - angleToParentAngle = 360 - break - case ANGLE_TO_PARENT.RANGE_180: - angleToParentAngle = 180 - break - case ANGLE_TO_PARENT.RANGE_90: - angleToParentAngle = 90 - break - case ANGLE_TO_PARENT.RANGE_45: - angleToParentAngle = 45 - break - } - - if (axisIndex === undefined) { - axisCount = 1 - axisIndex = axisCount - } - - if (parent.payload.chainParent !== undefined && parent.payload.angle !== undefined) { - axisCount++ - axisIndex++ - baseAngle = parent.payload.angle + 180 - lastParentAngle = parent.payload.angle - } else { - if (lastParentAngle !== undefined) { - axisCount++ - axisIndex++ - baseAngle = lastParentAngle + 180 + function arrangementStyleToggle() { + switch (thisObject.arrangementStyle) { + case ARRANGEMENT_STYLE.CONCAVE: + thisObject.arrangementStyle = ARRANGEMENT_STYLE.CONVEX + break + case ARRANGEMENT_STYLE.CONVEX: + thisObject.arrangementStyle = ARRANGEMENT_STYLE.VERTICAL_RIGHT + break + case ARRANGEMENT_STYLE.VERTICAL_RIGHT: + thisObject.arrangementStyle = ARRANGEMENT_STYLE.VERTICAL_LEFT + break + case ARRANGEMENT_STYLE.VERTICAL_LEFT: + thisObject.arrangementStyle = ARRANGEMENT_STYLE.HORIZONTAL_BOTTOM + break + case ARRANGEMENT_STYLE.HORIZONTAL_BOTTOM: + thisObject.arrangementStyle = ARRANGEMENT_STYLE.HORIZONTAL_TOP + break + case ARRANGEMENT_STYLE.HORIZONTAL_TOP: + thisObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + break } - } - let separatorAngle = (360 - angleToParentAngle) / 2 - let angleStep = angleToParentAngle / axisCount + return thisObject.arrangementStyle + } - thisObject.payload.angle = baseAngle + separatorAngle + (axisIndex - 1) * angleStep - if (thisObject.payload.angle >= 360) { - thisObject.payload.angle = thisObject.payload.angle - 360 - } - - thisObject.payload.distance = distanceToParent - - if (thisObject.isPinned === true) { - /* When an object is pinned, its angle to its parent needs to be calculated since it depends on where the user places the node. */ - /* - if (thisObject.payload.chainParent !== undefined) { - let x = thisObject.container.frame.position.x - thisObject.payload.chainParent.payload.floatingObject.container.frame.position.x - let y = thisObject.container.frame.position.y - thisObject.payload.chainParent.payload.floatingObject.container.frame.position.y - - thisObject.payload.angle = Math.atan(y / x) + function invisiblePhysics() { + if (thisObject.payload.uiObject !== undefined) { + thisObject.payload.uiObject.invisiblePhysics() } - */ - return - } + } - let newPosition = { - x: parent.payload.position.x, - y: parent.payload.position.y - } - - let displacement - - switch (thisObject.arrangementStyle) { - case ARRANGEMENT_STYLE.CONCAVE: { - displacement = { - x: distanceToParent * Math.cos(toRadians(thisObject.payload.angle)), - y: distanceToParent * Math.sin(toRadians(thisObject.payload.angle)) - } - - break + function physics() { + frozenPhysics() + /* From here on, only if they are not too far. */ + if (canvas.floatingSpace.isItFar(thisObject.payload)) { return } + thisObjectPhysics() + if (thisObject.payload.uiObject !== undefined) { + thisObject.payload.uiObject.physics() } - case ARRANGEMENT_STYLE.CONVEX: { - displacement = { - x: 2 * distanceToParent * Math.cos(toRadians(lastParentAngle)) + distanceToParent * Math.cos(toRadians(thisObject.payload.angle + 180)), - y: 2 * distanceToParent * Math.sin(toRadians(lastParentAngle)) + distanceToParent * Math.sin(toRadians(thisObject.payload.angle + 180)) - } - break + positionContraintsPhysics() + } + + function frozenPhysics() { + if (thisObject.frozenManually !== false) { return } + if (thisObject.payload === undefined) { return } + let parent = thisObject.payload.chainParent + if (parent !== undefined) { + if (parent.payload !== undefined) { + if (parent.payload.floatingObject !== undefined) { + thisObject.isFrozen = parent.payload.floatingObject.isFrozen + } + } } - case ARRANGEMENT_STYLE.HORIZONTAL_BOTTOM: { - displacement = { - x: distanceToParent * Math.tan(toRadians(thisObject.payload.angle)), - y: distanceToParent - } - break + } + + function positionContraintsPhysics() { + const MAX_DISTANCE_TO_PARENT = 5000 + const MIN_DISTANCE_TO_PARENT = 100 + + if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) { + let parent = thisObject.payload.chainParent + if (parent === undefined) { return } + if (parent.payload === undefined) { return } + if (parent.payload.position === undefined) { return } + + let distanceToParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ... + let parentChildren = canvas.designSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node) + let axisCount = parentChildren.childrenCount + let axisIndex = parentChildren.childIndex + let baseAngle = 0 + let angleToParentAngle + + if (parent.payload.distance !== undefined) { + switch (thisObject.distanceToParent) { + case DISTANCE_TO_PARENT.PARENT_025X: + distanceToParent = parent.payload.distance / 4 + break + case DISTANCE_TO_PARENT.PARENT_050X: + distanceToParent = parent.payload.distance / 2 + break + case DISTANCE_TO_PARENT.PARENT_100X: + distanceToParent = parent.payload.distance + break + case DISTANCE_TO_PARENT.PARENT_150X: + distanceToParent = parent.payload.distance * 1.5 + break + case DISTANCE_TO_PARENT.PARENT_200X: + distanceToParent = parent.payload.distance * 2 + break + } + } + + if (distanceToParent > MAX_DISTANCE_TO_PARENT) { + distanceToParent = MAX_DISTANCE_TO_PARENT + } + + if (distanceToParent < MIN_DISTANCE_TO_PARENT) { + distanceToParent = MIN_DISTANCE_TO_PARENT + } + + switch (thisObject.angleToParent) { + case ANGLE_TO_PARENT.RANGE_360: + angleToParentAngle = 360 + break + case ANGLE_TO_PARENT.RANGE_180: + angleToParentAngle = 180 + break + case ANGLE_TO_PARENT.RANGE_90: + angleToParentAngle = 90 + break + case ANGLE_TO_PARENT.RANGE_45: + angleToParentAngle = 45 + break + } + + if (axisIndex === undefined) { + axisCount = 1 + axisIndex = axisCount + } + + if (parent.payload.chainParent !== undefined && parent.payload.angle !== undefined) { + axisCount++ + axisIndex++ + baseAngle = parent.payload.angle + 180 + lastParentAngle = parent.payload.angle + } else { + if (lastParentAngle !== undefined) { + axisCount++ + axisIndex++ + baseAngle = lastParentAngle + 180 + } + } + + let separatorAngle = (360 - angleToParentAngle) / 2 + let angleStep = angleToParentAngle / axisCount + + thisObject.payload.angle = baseAngle + separatorAngle + (axisIndex - 1) * angleStep + if (thisObject.payload.angle >= 360) { + thisObject.payload.angle = thisObject.payload.angle - 360 + } + + thisObject.payload.distance = distanceToParent + + if (thisObject.isPinned === true) { + /* When an object is pinned, its angle to its parent needs to be calculated since it depends on where the user places the node. */ + /* + if (thisObject.payload.chainParent !== undefined) { + let x = thisObject.container.frame.position.x - thisObject.payload.chainParent.payload.floatingObject.container.frame.position.x + let y = thisObject.container.frame.position.y - thisObject.payload.chainParent.payload.floatingObject.container.frame.position.y + + thisObject.payload.angle = Math.atan(y / x) + } + */ + return + } + + let newPosition = { + x: parent.payload.position.x, + y: parent.payload.position.y + } + + let displacement + + switch (thisObject.arrangementStyle) { + case ARRANGEMENT_STYLE.CONCAVE: { + displacement = { + x: distanceToParent * Math.cos(toRadians(thisObject.payload.angle)), + y: distanceToParent * Math.sin(toRadians(thisObject.payload.angle)) + } + + break + } + case ARRANGEMENT_STYLE.CONVEX: { + displacement = { + x: 2 * distanceToParent * Math.cos(toRadians(lastParentAngle)) + distanceToParent * Math.cos(toRadians(thisObject.payload.angle + 180)), + y: 2 * distanceToParent * Math.sin(toRadians(lastParentAngle)) + distanceToParent * Math.sin(toRadians(thisObject.payload.angle + 180)) + } + break + } + case ARRANGEMENT_STYLE.HORIZONTAL_BOTTOM: { + displacement = { + x: distanceToParent * Math.tan(toRadians(thisObject.payload.angle)), + y: distanceToParent + } + break + } + case ARRANGEMENT_STYLE.HORIZONTAL_TOP: { + displacement = { + x: -distanceToParent * Math.tan(toRadians(thisObject.payload.angle)), + y: -distanceToParent + } + break + } + case ARRANGEMENT_STYLE.VERTICAL_RIGHT: { + displacement = { + x: distanceToParent, + y: distanceToParent * Math.tan(toRadians(thisObject.payload.angle)) + } + break + } + case ARRANGEMENT_STYLE.VERTICAL_LEFT: { + displacement = { + x: -distanceToParent, + y: -distanceToParent * Math.tan(toRadians(thisObject.payload.angle)) + } + break + } + } + + if (displacement.x > MAX_DISTANCE_TO_PARENT) { + displacement.x = MAX_DISTANCE_TO_PARENT + } + if (displacement.y > MAX_DISTANCE_TO_PARENT) { + displacement.y = MAX_DISTANCE_TO_PARENT + } + + newPosition.x = newPosition.x + displacement.x + newPosition.y = newPosition.y + displacement.y + + if (isNaN(newPosition.x) === false) { + thisObject.container.frame.position.x = newPosition.x + } + if (isNaN(newPosition.y) === false) { + thisObject.container.frame.position.y = newPosition.y + } } - case ARRANGEMENT_STYLE.HORIZONTAL_TOP: { - displacement = { - x: -distanceToParent * Math.tan(toRadians(thisObject.payload.angle)), - y: -distanceToParent - } - break + } + + function thisObjectPhysics() { + // The radius also have a target. + let ANIMATION_STEP = Math.abs(thisObject.targetRadius - thisObject.rawRadius) / 5 + + if (ANIMATION_STEP === 0) { ANIMATION_STEP = 10 } + + if (Math.abs(thisObject.container.frame.radius - thisObject.targetRadius) >= ANIMATION_STEP) { + if (thisObject.container.frame.radius < thisObject.targetRadius) { + thisObject.container.frame.radius = thisObject.container.frame.radius + ANIMATION_STEP + } else { + thisObject.container.frame.radius = thisObject.container.frame.radius - ANIMATION_STEP + } + + thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) } - case ARRANGEMENT_STYLE.VERTICAL_RIGHT: { - displacement = { - x: distanceToParent, - y: distanceToParent * Math.tan(toRadians(thisObject.payload.angle)) - } - break + + // The imageSize also have a target. + + if (Math.abs(thisObject.currentImageSize - thisObject.targetImageSize) >= ANIMATION_STEP) { + if (thisObject.currentImageSize < thisObject.targetImageSize) { + thisObject.currentImageSize = thisObject.currentImageSize + ANIMATION_STEP + } else { + thisObject.currentImageSize = thisObject.currentImageSize - ANIMATION_STEP + } } - case ARRANGEMENT_STYLE.VERTICAL_LEFT: { - displacement = { - x: -distanceToParent, - y: -distanceToParent * Math.tan(toRadians(thisObject.payload.angle)) - } - break + + // The fontSize also have a target. + + if (Math.abs(thisObject.currentFontSize - thisObject.targetFontSize) >= ANIMATION_STEP / 10) { + if (thisObject.currentFontSize < thisObject.targetFontSize) { + thisObject.currentFontSize = thisObject.currentFontSize + ANIMATION_STEP / 10 + } else { + thisObject.currentFontSize = thisObject.currentFontSize - ANIMATION_STEP / 10 + } } - } - if (displacement.x > MAX_DISTANCE_TO_PARENT) { - displacement.x = MAX_DISTANCE_TO_PARENT - } - if (displacement.y > MAX_DISTANCE_TO_PARENT) { - displacement.y = MAX_DISTANCE_TO_PARENT - } + if (Math.abs(thisObject.currentHierarchyRing - thisObject.targetHierarchyRing) >= ANIMATION_STEP) { + if (thisObject.currentHierarchyRing < thisObject.targetHierarchyRing) { + thisObject.currentHierarchyRing = thisObject.currentHierarchyRing + ANIMATION_STEP + } else { + thisObject.currentHierarchyRing = thisObject.currentHierarchyRing - ANIMATION_STEP + } + } - newPosition.x = newPosition.x + displacement.x - newPosition.y = newPosition.y + displacement.y + /* Floating object position in screen coordinates */ - if (isNaN(newPosition.x) === false) { - thisObject.container.frame.position.x = newPosition.x - } - if (isNaN(newPosition.y) === false) { - thisObject.container.frame.position.y = newPosition.y - } - } - } - - function thisObjectPhysics () { - // The radius also have a target. - let ANIMATION_STEP = Math.abs(thisObject.targetRadius - thisObject.rawRadius) / 5 - - if (ANIMATION_STEP === 0) { ANIMATION_STEP = 10 } - - if (Math.abs(thisObject.container.frame.radius - thisObject.targetRadius) >= ANIMATION_STEP) { - if (thisObject.container.frame.radius < thisObject.targetRadius) { - thisObject.container.frame.radius = thisObject.container.frame.radius + ANIMATION_STEP - } else { - thisObject.container.frame.radius = thisObject.container.frame.radius - ANIMATION_STEP - } - - thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) + thisObject.payload.position.x = thisObject.container.frame.position.x + thisObject.payload.position.y = thisObject.container.frame.position.y } - // The imageSize also have a target. + function onMouseOver(point) { + if (thisObject.isOnFocus === false) { + thisObject.targetRadius = thisObject.rawRadius * 6.0 + thisObject.targetImageSize = thisObject.rawImageSize * 2.0 + thisObject.targetFontSize = thisObject.rawFontSize * 2.0 + thisObject.targetHierarchyRing = thisObject.rawHierarchyRing * 8.0 - if (Math.abs(thisObject.currentImageSize - thisObject.targetImageSize) >= ANIMATION_STEP) { - if (thisObject.currentImageSize < thisObject.targetImageSize) { - thisObject.currentImageSize = thisObject.currentImageSize + ANIMATION_STEP - } else { - thisObject.currentImageSize = thisObject.currentImageSize - ANIMATION_STEP - } + thisObject.payload.uiObject.container.eventHandler.raiseEvent('onFocus', point) + + thisObject.positionLocked = true + + canvas.floatingSpace.container.eventHandler.raiseEvent('onFocusAquired', thisObject) + thisObject.isOnFocus = true + } } - // The fontSize also have a target. - - if (Math.abs(thisObject.currentFontSize - thisObject.targetFontSize) >= ANIMATION_STEP / 10) { - if (thisObject.currentFontSize < thisObject.targetFontSize) { - thisObject.currentFontSize = thisObject.currentFontSize + ANIMATION_STEP / 10 - } else { - thisObject.currentFontSize = thisObject.currentFontSize - ANIMATION_STEP / 10 - } + function mouseOverFlotingSpace(point) { + removeFocus() } - if (Math.abs(thisObject.currentHierarchyRing - thisObject.targetHierarchyRing) >= ANIMATION_STEP) { - if (thisObject.currentHierarchyRing < thisObject.targetHierarchyRing) { - thisObject.currentHierarchyRing = thisObject.currentHierarchyRing + ANIMATION_STEP - } else { - thisObject.currentHierarchyRing = thisObject.currentHierarchyRing - ANIMATION_STEP - } + function someoneAquiredFocus(floatingObject) { + if (floatingObject === undefined || floatingObject.container === undefined) { + return + } + if (thisObject.container === undefined) { + return + } + if (floatingObject.container.id !== thisObject.container.id) { + removeFocus() + } } - /* Floating object position in screen coordinates */ + function removeFocus() { + if (thisObject.payload === undefined) { return } + if (thisObject.isOnFocus === true) { + thisObject.targetRadius = thisObject.rawRadius * 1 + thisObject.targetImageSize = thisObject.rawImageSize * 1 + thisObject.targetFontSize = thisObject.rawFontSize * 1 + thisObject.targetHierarchyRing = thisObject.rawHierarchyRing * 1 - thisObject.payload.position.x = thisObject.container.frame.position.x - thisObject.payload.position.y = thisObject.container.frame.position.y - } + thisObject.payload.uiObject.container.eventHandler.raiseEvent('onNotFocus', thisObject.container) - function onMouseOver (point) { - if (thisObject.isOnFocus === false) { - thisObject.targetRadius = thisObject.rawRadius * 6.0 - thisObject.targetImageSize = thisObject.rawImageSize * 2.0 - thisObject.targetFontSize = thisObject.rawFontSize * 2.0 - thisObject.targetHierarchyRing = thisObject.rawHierarchyRing * 8.0 - - thisObject.payload.uiObject.container.eventHandler.raiseEvent('onFocus', point) - - thisObject.positionLocked = true - - canvas.floatingSpace.container.eventHandler.raiseEvent('onFocusAquired', thisObject) - thisObject.isOnFocus = true - } - } - - function mouseOverFlotingSpace (point) { - removeFocus() - } - - function someoneAquiredFocus (floatingObject) { - if (floatingObject === undefined || floatingObject.container === undefined) { - return - } - if (thisObject.container === undefined) { - return - } - if (floatingObject.container.id !== thisObject.container.id) { - removeFocus() - } - } - - function removeFocus () { - if (thisObject.payload === undefined) { return } - if (thisObject.isOnFocus === true) { - thisObject.targetRadius = thisObject.rawRadius * 1 - thisObject.targetImageSize = thisObject.rawImageSize * 1 - thisObject.targetFontSize = thisObject.rawFontSize * 1 - thisObject.targetHierarchyRing = thisObject.rawHierarchyRing * 1 - - thisObject.payload.uiObject.container.eventHandler.raiseEvent('onNotFocus', thisObject.container) - - if (thisObject.isPinned !== true) { - thisObject.positionLocked = false - } - thisObject.isOnFocus = false - } - } - - function onMouseClick (pPoint) { - let event = { - point: pPoint, - parent: thisObject - } - thisObject.payload.uiObject.container.eventHandler.raiseEvent('onMouseClick', event) - } - - function drawBackground () { - if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } - if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { - if (thisObject.payload.uiObject.isShowing !== true) { - return - } - } - thisObject.payload.uiObject.drawBackground() - } - - function drawMiddleground () { - if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } - if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { - if (thisObject.payload.uiObject.isShowing !== true) { - return - } - } - thisObject.payload.uiObject.drawMiddleground() - } - - function drawForeground () { - if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } - if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { - if (thisObject.payload.uiObject.isShowing !== true) { - return - } - } - thisObject.payload.uiObject.drawForeground() - } - - function drawOnFocus () { - thisObject.payload.uiObject.drawOnFocus() - } - - function initializeMass (suggestedValue) { - let mass = suggestedValue - if (mass < 0.1) { - mass = 0.1 + if (thisObject.isPinned !== true) { + thisObject.positionLocked = false + } + thisObject.isOnFocus = false + } } - thisObject.rawMass = mass - thisObject.currentMass = mass - } - - function initializeRadius (suggestedValue) { - let radius = suggestedValue - if (radius < 2) { - radius = 2 + function onMouseClick(pPoint) { + let event = { + point: pPoint, + parent: thisObject + } + thisObject.payload.uiObject.container.eventHandler.raiseEvent('onMouseClick', event) } - thisObject.rawRadius = radius - thisObject.targetRadius = radius - thisObject.container.frame.radius = radius / 5 - - thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) - } - - function initializeImageSize (suggestedValue) { - let size = suggestedValue - if (size < 2) { - size = 2 + function drawBackground() { + if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } + if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { + if (thisObject.payload.uiObject.isShowing !== true) { + return + } + } + thisObject.payload.uiObject.drawBackground() } - thisObject.rawImageSize = size - thisObject.targetImageSize = size - thisObject.currentImageSize = size / 3 - } - - function initializeFontSize (suggestedValue) { - let size = suggestedValue - if (size < 3) { - size = 3 + function drawMiddleground() { + if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } + if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { + if (thisObject.payload.uiObject.isShowing !== true) { + return + } + } + thisObject.payload.uiObject.drawMiddleground() } - thisObject.rawFontSize = size - thisObject.targetFontSize = size - thisObject.currentFontSize = size / 3 - } - - function initializeHierarchyRing (suggestedValue) { - let radius = suggestedValue - if (radius < 3) { - radius = 3 + function drawForeground() { + if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } + if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { + if (thisObject.payload.uiObject.isShowing !== true) { + return + } + } + thisObject.payload.uiObject.drawForeground() } - thisObject.rawHierarchyRing = radius - thisObject.targetHierarchyRing = radius - thisObject.currentHierarchyRing = radius - } - - function initializeCurrentPosition (arroundPoint) { - let position = {} - - if (thisObject.payload.position === undefined) { - position = { - x: Math.floor((Math.random() * (200) - 100)) + arroundPoint.x, - y: Math.floor((Math.random() * (200) - 100)) + arroundPoint.y - } - } else { - position = { - x: thisObject.payload.position.x, - y: thisObject.payload.position.y - } + function drawOnFocus() { + thisObject.payload.uiObject.drawOnFocus() } - setPosition(position) - } + function initializeMass(suggestedValue) { + let mass = suggestedValue + if (mass < 0.1) { + mass = 0.1 + } - function setPosition (position) { - thisObject.container.frame.position.x = position.x - thisObject.container.frame.position.y = position.y - - thisObject.payload.position = {} - thisObject.payload.position.x = position.x - thisObject.payload.position.y = position.y - } - - function radomizeCurrentSpeed () { - var initialXDirection - var randomX = Math.floor((Math.random() * 10) + 1) - if (randomX > 5) { - initialXDirection = 1 - } else { - initialXDirection = -1 + thisObject.rawMass = mass + thisObject.currentMass = mass } - var initialYDirection - var randomY = Math.floor((Math.random() * 10) + 1) - if (randomY > 5) { - initialYDirection = 1 - } else { - initialYDirection = -1 + function initializeRadius(suggestedValue) { + let radius = suggestedValue + if (radius < 2) { + radius = 2 + } + + thisObject.rawRadius = radius + thisObject.targetRadius = radius + thisObject.container.frame.radius = radius / 5 + + thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) } - var velocity = { - x: initialXDirection * Math.floor((Math.random() * 300) + 1) / 100, - y: initialYDirection * Math.floor((Math.random() * 300) + 1) / 100 + function initializeImageSize(suggestedValue) { + let size = suggestedValue + if (size < 2) { + size = 2 + } + + thisObject.rawImageSize = size + thisObject.targetImageSize = size + thisObject.currentImageSize = size / 3 } - thisObject.currentSpeed = velocity - } + function initializeFontSize(suggestedValue) { + let size = suggestedValue + if (size < 3) { + size = 3 + } - function updateMass () { + thisObject.rawFontSize = size + thisObject.targetFontSize = size + thisObject.currentFontSize = size / 3 + } - } + function initializeHierarchyRing(suggestedValue) { + let radius = suggestedValue + if (radius < 3) { + radius = 3 + } - function updateRadius () { - } + thisObject.rawHierarchyRing = radius + thisObject.targetHierarchyRing = radius + thisObject.currentHierarchyRing = radius + } + + function initializeCurrentPosition(arroundPoint) { + let position = {} + + if (thisObject.payload.position === undefined) { + position = { + x: Math.floor((Math.random() * (200) - 100)) + arroundPoint.x, + y: Math.floor((Math.random() * (200) - 100)) + arroundPoint.y + } + } else { + position = { + x: thisObject.payload.position.x, + y: thisObject.payload.position.y + } + } + + setPosition(position) + } + + function setPosition(position) { + thisObject.container.frame.position.x = position.x + thisObject.container.frame.position.y = position.y + + thisObject.payload.position = {} + thisObject.payload.position.x = position.x + thisObject.payload.position.y = position.y + } + + function radomizeCurrentSpeed() { + var initialXDirection + var randomX = Math.floor((Math.random() * 10) + 1) + if (randomX > 5) { + initialXDirection = 1 + } else { + initialXDirection = -1 + } + + var initialYDirection + var randomY = Math.floor((Math.random() * 10) + 1) + if (randomY > 5) { + initialYDirection = 1 + } else { + initialYDirection = -1 + } + + var velocity = { + x: initialXDirection * Math.floor((Math.random() * 300) + 1) / 100, + y: initialYDirection * Math.floor((Math.random() * 300) + 1) / 100 + } + + thisObject.currentSpeed = velocity + } + + function updateMass() { + + } + + function updateRadius() { + } } diff --git a/FloatingSpace/FormulaEditor.js b/FloatingSpace/FormulaEditor.js index 596f1ba27..0b3887637 100644 --- a/FloatingSpace/FormulaEditor.js +++ b/FloatingSpace/FormulaEditor.js @@ -1,199 +1,199 @@ -function newFormulaEditor () { - const MODULE_NAME = 'Formula Editor' +function newFormulaEditor() { + const MODULE_NAME = 'Formula Editor' - let thisObject = { - isVisibleFunction: undefined, - visible: false, - imagePathOK: undefined, - imagePathNOT_OK: undefined, - rawRadius: undefined, - targetRadius: undefined, - currentRadius: undefined, - container: undefined, - payload: undefined, - deactivate: deactivate, - activate: activate, - physics: physics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let isMouseOver = false - let SIZE_FACTOR = 1.2 - - return thisObject - - function finalize () { - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.isVisibleFunction = undefined - } - - function initialize () { - - } - - function deactivate () { - if (thisObject.visible === true) { - thisObject.visible = false - let textArea = document.getElementById('textArea') - textArea.style.display = 'none' - thisObject.payload.node.code = textArea.value - } - EDITOR_ON_FOCUS = false - } - - function activate (payload) { - thisObject.visible = true - thisObject.payload = payload - thisObject.rawRadius = 8 - thisObject.targetRadius = thisObject.container.frame.radius - thisObject.currentRadius = 0 - thisObject.payload.uiObject.setErrorMessage('', 0) - - let textArea = document.getElementById('textArea') - textArea.value = payload.node.code - textArea.style = 'resize: none;' + - ' border: none;' + - ' outline: none;' + - 'box-shadow: none;' + - 'overflow:hidden;' + - 'font-family: ' + UI_FONT.PRIMARY + ';' + - 'font-size: 14px;' + - 'background-color: rgb(' + UI_COLOR.MANGANESE_PURPLE + ');' + - 'color:rgb(255, 255, 255);' + - 'width: ' + thisObject.container.frame.width + 'px;' + - 'height: ' + thisObject.container.frame.height + 'px' - textArea.style.display = 'block' - textArea.focus() - EDITOR_ON_FOCUS = true - } - - function getContainer (point) { - let container - if (thisObject.visible === true) { - if (point.x === VERY_LARGE_NUMBER) { - /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that - anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is - triggered. We compensate recognizing this coordinate and returning our container. */ - return thisObject.container - } - - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - return thisObject.container - } else { - return undefined - } - } - } - - function physics () { - if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { - if (thisObject.currentRadius < thisObject.targetRadius) { - thisObject.currentRadius = thisObject.currentRadius + 0.5 - } else { - thisObject.currentRadius = thisObject.currentRadius - 0.5 - } + let thisObject = { + isVisibleFunction: undefined, + visible: false, + imagePathOK: undefined, + imagePathNOT_OK: undefined, + rawRadius: undefined, + targetRadius: undefined, + currentRadius: undefined, + container: undefined, + payload: undefined, + deactivate: deactivate, + activate: activate, + physics: physics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = false + thisObject.container.frame.radius = 0 thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR - thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR + let isMouseOver = false + let SIZE_FACTOR = 1.2 - let textAreaPosition = { - x: 0 - thisObject.container.frame.width / 2, - y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN + return thisObject + + function finalize() { + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.isVisibleFunction = undefined } - textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) - if (thisObject.visible === true) { - let checkPosition = { - x: textAreaPosition.x, - y: textAreaPosition.y - CURRENT_TOP_MARGIN - } - if (thisObject.isVisibleFunction(checkPosition) === false) { - deactivate() - } - } - if (thisObject.visible === true) { - let textAreaDiv = document.getElementById('textAreaDiv') - textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; ' - } - } + function initialize() { - function drawBackground () { - if (thisObject.visible === true) { - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - let radius = thisObject.container.frame.radius * SIZE_FACTOR - - if (radius > 0.5) { - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' - browserCanvasContext.fill() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', ' + 1 + ')' - browserCanvasContext.fill() - } - } - } - function drawForeground () { - let iconPosition = { - x: 0, - y: thisObject.currentRadius * 1.5 } - iconPosition = thisObject.container.frame.frameThisPoint(iconPosition) + function deactivate() { + if (thisObject.visible === true) { + thisObject.visible = false + let textArea = document.getElementById('textArea') + textArea.style.display = 'none' + thisObject.payload.node.code = textArea.value + } + EDITOR_ON_FOCUS = false + } - /* Menu Item */ + function activate(payload) { + thisObject.visible = true + thisObject.payload = payload + thisObject.rawRadius = 8 + thisObject.targetRadius = thisObject.container.frame.radius + thisObject.currentRadius = 0 + thisObject.payload.uiObject.setErrorMessage('', 0) - if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) { - browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + let textArea = document.getElementById('textArea') + textArea.value = payload.node.code + textArea.style = 'resize: none;' + + ' border: none;' + + ' outline: none;' + + 'box-shadow: none;' + + 'overflow:hidden;' + + 'font-family: ' + UI_FONT.PRIMARY + ';' + + 'font-size: 14px;' + + 'background-color: rgb(' + UI_COLOR.MANGANESE_PURPLE + ');' + + 'color:rgb(255, 255, 255);' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + textArea.style.display = 'block' + textArea.focus() + EDITOR_ON_FOCUS = true + } - /* Menu Label */ + function getContainer(point) { + let container + if (thisObject.visible === true) { + if (point.x === VERY_LARGE_NUMBER) { + /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that + anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is + triggered. We compensate recognizing this coordinate and returning our container. */ + return thisObject.container + } - let label = 'Code looks good!' - let labelPoint - let fontSize = 10 + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + return thisObject.container + } else { + return undefined + } + } + } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - - if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) { - labelPoint = { - x: iconPosition.x + thisObject.currentRadius + 10, - y: iconPosition.y + fontSize * FONT_ASPECT_RATIO + function physics() { + if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) { + if (thisObject.currentRadius < thisObject.targetRadius) { + thisObject.currentRadius = thisObject.currentRadius + 0.5 + } else { + thisObject.currentRadius = thisObject.currentRadius - 0.5 + } } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + + thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR + thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR + + let textAreaPosition = { + x: 0 - thisObject.container.frame.width / 2, + y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN + } + + textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) + if (thisObject.visible === true) { + let checkPosition = { + x: textAreaPosition.x, + y: textAreaPosition.y - CURRENT_TOP_MARGIN + } + if (thisObject.isVisibleFunction(checkPosition) === false) { + deactivate() + } + } + if (thisObject.visible === true) { + let textAreaDiv = document.getElementById('textAreaDiv') + textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; ' + } + } + + function drawBackground() { + if (thisObject.visible === true) { + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + let radius = thisObject.container.frame.radius * SIZE_FACTOR + + if (radius > 0.5) { + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' + browserCanvasContext.fill() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', ' + 1 + ')' + browserCanvasContext.fill() + } + } + } + function drawForeground() { + let iconPosition = { + x: 0, + y: thisObject.currentRadius * 1.5 + } + + iconPosition = thisObject.container.frame.frameThisPoint(iconPosition) + + /* Menu Item */ + + if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) { + browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2) + + /* Menu Label */ + + let label = 'Code looks good!' + let labelPoint + let fontSize = 10 + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + + if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) { + labelPoint = { + x: iconPosition.x + thisObject.currentRadius + 10, + y: iconPosition.y + fontSize * FONT_ASPECT_RATIO + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } } - } } diff --git a/FloatingSpace/Picker.js b/FloatingSpace/Picker.js index b306ac85e..4d3a25759 100644 --- a/FloatingSpace/Picker.js +++ b/FloatingSpace/Picker.js @@ -1,220 +1,220 @@ -function newPicker () { - const MODULE_NAME = 'Picker' +function newPicker() { + const MODULE_NAME = 'Picker' - let thisObject = { - container: undefined, - selectedItem: 0, - onParentChanged: onParentChanged, - getSelected: getSelected, - setSelected: setSelected, - physics: physics, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = 150 - thisObject.container.frame.height = 60 - - let isMouseOver - let optionsList - let parent - let current - let parentSelected = 0 - let propertyName - let selected = 0 - let lastSelected = 0 - let onMouseWheelEventSubscriptionId - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - optionsList = undefined - parent = undefined - current = undefined - } - - function initialize (pOptionsList, pCurrent, pParent, pPropertyName) { - optionsList = pOptionsList - current = pCurrent - parent = pParent - propertyName = pPropertyName - onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - } - - function onMouseOver (event) { - isMouseOver = true - } - - function onMouseNotOver () { - isMouseOver = false - } - - function getSelected () { - return optionsList[selected] - } - - function setSelected (pOptionsList, pCurrent, pParent, pSelected) { - if (pOptionsList !== undefined) { - optionsList = pOptionsList - } - if (pCurrent !== undefined) { - current = pCurrent - } - if (pParent !== undefined) { - parent = pParent - } - if (pSelected !== undefined) { - selected = pSelected - } - raiseEventParentChanged() - } - - function onParentChanged (event) { - if (event.parent !== undefined) { - parent = event.parent - } - parentSelected = event.selected - - selected = 0 - let parentKeys - - parentKeys = Object.keys(parent) - checkPropertyName() - - function checkPropertyName () { - if (propertyName === undefined) { - current = parent[parentKeys[parentSelected]] - checkArray() - } else { - current = parent[parentKeys[parentSelected]] - current = current[propertyName] - checkArray() - } + let thisObject = { + container: undefined, + selectedItem: 0, + onParentChanged: onParentChanged, + getSelected: getSelected, + setSelected: setSelected, + physics: physics, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - function checkArray () { - if (Array.isArray(current) === false) { - optionsList = Object.keys(current) - } else { - optionsList = current - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + thisObject.container.frame.width = 150 + thisObject.container.frame.height = 60 + + let isMouseOver + let optionsList + let parent + let current + let parentSelected = 0 + let propertyName + let selected = 0 + let lastSelected = 0 + let onMouseWheelEventSubscriptionId + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) + thisObject.container.finalize() + thisObject.container = undefined + optionsList = undefined + parent = undefined + current = undefined } - raiseEventParentChanged() - } - - function getContainer (point) { - let container - - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - return thisObject.container - } - } - - function getSelected () { - return optionsList[selected] - } - - function onMouseWheel () { - delta = event.wheelDelta - if (delta > 0) { - delta = -1 - } else { - delta = 1 + function initialize(pOptionsList, pCurrent, pParent, pPropertyName) { + optionsList = pOptionsList + current = pCurrent + parent = pParent + propertyName = pPropertyName + onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) } - selected = selected + delta - if (selected < 0) { selected = 0 } - if (selected > optionsList.length - 1) { - selected = optionsList.length - 1 + function onMouseOver(event) { + isMouseOver = true } - if (selected !== lastSelected) { - lastSelected = selected - raiseEventParentChanged() + function onMouseNotOver() { + isMouseOver = false } - } - function raiseEventParentChanged () { - let event = { - selected: selected, - parent: current, - propertyName: propertyName + function getSelected() { + return optionsList[selected] } - thisObject.container.eventHandler.raiseEvent('onParentChanged', event) - } - function physics () { - - } - - function drawBackground () { - - } - - function drawForeground () { - const FONT_SIZE = 15 - const VISIBLE_LABELS = 5 - let fontSize - let fontColor - let opacity - - for (let i = 0; i < VISIBLE_LABELS; i++) { - let index = i - 2 + selected - let label = '' - if (index >= 0 && index < optionsList.length) { - label = optionsList[index] - } - fontColor = UI_COLOR.LIGHT_GREY - switch (i) { - case 0: - fontSize = FONT_SIZE - 5 - opacity = 0.4 - break - case 1: - fontSize = FONT_SIZE - 3 - opacity = 0.5 - break - case 2: - fontSize = FONT_SIZE - 0 - fontColor = UI_COLOR.BLACK - opacity = 1 - break - case 3: - fontSize = FONT_SIZE - 3 - opacity = 0.5 - break - case 4: - fontSize = FONT_SIZE - 5 - opacity = 0.4 - break - } - - if (i === 2 || isMouseOver === true) { - drawLabel(label, 1 / 2, i / VISIBLE_LABELS, 0, 0, fontSize, thisObject.container, fontColor, undefined, undefined, opacity) - } + function setSelected(pOptionsList, pCurrent, pParent, pSelected) { + if (pOptionsList !== undefined) { + optionsList = pOptionsList + } + if (pCurrent !== undefined) { + current = pCurrent + } + if (pParent !== undefined) { + parent = pParent + } + if (pSelected !== undefined) { + selected = pSelected + } + raiseEventParentChanged() + } + + function onParentChanged(event) { + if (event.parent !== undefined) { + parent = event.parent + } + parentSelected = event.selected + + selected = 0 + let parentKeys + + parentKeys = Object.keys(parent) + checkPropertyName() + + function checkPropertyName() { + if (propertyName === undefined) { + current = parent[parentKeys[parentSelected]] + checkArray() + } else { + current = parent[parentKeys[parentSelected]] + current = current[propertyName] + checkArray() + } + } + + function checkArray() { + if (Array.isArray(current) === false) { + optionsList = Object.keys(current) + } else { + optionsList = current + } + } + + raiseEventParentChanged() + } + + function getContainer(point) { + let container + + if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { + return thisObject.container + } + } + + function getSelected() { + return optionsList[selected] + } + + function onMouseWheel() { + delta = event.wheelDelta + if (delta > 0) { + delta = -1 + } else { + delta = 1 + } + + selected = selected + delta + if (selected < 0) { selected = 0 } + if (selected > optionsList.length - 1) { + selected = optionsList.length - 1 + } + + if (selected !== lastSelected) { + lastSelected = selected + raiseEventParentChanged() + } + } + + function raiseEventParentChanged() { + let event = { + selected: selected, + parent: current, + propertyName: propertyName + } + thisObject.container.eventHandler.raiseEvent('onParentChanged', event) + } + + function physics() { + + } + + function drawBackground() { + + } + + function drawForeground() { + const FONT_SIZE = 15 + const VISIBLE_LABELS = 5 + let fontSize + let fontColor + let opacity + + for (let i = 0; i < VISIBLE_LABELS; i++) { + let index = i - 2 + selected + let label = '' + if (index >= 0 && index < optionsList.length) { + label = optionsList[index] + } + fontColor = UI_COLOR.LIGHT_GREY + switch (i) { + case 0: + fontSize = FONT_SIZE - 5 + opacity = 0.4 + break + case 1: + fontSize = FONT_SIZE - 3 + opacity = 0.5 + break + case 2: + fontSize = FONT_SIZE - 0 + fontColor = UI_COLOR.BLACK + opacity = 1 + break + case 3: + fontSize = FONT_SIZE - 3 + opacity = 0.5 + break + case 4: + fontSize = FONT_SIZE - 5 + opacity = 0.4 + break + } + + if (i === 2 || isMouseOver === true) { + drawLabel(label, 1 / 2, i / VISIBLE_LABELS, 0, 0, fontSize, thisObject.container, fontColor, undefined, undefined, opacity) + } + } } - } } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 62fdbbdec..be7190251 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1,1885 +1,1885 @@ -function newUiObject () { - const MODULE_NAME = 'UI Object' - const ERROR_LOG = true +function newUiObject() { + const MODULE_NAME = 'UI Object' + const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - fitFunction: undefined, - isVisibleFunction: undefined, - type: undefined, - menu: undefined, - isOnFocus: false, - container: undefined, - payload: undefined, - codeEditor: undefined, - configEditor: undefined, - conditionEditor: undefined, - formulaEditor: undefined, - uiObjectTitle: undefined, - circularProgressBar: undefined, - isRunning: undefined, - shortcutKey: undefined, - isShowing: undefined, - run: run, - stop: stop, - heartBeat: heartBeat, - getReadyToChainAttach: getReadyToChainAttach, - showAvailabilityToChainAttach: showAvailabilityToChainAttach, - getReadyToReferenceAttach: getReadyToReferenceAttach, - showAvailabilityToReferenceAttach: showAvailabilityToReferenceAttach, - highlight: highlight, - runningAtBackend: runningAtBackend, - setErrorMessage: setErrorMessage, - resetErrorMessage: resetErrorMessage, - setValue: setValue, - resetValue: resetValue, - setPercentage: setPercentage, - resetPercentage: resetPercentage, - setStatus: setStatus, - resetStatus: resetStatus, - physics: physics, - invisiblePhysics: invisiblePhysics, - drawBackground: drawBackground, - drawMiddleground: drawMiddleground, - drawForeground: drawForeground, - drawOnFocus: drawOnFocus, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME, 'Circle') - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = false - thisObject.container.frame.radius = 0 - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - let icon - let executingIcon - - let selfFocusEventSubscriptionId - let selfNotFocusEventSubscriptionId - let selfDisplaceEventSubscriptionId - let selfDragStartedEventSubscriptionId - let selfDragFinishedEventSubscriptionId - - let isHighlighted - let highlightCounter = 0 - - let isRunningAtBackend - let runningAtBackendCounter = 0 - - let hasError - let errorMessageCounter = 0 - - let hasValue - let valueCounter = 0 - - let hasPercentage - let percentageCounter = 0 - - let hasStatus - let statusCounter = 0 - - let previousDistanceToChainParent - let readyToChainAttachDisplayCounter = 5 - let readyToChainAttachDisplayIncrement = 0.1 - let readyToChainAttachCounter = 0 - let isReadyToChainAttach - let availableToChainAttachCounter = 0 - let isAvailableToChainAttach - let isChainAttaching = false - let chainAttachToNode - - let previousDistanceToReferenceParent - let readyToReferenceAttachDisplayCounter = 5 - let readyToReferenceAttachDisplayIncrement = 0.1 - let readyToReferenceAttachCounter = 0 - let isReadyToReferenceAttach - let availableToReferenceAttachCounter = 0 - let isAvailableToReferenceAttach - let isReferenceAttaching = false - let referenceAttachToNode - - let isDragging = false - - let errorMessage = '' - let currentValue = 0 - let currentPercentage = '' - let currentStatus = '' - let rightDragging = false - - let eventSubscriptionIdOnError - let eventSubscriptionIdOnRunning - let eventSubscriptionIdOnStopped - let lastHeartBeat - let onRunningCallBackFunction - let onRunningCallBackFunctionWasCalled = false - - let newUiObjectCounter = 25 - let referenceLineCounter = 0 - let chainLineCounter = 0 - - let eventsServerClient - - return thisObject - - function finalize () { - finalizeEventsServerClient() - - thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfNotFocusEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfDisplaceEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfDragStartedEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfDragFinishedEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.menu.finalize() - thisObject.menu = undefined - thisObject.uiObjectTitle.finalize() - thisObject.uiObjectTitle = undefined - thisObject.fitFunction = undefined - thisObject.isVisibleFunction = undefined - - if (thisObject.codeEditor !== undefined) { - thisObject.codeEditor.finalize() - thisObject.codeEditor = undefined + let thisObject = { + fitFunction: undefined, + isVisibleFunction: undefined, + type: undefined, + menu: undefined, + isOnFocus: false, + container: undefined, + payload: undefined, + codeEditor: undefined, + configEditor: undefined, + conditionEditor: undefined, + formulaEditor: undefined, + uiObjectTitle: undefined, + circularProgressBar: undefined, + isRunning: undefined, + shortcutKey: undefined, + isShowing: undefined, + run: run, + stop: stop, + heartBeat: heartBeat, + getReadyToChainAttach: getReadyToChainAttach, + showAvailabilityToChainAttach: showAvailabilityToChainAttach, + getReadyToReferenceAttach: getReadyToReferenceAttach, + showAvailabilityToReferenceAttach: showAvailabilityToReferenceAttach, + highlight: highlight, + runningAtBackend: runningAtBackend, + setErrorMessage: setErrorMessage, + resetErrorMessage: resetErrorMessage, + setValue: setValue, + resetValue: resetValue, + setPercentage: setPercentage, + resetPercentage: resetPercentage, + setStatus: setStatus, + resetStatus: resetStatus, + physics: physics, + invisiblePhysics: invisiblePhysics, + drawBackground: drawBackground, + drawMiddleground: drawMiddleground, + drawForeground: drawForeground, + drawOnFocus: drawOnFocus, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - if (thisObject.configEditor !== undefined) { - thisObject.configEditor.finalize() - thisObject.configEditor = undefined - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME, 'Circle') + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = false + thisObject.container.frame.radius = 0 + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 - if (thisObject.conditionEditor !== undefined) { - thisObject.conditionEditor.finalize() - thisObject.conditionEditor = undefined - } + let icon + let executingIcon - if (thisObject.formulaEditor !== undefined) { - thisObject.formulaEditor.finalize() - thisObject.formulaEditor = undefined - } + let selfFocusEventSubscriptionId + let selfNotFocusEventSubscriptionId + let selfDisplaceEventSubscriptionId + let selfDragStartedEventSubscriptionId + let selfDragFinishedEventSubscriptionId - icon = undefined - chainAttachToNode = undefined - referenceAttachToNode = undefined - lastHeartBeat = undefined + let isHighlighted + let highlightCounter = 0 - onRunningCallBackFunction = undefined - } + let isRunningAtBackend + let runningAtBackendCounter = 0 - function finalizeEventsServerClient () { - if (eventsServerClient !== undefined) { - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + let hasError + let errorMessageCounter = 0 - if (eventSubscriptionIdOnRunning !== undefined) { - eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') - } - if (eventSubscriptionIdOnStopped !== undefined) { - eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject') - } - if (eventSubscriptionIdOnError !== undefined) { - eventsServerClient.stopListening(key, eventSubscriptionIdOnError, 'UiObject') - } - } - } + let hasValue + let valueCounter = 0 - function initialize (payload, menuItemsInitialValues) { - thisObject.payload = payload + let hasPercentage + let percentageCounter = 0 -/* Initialize the Menu */ + let hasStatus + let statusCounter = 0 - thisObject.menu = newCircularMenu() - thisObject.menu.initialize(menuItemsInitialValues, thisObject.payload) - thisObject.menu.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) + let previousDistanceToChainParent + let readyToChainAttachDisplayCounter = 5 + let readyToChainAttachDisplayIncrement = 0.1 + let readyToChainAttachCounter = 0 + let isReadyToChainAttach + let availableToChainAttachCounter = 0 + let isAvailableToChainAttach + let isChainAttaching = false + let chainAttachToNode -/* Initialize UI Object Title */ + let previousDistanceToReferenceParent + let readyToReferenceAttachDisplayCounter = 5 + let readyToReferenceAttachDisplayIncrement = 0.1 + let readyToReferenceAttachCounter = 0 + let isReadyToReferenceAttach + let availableToReferenceAttachCounter = 0 + let isAvailableToReferenceAttach + let isReferenceAttaching = false + let referenceAttachToNode - thisObject.uiObjectTitle = newUiObjectTitle() - thisObject.uiObjectTitle.isVisibleFunction = thisObject.isVisibleFunction - thisObject.uiObjectTitle.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) - thisObject.uiObjectTitle.fitFunction = thisObject.fitFunction - thisObject.uiObjectTitle.initialize(thisObject.payload) + let isDragging = false -/* Load UI Object Image */ + let errorMessage = '' + let currentValue = 0 + let currentPercentage = '' + let currentStatus = '' + let rightDragging = false - iconPhysics() + let eventSubscriptionIdOnError + let eventSubscriptionIdOnRunning + let eventSubscriptionIdOnStopped + let lastHeartBeat + let onRunningCallBackFunction + let onRunningCallBackFunctionWasCalled = false - selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) - selfNotFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) - selfDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace) - selfDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted) - selfDragFinishedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragFinished', onDragFinished) - } + let newUiObjectCounter = 25 + let referenceLineCounter = 0 + let chainLineCounter = 0 - function getContainer (point) { - let container + let eventsServerClient - if (isDragging === false && thisObject.isOnFocus === true) { - if (thisObject.codeEditor !== undefined) { - container = thisObject.codeEditor.getContainer(point) - if (container !== undefined) { return container } - } + return thisObject - if (thisObject.configEditor !== undefined) { - container = thisObject.configEditor.getContainer(point) - if (container !== undefined) { return container } - } + function finalize() { + finalizeEventsServerClient() - if (thisObject.conditionEditor !== undefined) { - container = thisObject.conditionEditor.getContainer(point) - if (container !== undefined) { return container } - } + thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfNotFocusEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfDisplaceEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfDragStartedEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfDragFinishedEventSubscriptionId) - if (thisObject.formulaEditor !== undefined) { - container = thisObject.formulaEditor.getContainer(point) - if (container !== undefined) { return container } - } + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.menu.finalize() + thisObject.menu = undefined + thisObject.uiObjectTitle.finalize() + thisObject.uiObjectTitle = undefined + thisObject.fitFunction = undefined + thisObject.isVisibleFunction = undefined - let getitle = true - - if (thisObject.codeEditor !== undefined) { - if (thisObject.codeEditor.visible === true) { - getitle = false + if (thisObject.codeEditor !== undefined) { + thisObject.codeEditor.finalize() + thisObject.codeEditor = undefined } - } - if (thisObject.configEditor !== undefined) { - if (thisObject.configEditor.visible === true) { - getitle = false + + if (thisObject.configEditor !== undefined) { + thisObject.configEditor.finalize() + thisObject.configEditor = undefined } - } - if (thisObject.conditionEditor !== undefined) { - if (thisObject.conditionEditor.visible === true) { - getitle = false + + if (thisObject.conditionEditor !== undefined) { + thisObject.conditionEditor.finalize() + thisObject.conditionEditor = undefined } - } - if (thisObject.formulaEditor !== undefined) { - if (thisObject.formulaEditor.visible === true) { - getitle = false + + if (thisObject.formulaEditor !== undefined) { + thisObject.formulaEditor.finalize() + thisObject.formulaEditor = undefined } - } - if (getitle === true) { - container = thisObject.uiObjectTitle.getContainer(point) - if (container !== undefined) { return container } - } - - container = thisObject.menu.getContainer(point) - if (container !== undefined) { return container } - } - - if (thisObject.container.frame.isThisPointHere(point, true, true) === true) { - return thisObject.container - } else { - return undefined - } - } - - function invisiblePhysics () { - thisObject.menu.invisiblePhysics() - childrenRunningPhysics() - } - - function physics () { - thisObject.menu.physics() - thisObject.uiObjectTitle.physics() - - if (thisObject.codeEditor !== undefined) { - thisObject.codeEditor.physics() - } - - if (thisObject.configEditor !== undefined) { - thisObject.configEditor.physics() - } - - if (thisObject.conditionEditor !== undefined) { - thisObject.conditionEditor.physics() - } - - if (thisObject.formulaEditor !== undefined) { - thisObject.formulaEditor.physics() - } - - if (thisObject.payload.chainParent === undefined || thisObject.payload.chainParent.payload === undefined) { - thisObject.payload.targetPosition.x = thisObject.payload.position.x, - thisObject.payload.targetPosition.y = thisObject.payload.position.y - } else { - if (thisObject.payload.chainParent.payload.position !== undefined) { - thisObject.payload.targetPosition.x = thisObject.payload.chainParent.payload.position.x - thisObject.payload.targetPosition.y = thisObject.payload.chainParent.payload.position.y - } - } - - if (thisObject.circularProgressBar !== undefined) { - thisObject.circularProgressBar.physics() - } - - iconPhysics() - highlightPhisycs() - runningAtBackendPhisycs() - errorMessagePhisycs() - valuePhisycs() - percentagePhisycs() - statusPhisycs() - chainDetachingPhysics() - chainAttachingPhysics() - referenceDetachingPhysics() - referenceAttachingPhysics() - childrenRunningPhysics() - newObjectPhysics() - referenceLinePhysics() - chainLinePhysics() - } - - function referenceLinePhysics () { - referenceLineCounter = referenceLineCounter + 2 - if (referenceLineCounter > 500) { - referenceLineCounter = 0 - } - } - - function chainLinePhysics () { - chainLineCounter = chainLineCounter - 5 - if (chainLineCounter < 0) { - chainLineCounter = 500 - } - } - - function newObjectPhysics () { - newUiObjectCounter-- - if (newUiObjectCounter < 0) { - newUiObjectCounter = 0 - } - } - - function heartBeatPhysics () { - if (lastHeartBeat !== undefined) { - const ONE_MIN = 60000 - nowTimestamp = (new Date()).valueOf() - if (nowTimestamp - lastHeartBeat.valueOf() > ONE_MIN) { + icon = undefined + chainAttachToNode = undefined + referenceAttachToNode = undefined lastHeartBeat = undefined - thisObject.isRunning = false - valueCounter = 0 - } - } else { - thisObject.isRunning = false - } - } - function childrenRunningPhysics () { - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition.properties === undefined) { return } - let monitorChildrenRunning = false - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - if (property.monitorChildrenRunning === true) { - let children = thisObject.payload.node[property.name] - if (children === undefined) { continue } - let totalRunning = 0 - for (let j = 0; j < children.length; j++) { - let child = children[j] - if (child.payload !== undefined) { - if (child.payload.uiObject.isRunning === true) { - totalRunning++ + onRunningCallBackFunction = undefined + } + + function finalizeEventsServerClient() { + if (eventsServerClient !== undefined) { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + + if (eventSubscriptionIdOnRunning !== undefined) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') + } + if (eventSubscriptionIdOnStopped !== undefined) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject') + } + if (eventSubscriptionIdOnError !== undefined) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnError, 'UiObject') } - } } - if (totalRunning > 0) { - setValue(totalRunning + ' / ' + children.length + ' Running') - thisObject.isRunning = true - } else { - thisObject.isRunning = false - valueCounter = 0 - } - monitorChildrenRunning = true - return - } - } - if (monitorChildrenRunning === false) { - heartBeatPhysics() - } - } - - function chainAttachingPhysics () { - chainAttacchingCounters() - - if (thisObject.isOnFocus !== true) { return } - if (isDragging !== true) { return } - if (rightDragging !== true) { return } - if (thisObject.payload.chainParent !== undefined) { return } - - let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects - let compatibleTypes - - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.chainAttachesTo !== undefined) { - compatibleTypes = nodeDefinition.chainAttachesTo.compatibleTypes - } else { - return - } - } else { - return } - let foundCompatible = false - chainAttachToNode = undefined - isChainAttaching = false + function initialize(payload, menuItemsInitialValues) { + thisObject.payload = payload - for (let i = 0; i < nearbyFloatingObjects.length; i++) { - let nearby = nearbyFloatingObjects[i] - let distance = nearby[0] - let floatingObject = nearby[1] - let nearbyNode = floatingObject.payload.node - if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { - /* Discard App Schema defined objects with busy coonection ports */ - nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - let mustContinue = false - let parentNodeDefinition = getNodeDefinition(nearbyNode) - if (parentNodeDefinition !== undefined) { - if (parentNodeDefinition.properties !== undefined) { - for (let j = 0; j < parentNodeDefinition.properties.length; j++) { - let property = parentNodeDefinition.properties[j] - if (nodeDefinition.propertyNameAtParent === property.name) { - switch (property.type) { - case 'node': { - if (nearbyNode[property.name] !== undefined) { - mustContinue = true - } - } - break - case 'array': { - /* Nothing to worry about since an array can take more than one element. */ - } - break - } + /* Initialize the Menu */ + + thisObject.menu = newCircularMenu() + thisObject.menu.initialize(menuItemsInitialValues, thisObject.payload) + thisObject.menu.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) + + /* Initialize UI Object Title */ + + thisObject.uiObjectTitle = newUiObjectTitle() + thisObject.uiObjectTitle.isVisibleFunction = thisObject.isVisibleFunction + thisObject.uiObjectTitle.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) + thisObject.uiObjectTitle.fitFunction = thisObject.fitFunction + thisObject.uiObjectTitle.initialize(thisObject.payload) + + /* Load UI Object Image */ + + iconPhysics() + + selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) + selfNotFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) + selfDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace) + selfDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted) + selfDragFinishedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragFinished', onDragFinished) + } + + function getContainer(point) { + let container + + if (isDragging === false && thisObject.isOnFocus === true) { + if (thisObject.codeEditor !== undefined) { + container = thisObject.codeEditor.getContainer(point) + if (container !== undefined) { return container } + } + + if (thisObject.configEditor !== undefined) { + container = thisObject.configEditor.getContainer(point) + if (container !== undefined) { return container } + } + + if (thisObject.conditionEditor !== undefined) { + container = thisObject.conditionEditor.getContainer(point) + if (container !== undefined) { return container } + } + + if (thisObject.formulaEditor !== undefined) { + container = thisObject.formulaEditor.getContainer(point) + if (container !== undefined) { return container } + } + + let getitle = true + + if (thisObject.codeEditor !== undefined) { + if (thisObject.codeEditor.visible === true) { + getitle = false } - } } - } - if (mustContinue === true) { continue } - } - - /* Discard Phases without partent */ - if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase' && nearbyNode.payload.parentNode === undefined) { continue } - /* Control maxPhases */ - if (thisObject.payload.node.type === 'Phase') { - if (nearbyNode.maxPhases !== undefined) { - if (nearbyNode.phases.length >= nearbyNode.maxPhases) { - continue + if (thisObject.configEditor !== undefined) { + if (thisObject.configEditor.visible === true) { + getitle = false + } } - } - } - if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase') { - if (nearbyNode.payload.parentNode.maxPhases !== undefined) { - if (nearbyNode.payload.parentNode.phases.length >= nearbyNode.payload.parentNode.maxPhases) { - continue + if (thisObject.conditionEditor !== undefined) { + if (thisObject.conditionEditor.visible === true) { + getitle = false + } } - } - } - if (foundCompatible === false) { - if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { - nearbyNode.payload.uiObject.getReadyToChainAttach() - isChainAttaching = true - chainAttachToNode = nearbyNode - foundCompatible = true - } - } - nearbyNode.payload.uiObject.showAvailabilityToChainAttach() - } - } - } - - function chainAttacchingCounters () { - if (readyToChainAttachDisplayCounter > 15) { - readyToChainAttachDisplayIncrement = -0.25 - } - - if (readyToChainAttachDisplayCounter < 5) { - readyToChainAttachDisplayIncrement = 0.25 - } - - readyToChainAttachDisplayCounter = readyToChainAttachDisplayCounter + readyToChainAttachDisplayIncrement - - readyToChainAttachCounter-- - if (readyToChainAttachCounter <= 0) { - readyToChainAttachCounter = 0 - isReadyToChainAttach = false - } else { - isReadyToChainAttach = true - } - - availableToChainAttachCounter-- - if (availableToChainAttachCounter <= 0) { - availableToChainAttachCounter = 0 - isAvailableToChainAttach = false - } else { - isAvailableToChainAttach = true - } - } - - function getReadyToChainAttach () { - readyToChainAttachCounter = 10 - } - - function showAvailabilityToChainAttach () { - availableToChainAttachCounter = 10 - } - - function chainDetachingPhysics () { - if (isDragging !== true) { return } - if (thisObject.payload.floatingObject.isFrozen === true) { return } - if (rightDragging === false) { return } - - let distanceToChainParent = Math.sqrt(Math.pow(thisObject.payload.position.x - thisObject.payload.targetPosition.x, 2) + Math.pow(thisObject.payload.position.y - thisObject.payload.targetPosition.y, 2)) - let ratio = distanceToChainParent / previousDistanceToChainParent - if (previousDistanceToChainParent === 0) { - previousDistanceToChainParent = distanceToChainParent - return - } - previousDistanceToChainParent = distanceToChainParent - - if (thisObject.isOnFocus !== true) { return } - if (thisObject.payload.chainParent === undefined) { return } - if (thisObject.payload.parentNode === undefined) { return } - - let THRESHOLD = 1.15 - - if (previousDistanceToChainParent !== undefined) { - if (ratio > THRESHOLD) { - canvas.designSpace.workspace.chainDetachNode(thisObject.payload.node) - } - } - } - - function referenceAttachingPhysics () { - referenceAttacchingCounters() - - if (thisObject.isOnFocus !== true) { return } - if (isDragging !== true) { return } - if (rightDragging !== true) { return } - if (thisObject.payload.referenceParent !== undefined) { return } - - let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects - let compatibleTypes - - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.referenceAttachesTo !== undefined) { - compatibleTypes = nodeDefinition.referenceAttachesTo.compatibleTypes - } else { - return - } - } else { - return - } - - let foundCompatible = false - referenceAttachToNode = undefined - isReferenceAttaching = false - - for (let i = 0; i < nearbyFloatingObjects.length; i++) { - let nearby = nearbyFloatingObjects[i] - let distance = nearby[0] - let floatingObject = nearby[1] - let nearbyNode = floatingObject.payload.node - if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { - if (foundCompatible === false) { - if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { - nearbyNode.payload.uiObject.getReadyToReferenceAttach() - isReferenceAttaching = true - referenceAttachToNode = nearbyNode - foundCompatible = true - } - } - nearbyNode.payload.uiObject.showAvailabilityToReferenceAttach() - } - } - } - - function referenceAttacchingCounters () { - if (readyToReferenceAttachDisplayCounter > 15) { - readyToReferenceAttachDisplayIncrement = -0.25 - } - - if (readyToReferenceAttachDisplayCounter < 5) { - readyToReferenceAttachDisplayIncrement = 0.25 - } - - readyToReferenceAttachDisplayCounter = readyToReferenceAttachDisplayCounter + readyToReferenceAttachDisplayIncrement - - readyToReferenceAttachCounter-- - if (readyToReferenceAttachCounter <= 0) { - readyToReferenceAttachCounter = 0 - isReadyToReferenceAttach = false - } else { - isReadyToReferenceAttach = true - } - - availableToReferenceAttachCounter-- - if (availableToReferenceAttachCounter <= 0) { - availableToReferenceAttachCounter = 0 - isAvailableToReferenceAttach = false - } else { - isAvailableToReferenceAttach = true - } - } - - function getReadyToReferenceAttach () { - readyToReferenceAttachCounter = 10 - } - - function showAvailabilityToReferenceAttach () { - availableToReferenceAttachCounter = 10 - } - - function referenceDetachingPhysics () { - if (isDragging !== true) { return } - if (thisObject.payload.floatingObject.isFrozen === true) { return } - if (rightDragging === false) { return } - if (thisObject.payload === undefined) { return } - if (thisObject.payload.referenceParent === undefined) { return } - - let distanceToReferenceParent = Math.sqrt(Math.pow(thisObject.payload.position.x - thisObject.payload.referenceParent.payload.position.x, 2) + Math.pow(thisObject.payload.position.y - thisObject.payload.referenceParent.payload.position.y, 2)) - let ratio = distanceToReferenceParent / previousDistanceToReferenceParent - if (previousDistanceToReferenceParent === 0) { - previousDistanceToReferenceParent = distanceToReferenceParent - return - } - previousDistanceToReferenceParent = distanceToReferenceParent - - if (thisObject.isOnFocus !== true) { return } - if (thisObject.payload.referenceParent === undefined) { return } - - let THRESHOLD = 1.15 - - if (previousDistanceToReferenceParent !== undefined) { - if (ratio > THRESHOLD) { - canvas.designSpace.workspace.referenceDetachNode(thisObject.payload.node) - } - } - } - - function highlightPhisycs () { - highlightCounter-- - if (highlightCounter < 0) { - highlightCounter = 0 - isHighlighted = false - } - } - - function runningAtBackendPhisycs () { - runningAtBackendCounter-- - if (runningAtBackendCounter < 0) { - runningAtBackendCounter = 0 - isRunningAtBackend = false - } - } - - function errorMessagePhisycs () { - errorMessageCounter-- - if (errorMessageCounter < 0) { - errorMessageCounter = 0 - hasError = false - } - } - - function valuePhisycs () { - valueCounter-- - if (valueCounter < 0) { - valueCounter = 0 - hasValue = false - } - } - - function percentagePhisycs () { - percentageCounter-- - if (percentageCounter < 0) { - percentageCounter = 0 - hasPercentage = false - } - } - - function statusPhisycs () { - statusCounter-- - if (statusCounter < 0) { - statusCounter = 0 - hasStatus = false - } - } - - function highlight (counter) { - isHighlighted = true - if (counter !== undefined) { - highlightCounter = counter - } else { - highlightCounter = 30 - } - } - - function runningAtBackend () { - isRunningAtBackend = true - runningAtBackendCounter = 5 - } - - function setErrorMessage (message, duration) { - if (message !== undefined) { - errorMessage = message - hasError = true - if (duration === undefined) { duration = 1 } - errorMessageCounter = 100 * duration - } - } - - function resetErrorMessage () { - errorMessage = undefined - hasError = false - } - - function setValue (value, counter) { - if (value !== undefined) { - currentValue = value - hasValue = true - if (counter !== undefined) { - valueCounter = counter - } else { - valueCounter = 100 - } - } - } - - function resetValue () { - currentValue = undefined - hasValue = false - valueCounter = 0 - } - - function setPercentage (percentage, counter) { - if (percentage !== undefined) { - currentPercentage = percentage - hasPercentage = true - if (counter !== undefined) { - percentageCounter = counter - } else { - percentageCounter = 100 - } - } - } - - function resetPercentage () { - currentPercentage = undefined - hasPercentage = false - percentageCounter = 0 - } - - function setStatus (status, counter) { - if (status !== undefined) { - currentStatus = status - hasStatus = true - if (counter !== undefined) { - statusCounter = counter - } else { - statusCounter = 100 - } - } - } - - function resetStatus () { - currentStatus = undefined - hasStatus = false - statusCounter = 0 - } - - function heartBeat () { - lastHeartBeat = new Date() - thisObject.isRunning = true - - if (onRunningCallBackFunctionWasCalled === false) { - onRunningCallBackFunctionWasCalled = true - if (onRunningCallBackFunction !== undefined) { - onRunningCallBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - } - } - } - - function run (pEventsServerClient, callBackFunction) { - finalizeEventsServerClient() - resetErrorMessage() - resetPercentage() - resetValue() - resetStatus() - eventsServerClient = pEventsServerClient - - /* We setup the circular progress bar. */ - if (thisObject.circularProgressBar !== undefined) { - thisObject.circularProgressBar.finalize() - } - - thisObject.circularProgressBar = newCircularProgressBar() - thisObject.circularProgressBar.initialize(thisObject.payload, eventsServerClient) - thisObject.circularProgressBar.fitFunction = thisObject.fitFunction - thisObject.circularProgressBar.container = thisObject.container - - setupRunningEventListener(callBackFunction) - setupErrorEventListener(callBackFunction) - } - - function setupRunningEventListener (callBackFunction) { - /* We will wait to hear the Running event in order to confirm the execution was really started */ - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning) - - onRunningCallBackFunction = callBackFunction - - function onResponse (message) { - eventSubscriptionIdOnRunning = message.eventSubscriptionId - } - - function onRunning () { - if (thisObject.payload === undefined) { return } - - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') - - thisObject.isRunning = true - - if (callBackFunction !== undefined) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - onRunningCallBackFunctionWasCalled = true - } - } - - /* - While it is running, it can happen that it naturally stops or is stopped not from the UI but from other means. - In those cases, the stop function would never be called (from the UI). So what we will do is to call it from - here with and event, and passing our own callBackFunction. In case there is an external source stopping this, - this will produce an execution of the callback with our event, which will produce that the menu item is restored - to its default stage. - - If on the other side, it is executed from the UI, then we will be processing the Stopped event twice, which in - both cases will reset the menu item to its default state. - */ - - let event = { - type: 'Secondary Action Already Executed' - } - stop(callBackFunction, event) - } - - function setupErrorEventListener (callBackFunction) { - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError) - - function onResponse (message) { - eventSubscriptionIdOnError = message.eventSubscriptionId - } - - function onError (message) { - setErrorMessage(message.event.errorMessage, 10) - - let event = { - type: 'Secondary Action Already Executed' - } - completeStop(callBackFunction, event) - } - } - - function stop (callBackFunction, event) { - /* We will wait to the event that the execution was terminated in order to call back the menu item */ - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Stopped', undefined, 'UiObject', onResponse, onStopped) - - function onResponse (message) { - eventSubscriptionIdOnStopped = message.eventSubscriptionId - } - - function onStopped () { - completeStop(callBackFunction, event) - } - } - - function completeStop (callBackFunction, event) { - if (thisObject.payload === undefined) { return } - if (callBackFunction !== undefined) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, event) - } - - if (thisObject.circularProgressBar !== undefined) { - thisObject.circularProgressBar.finalize() - thisObject.circularProgressBar = undefined - } - thisObject.isRunning = false - hasValue = false - hasPercentage = false - hasStatus = false - lastHeartBeat = undefined - - finalizeEventsServerClient() - } - - function iconPhysics () { - icon = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition.alternativeIcons !== undefined) { - let nodeToUse = thisObject.payload.node - if (nodeDefinition.alternativeIcons === 'Use Reference Parent') { - if (thisObject.payload.node.payload.referenceParent !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent - } - } - if (nodeDefinition.alternativeIcons === 'Use Reference Grandparent') { - if (thisObject.payload.node.payload.referenceParent !== undefined) { - if (thisObject.payload.node.payload.referenceParent.payload !== undefined) { - if (thisObject.payload.node.payload.referenceParent.payload.referenceParent !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.referenceParent + if (thisObject.formulaEditor !== undefined) { + if (thisObject.formulaEditor.visible === true) { + getitle = false + } } - } - } - } - nodeDefinition = getNodeDefinition(nodeToUse) - let config = nodeToUse.config - try { - config = JSON.parse(config) - let alternativeIcon - let iconName - for (let i = 0; i < nodeDefinition.alternativeIcons.length; i++) { - alternativeIcon = nodeDefinition.alternativeIcons[i] - if (alternativeIcon.codeName === config.codeName) { - iconName = alternativeIcon.iconName - } - } - let newIcon = canvas.designSpace.iconCollection.get(iconName) - if (newIcon !== undefined) { - icon = newIcon - } - } catch (err) { - // Nothing to do if JSON is baddly formated. - } - } - executingIcon = canvas.designSpace.iconCollection.get('attractive') - } + if (getitle === true) { + container = thisObject.uiObjectTitle.getContainer(point) + if (container !== undefined) { return container } + } - function onFocus () { - thisObject.isOnFocus = true - - if (thisObject.payload !== undefined && thisObject.isOnFocus === true && thisObject.payload.referenceParent !== undefined) { - if (thisObject.payload.referenceParent.payload !== undefined) { - if (thisObject.payload.referenceParent.payload.uiObject !== undefined) { - thisObject.payload.referenceParent.payload.uiObject.isShowing = true - } - } - } - } - - function onNotFocus () { - thisObject.isOnFocus = false - if (thisObject.codeEditor !== undefined) { - thisObject.codeEditor.deactivate() - } - if (thisObject.configEditor !== undefined) { - thisObject.configEditor.deactivate() - } - if (thisObject.conditionEditor !== undefined) { - thisObject.conditionEditor.deactivate() - } - if (thisObject.formulaEditor !== undefined) { - thisObject.formulaEditor.deactivate() - } - - if (thisObject.payload !== undefined && - thisObject.isOnFocus === false && - thisObject.payload.referenceParent !== undefined && - thisObject.payload.referenceParent.payload !== undefined && - thisObject.payload.referenceParent.payload.uiObject !== undefined) { - thisObject.payload.referenceParent.payload.uiObject.isShowing = false - } - } - - function onDisplace (event) { - thisObject.uiObjectTitle.exitEditMode() - } - - function onDragStarted (event) { - thisObject.uiObjectTitle.exitEditMode() - if (thisObject.codeEditor !== undefined) { - thisObject.codeEditor.deactivate() - } - if (thisObject.configEditor !== undefined) { - thisObject.configEditor.deactivate() - } - if (thisObject.conditionEditor !== undefined) { - thisObject.conditionEditor.deactivate() - } - if (thisObject.formulaEditor !== undefined) { - thisObject.formulaEditor.deactivate() - } - isDragging = true - if (event.button === 2) { - rightDragging = true - } else { - rightDragging = false - } - - previousDistanceToReferenceParent = undefined - previousDistanceToChainParent = undefined - } - - function onDragFinished (event) { - if (isChainAttaching === true) { - canvas.designSpace.workspace.chainAttachNode(thisObject.payload.node, chainAttachToNode) - chainAttachToNode = undefined - isChainAttaching = false - } - if (isReferenceAttaching === true) { - canvas.designSpace.workspace.referenceAttachNode(thisObject.payload.node, referenceAttachToNode) - referenceAttachToNode = undefined - isReferenceAttaching = false - } - isDragging = false - } - - function drawBackground () { - if (thisObject.isOnFocus === false) { - drawReferenceLine() - drawChainLine() - - if (isDragging === false && thisObject.isOnFocus === true) { - thisObject.menu.drawBackground() - } - } - - if (thisObject.circularProgressBar !== undefined) { - thisObject.circularProgressBar.drawBackground() - } - } - - function drawMiddleground () { - if (thisObject.isOnFocus === false) { - drawValue() - drawPercentage() - drawStatus() - drawText() - thisObject.uiObjectTitle.draw() - } - } - - function drawForeground () { - if (thisObject.isOnFocus === false) { - drawBodyAndPicture() - if (isDragging === false) { - thisObject.menu.drawForeground() - } - } - - if (thisObject.circularProgressBar !== undefined) { - thisObject.circularProgressBar.drawForeground() - } - } - - function drawOnFocus () { - if (thisObject.isOnFocus === true) { - drawReferenceLine() - drawChainLine() - - if (thisObject.codeEditor !== undefined) { - thisObject.codeEditor.drawBackground() - thisObject.codeEditor.drawForeground() - } - if (thisObject.configEditor !== undefined) { - thisObject.configEditor.drawBackground() - thisObject.configEditor.drawForeground() - } - if (thisObject.conditionEditor !== undefined) { - thisObject.conditionEditor.drawBackground() - thisObject.conditionEditor.drawForeground() - } - if (thisObject.formulaEditor !== undefined) { - thisObject.formulaEditor.drawBackground() - thisObject.formulaEditor.drawForeground() - } - - let drawMenu = true - let drawTitle = true - - if (thisObject.codeEditor !== undefined) { - if (thisObject.codeEditor.visible === true) { - drawMenu = false - drawTitle = false - } - } - if (thisObject.configEditor !== undefined) { - if (thisObject.configEditor.visible === true) { - drawMenu = false - drawTitle = false - } - } - if (thisObject.conditionEditor !== undefined) { - if (thisObject.conditionEditor.visible === true) { - drawMenu = false - drawTitle = false - } - } - if (thisObject.formulaEditor !== undefined) { - if (thisObject.formulaEditor.visible === true) { - drawMenu = false - drawTitle = false - } - } - - if (drawMenu === true) { - drawBodyAndPicture() - if (isDragging === false) { - thisObject.menu.drawBackground() - thisObject.menu.drawForeground() - } - } - - drawErrorMessage() - drawValue() - drawPercentage() - drawStatus() - drawText() - - if (drawTitle === true) { - thisObject.uiObjectTitle.draw() - } - } - } - - function drawChainLine () { - if (canvas.floatingSpace.drawChainLines === false) { return } - if (thisObject.payload.chainParent === undefined) { return } - - let targetPoint = { - x: thisObject.payload.chainParent.payload.floatingObject.container.frame.position.x, - y: thisObject.payload.chainParent.payload.floatingObject.container.frame.position.y - } - - let position = { - x: 0, - y: 0 - } - - targetPoint = canvas.floatingSpace.container.frame.frameThisPoint(targetPoint) - position = thisObject.container.frame.frameThisPoint(position) - - if (canvas.floatingSpace.inMapMode === true) { - targetPoint = canvas.floatingSpace.transformPointToMap(targetPoint) - position = canvas.floatingSpace.transformPointToMap(position) - } - - if (thisObject.container.frame.radius > 1) { - let LINE_STYLE = UI_COLOR.TITANIUM_YELLOW - if (thisObject.payload.floatingObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED) { - LINE_STYLE = UI_COLOR.GOLDEN_ORANGE - } - if (thisObject.payload.floatingObject.isFrozen === true) { - LINE_STYLE = UI_COLOR.TURQUOISE - } - if (newUiObjectCounter > 0) { - LINE_STYLE = UI_COLOR.GREY - } - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(position.x, position.y) - browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) - browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' - browserCanvasContext.setLineDash([0, chainLineCounter, 2, 3, 0, 500 - chainLineCounter]) - browserCanvasContext.lineWidth = 2 - browserCanvasContext.stroke() - browserCanvasContext.setLineDash([0, 0]) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(position.x, position.y) - browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) - browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' - browserCanvasContext.setLineDash([3, 47]) - browserCanvasContext.lineWidth = 3 - browserCanvasContext.stroke() - browserCanvasContext.setLineDash([0, 0]) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(position.x, position.y) - browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) - browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' - browserCanvasContext.setLineDash([1, 9]) - browserCanvasContext.lineWidth = 1 - browserCanvasContext.stroke() - browserCanvasContext.setLineDash([0, 0]) - } - - if (thisObject.container.frame.radius > 0.5) { - let radius = 1 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(targetPoint.x, targetPoint.y, radius, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fill() - } - } - - function drawReferenceLine () { - if (canvas.floatingSpace.drawReferenceLines === false && thisObject.isOnFocus === false) { return } - if (thisObject.payload.referenceParent === undefined) { return } - if (thisObject.payload.referenceParent.payload === undefined) { return } - if (thisObject.payload.referenceParent.payload.floatingObject === undefined) { return } - if (thisObject.payload.referenceParent.payload.floatingObject.isParentCollapsed === true && thisObject.isOnFocus === false) { return } - - let targetPoint = { - x: thisObject.payload.referenceParent.payload.position.x, - y: thisObject.payload.referenceParent.payload.position.y - } - - let position = { - x: 0, - y: 0 - } - - targetPoint = canvas.floatingSpace.container.frame.frameThisPoint(targetPoint) - position = thisObject.container.frame.frameThisPoint(position) - - if (thisObject.isOnFocus === true) { - targetPoint = thisObject.fitFunction(targetPoint) - } - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - targetPoint = canvas.floatingSpace.transformPointToMap(targetPoint) - } - - let LINE_STYLE = UI_COLOR.GREY - - if (thisObject.container.frame.radius > 1) { - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(position.x, position.y) - browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) - browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' - browserCanvasContext.setLineDash([1, 9]) - browserCanvasContext.lineWidth = 0.75 - browserCanvasContext.stroke() - browserCanvasContext.setLineDash([0, 0]) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(position.x, position.y) - browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) - browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' - browserCanvasContext.setLineDash([0, referenceLineCounter, 1, 9, 2, 8, 3, 7, 4, 6, 0, 500 - referenceLineCounter]) - browserCanvasContext.lineWidth = 4 - browserCanvasContext.stroke() - browserCanvasContext.setLineDash([0, 0]) - } - - if (thisObject.container.frame.radius > 0.5) { - let radius = 1 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(targetPoint.x, targetPoint.y, radius, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fill() - } - } - - function isEditorVisible () { - if (thisObject.codeEditor !== undefined) { - if (thisObject.codeEditor.visible === true) { return true } - } - - if (thisObject.configEditor !== undefined) { - if (thisObject.configEditor.visible === true) { return true } - } - - if (thisObject.conditionEditor !== undefined) { - if (thisObject.conditionEditor.visible === true) { return true } - } - - if (thisObject.formulaEditor !== undefined) { - if (thisObject.formulaEditor.visible === true) { return true } - } - } - - function drawText () { - if (isEditorVisible() === true) { return } -/* Text Follows */ - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - } - - let radius = thisObject.container.frame.radius - /* Label Text */ - let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize - let label - - if (radius > 6) { - const MAX_LABEL_LENGTH = 30 - - label = thisObject.payload.subTitle - label = addIndexNumber(label) - - if (label !== undefined) { - if (label.length > MAX_LABEL_LENGTH) { - label = label.substring(0, MAX_LABEL_LENGTH) + '...' + container = thisObject.menu.getContainer(point) + if (container !== undefined) { return container } } - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 4 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + if (thisObject.container.frame.isThisPointHere(point, true, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function invisiblePhysics() { + thisObject.menu.invisiblePhysics() + childrenRunningPhysics() + } + + function physics() { + thisObject.menu.physics() + thisObject.uiObjectTitle.physics() + + if (thisObject.codeEditor !== undefined) { + thisObject.codeEditor.physics() + } + + if (thisObject.configEditor !== undefined) { + thisObject.configEditor.physics() + } + + if (thisObject.conditionEditor !== undefined) { + thisObject.conditionEditor.physics() + } + + if (thisObject.formulaEditor !== undefined) { + thisObject.formulaEditor.physics() + } + + if (thisObject.payload.chainParent === undefined || thisObject.payload.chainParent.payload === undefined) { + thisObject.payload.targetPosition.x = thisObject.payload.position.x, + thisObject.payload.targetPosition.y = thisObject.payload.position.y + } else { + if (thisObject.payload.chainParent.payload.position !== undefined) { + thisObject.payload.targetPosition.x = thisObject.payload.chainParent.payload.position.x + thisObject.payload.targetPosition.y = thisObject.payload.chainParent.payload.position.y + } + } + + if (thisObject.circularProgressBar !== undefined) { + thisObject.circularProgressBar.physics() + } + + iconPhysics() + highlightPhisycs() + runningAtBackendPhisycs() + errorMessagePhisycs() + valuePhisycs() + percentagePhisycs() + statusPhisycs() + chainDetachingPhysics() + chainAttachingPhysics() + referenceDetachingPhysics() + referenceAttachingPhysics() + childrenRunningPhysics() + newObjectPhysics() + referenceLinePhysics() + chainLinePhysics() + } + + function referenceLinePhysics() { + referenceLineCounter = referenceLineCounter + 2 + if (referenceLineCounter > 500) { + referenceLineCounter = 0 + } + } + + function chainLinePhysics() { + chainLineCounter = chainLineCounter - 5 + if (chainLineCounter < 0) { + chainLineCounter = 500 + } + } + + function newObjectPhysics() { + newUiObjectCounter-- + if (newUiObjectCounter < 0) { + newUiObjectCounter = 0 + } + } + + function heartBeatPhysics() { + if (lastHeartBeat !== undefined) { + const ONE_MIN = 60000 + nowTimestamp = (new Date()).valueOf() + if (nowTimestamp - lastHeartBeat.valueOf() > ONE_MIN) { + lastHeartBeat = undefined + thisObject.isRunning = false + valueCounter = 0 + } + } else { + thisObject.isRunning = false + } + } + + function childrenRunningPhysics() { + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition.properties === undefined) { return } + let monitorChildrenRunning = false + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + if (property.monitorChildrenRunning === true) { + let children = thisObject.payload.node[property.name] + if (children === undefined) { continue } + let totalRunning = 0 + for (let j = 0; j < children.length; j++) { + let child = children[j] + if (child.payload !== undefined) { + if (child.payload.uiObject.isRunning === true) { + totalRunning++ + } + } + } + if (totalRunning > 0) { + setValue(totalRunning + ' / ' + children.length + ' Running') + thisObject.isRunning = true + } else { + thisObject.isRunning = false + valueCounter = 0 + } + monitorChildrenRunning = true + return + } + } + if (monitorChildrenRunning === false) { + heartBeatPhysics() + } + } + + function chainAttachingPhysics() { + chainAttacchingCounters() + + if (thisObject.isOnFocus !== true) { return } + if (isDragging !== true) { return } + if (rightDragging !== true) { return } + if (thisObject.payload.chainParent !== undefined) { return } + + let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects + let compatibleTypes + + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.chainAttachesTo !== undefined) { + compatibleTypes = nodeDefinition.chainAttachesTo.compatibleTypes + } else { + return + } + } else { + return + } + + let foundCompatible = false + chainAttachToNode = undefined + isChainAttaching = false + + for (let i = 0; i < nearbyFloatingObjects.length; i++) { + let nearby = nearbyFloatingObjects[i] + let distance = nearby[0] + let floatingObject = nearby[1] + let nearbyNode = floatingObject.payload.node + if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { + /* Discard App Schema defined objects with busy coonection ports */ + nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + let mustContinue = false + let parentNodeDefinition = getNodeDefinition(nearbyNode) + if (parentNodeDefinition !== undefined) { + if (parentNodeDefinition.properties !== undefined) { + for (let j = 0; j < parentNodeDefinition.properties.length; j++) { + let property = parentNodeDefinition.properties[j] + if (nodeDefinition.propertyNameAtParent === property.name) { + switch (property.type) { + case 'node': { + if (nearbyNode[property.name] !== undefined) { + mustContinue = true + } + } + break + case 'array': { + /* Nothing to worry about since an array can take more than one element. */ + } + break + } + } + } + } + } + if (mustContinue === true) { continue } + } + + /* Discard Phases without partent */ + if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase' && nearbyNode.payload.parentNode === undefined) { continue } + /* Control maxPhases */ + if (thisObject.payload.node.type === 'Phase') { + if (nearbyNode.maxPhases !== undefined) { + if (nearbyNode.phases.length >= nearbyNode.maxPhases) { + continue + } + } + } + if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase') { + if (nearbyNode.payload.parentNode.maxPhases !== undefined) { + if (nearbyNode.payload.parentNode.phases.length >= nearbyNode.payload.parentNode.maxPhases) { + continue + } + } + } + if (foundCompatible === false) { + if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { + nearbyNode.payload.uiObject.getReadyToChainAttach() + isChainAttaching = true + chainAttachToNode = nearbyNode + foundCompatible = true + } + } + nearbyNode.payload.uiObject.showAvailabilityToChainAttach() + } + } + } + + function chainAttacchingCounters() { + if (readyToChainAttachDisplayCounter > 15) { + readyToChainAttachDisplayIncrement = -0.25 + } + + if (readyToChainAttachDisplayCounter < 5) { + readyToChainAttachDisplayIncrement = 0.25 + } + + readyToChainAttachDisplayCounter = readyToChainAttachDisplayCounter + readyToChainAttachDisplayIncrement + + readyToChainAttachCounter-- + if (readyToChainAttachCounter <= 0) { + readyToChainAttachCounter = 0 + isReadyToChainAttach = false + } else { + isReadyToChainAttach = true + } + + availableToChainAttachCounter-- + if (availableToChainAttachCounter <= 0) { + availableToChainAttachCounter = 0 + isAvailableToChainAttach = false + } else { + isAvailableToChainAttach = true + } + } + + function getReadyToChainAttach() { + readyToChainAttachCounter = 10 + } + + function showAvailabilityToChainAttach() { + availableToChainAttachCounter = 10 + } + + function chainDetachingPhysics() { + if (isDragging !== true) { return } + if (thisObject.payload.floatingObject.isFrozen === true) { return } + if (rightDragging === false) { return } + + let distanceToChainParent = Math.sqrt(Math.pow(thisObject.payload.position.x - thisObject.payload.targetPosition.x, 2) + Math.pow(thisObject.payload.position.y - thisObject.payload.targetPosition.y, 2)) + let ratio = distanceToChainParent / previousDistanceToChainParent + if (previousDistanceToChainParent === 0) { + previousDistanceToChainParent = distanceToChainParent + return + } + previousDistanceToChainParent = distanceToChainParent + + if (thisObject.isOnFocus !== true) { return } + if (thisObject.payload.chainParent === undefined) { return } + if (thisObject.payload.parentNode === undefined) { return } + + let THRESHOLD = 1.15 + + if (previousDistanceToChainParent !== undefined) { + if (ratio > THRESHOLD) { + canvas.designSpace.workspace.chainDetachNode(thisObject.payload.node) + } + } + } + + function referenceAttachingPhysics() { + referenceAttacchingCounters() + + if (thisObject.isOnFocus !== true) { return } + if (isDragging !== true) { return } + if (rightDragging !== true) { return } + if (thisObject.payload.referenceParent !== undefined) { return } + + let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects + let compatibleTypes + + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.referenceAttachesTo !== undefined) { + compatibleTypes = nodeDefinition.referenceAttachesTo.compatibleTypes + } else { + return + } + } else { + return + } + + let foundCompatible = false + referenceAttachToNode = undefined + isReferenceAttaching = false + + for (let i = 0; i < nearbyFloatingObjects.length; i++) { + let nearby = nearbyFloatingObjects[i] + let distance = nearby[0] + let floatingObject = nearby[1] + let nearbyNode = floatingObject.payload.node + if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { + if (foundCompatible === false) { + if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { + nearbyNode.payload.uiObject.getReadyToReferenceAttach() + isReferenceAttaching = true + referenceAttachToNode = nearbyNode + foundCompatible = true + } + } + nearbyNode.payload.uiObject.showAvailabilityToReferenceAttach() + } + } + } + + function referenceAttacchingCounters() { + if (readyToReferenceAttachDisplayCounter > 15) { + readyToReferenceAttachDisplayIncrement = -0.25 + } + + if (readyToReferenceAttachDisplayCounter < 5) { + readyToReferenceAttachDisplayIncrement = 0.25 + } + + readyToReferenceAttachDisplayCounter = readyToReferenceAttachDisplayCounter + readyToReferenceAttachDisplayIncrement + + readyToReferenceAttachCounter-- + if (readyToReferenceAttachCounter <= 0) { + readyToReferenceAttachCounter = 0 + isReadyToReferenceAttach = false + } else { + isReadyToReferenceAttach = true + } + + availableToReferenceAttachCounter-- + if (availableToReferenceAttachCounter <= 0) { + availableToReferenceAttachCounter = 0 + isAvailableToReferenceAttach = false + } else { + isAvailableToReferenceAttach = true + } + } + + function getReadyToReferenceAttach() { + readyToReferenceAttachCounter = 10 + } + + function showAvailabilityToReferenceAttach() { + availableToReferenceAttachCounter = 10 + } + + function referenceDetachingPhysics() { + if (isDragging !== true) { return } + if (thisObject.payload.floatingObject.isFrozen === true) { return } + if (rightDragging === false) { return } + if (thisObject.payload === undefined) { return } + if (thisObject.payload.referenceParent === undefined) { return } + + let distanceToReferenceParent = Math.sqrt(Math.pow(thisObject.payload.position.x - thisObject.payload.referenceParent.payload.position.x, 2) + Math.pow(thisObject.payload.position.y - thisObject.payload.referenceParent.payload.position.y, 2)) + let ratio = distanceToReferenceParent / previousDistanceToReferenceParent + if (previousDistanceToReferenceParent === 0) { + previousDistanceToReferenceParent = distanceToReferenceParent + return + } + previousDistanceToReferenceParent = distanceToReferenceParent + + if (thisObject.isOnFocus !== true) { return } + if (thisObject.payload.referenceParent === undefined) { return } + + let THRESHOLD = 1.15 + + if (previousDistanceToReferenceParent !== undefined) { + if (ratio > THRESHOLD) { + canvas.designSpace.workspace.referenceDetachNode(thisObject.payload.node) + } + } + } + + function highlightPhisycs() { + highlightCounter-- + if (highlightCounter < 0) { + highlightCounter = 0 + isHighlighted = false + } + } + + function runningAtBackendPhisycs() { + runningAtBackendCounter-- + if (runningAtBackendCounter < 0) { + runningAtBackendCounter = 0 + isRunningAtBackend = false + } + } + + function errorMessagePhisycs() { + errorMessageCounter-- + if (errorMessageCounter < 0) { + errorMessageCounter = 0 + hasError = false + } + } + + function valuePhisycs() { + valueCounter-- + if (valueCounter < 0) { + valueCounter = 0 + hasValue = false + } + } + + function percentagePhisycs() { + percentageCounter-- + if (percentageCounter < 0) { + percentageCounter = 0 + hasPercentage = false + } + } + + function statusPhisycs() { + statusCounter-- + if (statusCounter < 0) { + statusCounter = 0 + hasStatus = false + } + } + + function highlight(counter) { + isHighlighted = true + if (counter !== undefined) { + highlightCounter = counter + } else { + highlightCounter = 30 + } + } + + function runningAtBackend() { + isRunningAtBackend = true + runningAtBackendCounter = 5 + } + + function setErrorMessage(message, duration) { + if (message !== undefined) { + errorMessage = message + hasError = true + if (duration === undefined) { duration = 1 } + errorMessageCounter = 100 * duration + } + } + + function resetErrorMessage() { + errorMessage = undefined + hasError = false + } + + function setValue(value, counter) { + if (value !== undefined) { + currentValue = value + hasValue = true + if (counter !== undefined) { + valueCounter = counter + } else { + valueCounter = 100 + } + } + } + + function resetValue() { + currentValue = undefined + hasValue = false + valueCounter = 0 + } + + function setPercentage(percentage, counter) { + if (percentage !== undefined) { + currentPercentage = percentage + hasPercentage = true + if (counter !== undefined) { + percentageCounter = counter + } else { + percentageCounter = 100 + } + } + } + + function resetPercentage() { + currentPercentage = undefined + hasPercentage = false + percentageCounter = 0 + } + + function setStatus(status, counter) { + if (status !== undefined) { + currentStatus = status + hasStatus = true + if (counter !== undefined) { + statusCounter = counter + } else { + statusCounter = 100 + } + } + } + + function resetStatus() { + currentStatus = undefined + hasStatus = false + statusCounter = 0 + } + + function heartBeat() { + lastHeartBeat = new Date() + thisObject.isRunning = true + + if (onRunningCallBackFunctionWasCalled === false) { + onRunningCallBackFunctionWasCalled = true + if (onRunningCallBackFunction !== undefined) { + onRunningCallBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + } + } + } + + function run(pEventsServerClient, callBackFunction) { + finalizeEventsServerClient() + resetErrorMessage() + resetPercentage() + resetValue() + resetStatus() + eventsServerClient = pEventsServerClient + + /* We setup the circular progress bar. */ + if (thisObject.circularProgressBar !== undefined) { + thisObject.circularProgressBar.finalize() + } + + thisObject.circularProgressBar = newCircularProgressBar() + thisObject.circularProgressBar.initialize(thisObject.payload, eventsServerClient) + thisObject.circularProgressBar.fitFunction = thisObject.fitFunction + thisObject.circularProgressBar.container = thisObject.container + + setupRunningEventListener(callBackFunction) + setupErrorEventListener(callBackFunction) + } + + function setupRunningEventListener(callBackFunction) { + /* We will wait to hear the Running event in order to confirm the execution was really started */ + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning) + + onRunningCallBackFunction = callBackFunction + + function onResponse(message) { + eventSubscriptionIdOnRunning = message.eventSubscriptionId + } + + function onRunning() { + if (thisObject.payload === undefined) { return } + + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') + + thisObject.isRunning = true + + if (callBackFunction !== undefined) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + onRunningCallBackFunctionWasCalled = true + } + } + + /* + While it is running, it can happen that it naturally stops or is stopped not from the UI but from other means. + In those cases, the stop function would never be called (from the UI). So what we will do is to call it from + here with and event, and passing our own callBackFunction. In case there is an external source stopping this, + this will produce an execution of the callback with our event, which will produce that the menu item is restored + to its default stage. + + If on the other side, it is executed from the UI, then we will be processing the Stopped event twice, which in + both cases will reset the menu item to its default state. + */ + + let event = { + type: 'Secondary Action Already Executed' + } + stop(callBackFunction, event) + } + + function setupErrorEventListener(callBackFunction) { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError) + + function onResponse(message) { + eventSubscriptionIdOnError = message.eventSubscriptionId + } + + function onError(message) { + setErrorMessage(message.event.errorMessage, 10) + + let event = { + type: 'Secondary Action Already Executed' + } + completeStop(callBackFunction, event) + } + } + + function stop(callBackFunction, event) { + /* We will wait to the event that the execution was terminated in order to call back the menu item */ + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Stopped', undefined, 'UiObject', onResponse, onStopped) + + function onResponse(message) { + eventSubscriptionIdOnStopped = message.eventSubscriptionId + } + + function onStopped() { + completeStop(callBackFunction, event) + } + } + + function completeStop(callBackFunction, event) { + if (thisObject.payload === undefined) { return } + if (callBackFunction !== undefined) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, event) + } + + if (thisObject.circularProgressBar !== undefined) { + thisObject.circularProgressBar.finalize() + thisObject.circularProgressBar = undefined + } + thisObject.isRunning = false + hasValue = false + hasPercentage = false + hasStatus = false + lastHeartBeat = undefined + + finalizeEventsServerClient() + } + + function iconPhysics() { + icon = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition.alternativeIcons !== undefined) { + let nodeToUse = thisObject.payload.node + if (nodeDefinition.alternativeIcons === 'Use Reference Parent') { + if (thisObject.payload.node.payload.referenceParent !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent + } + } + if (nodeDefinition.alternativeIcons === 'Use Reference Grandparent') { + if (thisObject.payload.node.payload.referenceParent !== undefined) { + if (thisObject.payload.node.payload.referenceParent.payload !== undefined) { + if (thisObject.payload.node.payload.referenceParent.payload.referenceParent !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.referenceParent + } + } + } + } + nodeDefinition = getNodeDefinition(nodeToUse) + let config = nodeToUse.config + try { + config = JSON.parse(config) + let alternativeIcon + let iconName + for (let i = 0; i < nodeDefinition.alternativeIcons.length; i++) { + alternativeIcon = nodeDefinition.alternativeIcons[i] + if (alternativeIcon.codeName === config.codeName) { + iconName = alternativeIcon.iconName + } + } + let newIcon = canvas.designSpace.iconCollection.get(iconName) + if (newIcon !== undefined) { + icon = newIcon + } + } catch (err) { + // Nothing to do if JSON is baddly formated. + } + } + + executingIcon = canvas.designSpace.iconCollection.get('attractive') + } + + function onFocus() { + thisObject.isOnFocus = true + + if (thisObject.payload !== undefined && thisObject.isOnFocus === true && thisObject.payload.referenceParent !== undefined) { + if (thisObject.payload.referenceParent.payload !== undefined) { + if (thisObject.payload.referenceParent.payload.uiObject !== undefined) { + thisObject.payload.referenceParent.payload.uiObject.isShowing = true + } + } + } + } + + function onNotFocus() { + thisObject.isOnFocus = false + if (thisObject.codeEditor !== undefined) { + thisObject.codeEditor.deactivate() + } + if (thisObject.configEditor !== undefined) { + thisObject.configEditor.deactivate() + } + if (thisObject.conditionEditor !== undefined) { + thisObject.conditionEditor.deactivate() + } + if (thisObject.formulaEditor !== undefined) { + thisObject.formulaEditor.deactivate() + } + + if (thisObject.payload !== undefined && + thisObject.isOnFocus === false && + thisObject.payload.referenceParent !== undefined && + thisObject.payload.referenceParent.payload !== undefined && + thisObject.payload.referenceParent.payload.uiObject !== undefined) { + thisObject.payload.referenceParent.payload.uiObject.isShowing = false + } + } + + function onDisplace(event) { + thisObject.uiObjectTitle.exitEditMode() + } + + function onDragStarted(event) { + thisObject.uiObjectTitle.exitEditMode() + if (thisObject.codeEditor !== undefined) { + thisObject.codeEditor.deactivate() + } + if (thisObject.configEditor !== undefined) { + thisObject.configEditor.deactivate() + } + if (thisObject.conditionEditor !== undefined) { + thisObject.conditionEditor.deactivate() + } + if (thisObject.formulaEditor !== undefined) { + thisObject.formulaEditor.deactivate() + } + isDragging = true + if (event.button === 2) { + rightDragging = true + } else { + rightDragging = false + } + + previousDistanceToReferenceParent = undefined + previousDistanceToChainParent = undefined + } + + function onDragFinished(event) { + if (isChainAttaching === true) { + canvas.designSpace.workspace.chainAttachNode(thisObject.payload.node, chainAttachToNode) + chainAttachToNode = undefined + isChainAttaching = false + } + if (isReferenceAttaching === true) { + canvas.designSpace.workspace.referenceAttachNode(thisObject.payload.node, referenceAttachToNode) + referenceAttachToNode = undefined + isReferenceAttaching = false + } + isDragging = false + } + + function drawBackground() { + if (thisObject.isOnFocus === false) { + drawReferenceLine() + drawChainLine() + + if (isDragging === false && thisObject.isOnFocus === true) { + thisObject.menu.drawBackground() + } + } + + if (thisObject.circularProgressBar !== undefined) { + thisObject.circularProgressBar.drawBackground() + } + } + + function drawMiddleground() { + if (thisObject.isOnFocus === false) { + drawValue() + drawPercentage() + drawStatus() + drawText() + thisObject.uiObjectTitle.draw() + } + } + + function drawForeground() { + if (thisObject.isOnFocus === false) { + drawBodyAndPicture() + if (isDragging === false) { + thisObject.menu.drawForeground() + } + } + + if (thisObject.circularProgressBar !== undefined) { + thisObject.circularProgressBar.drawForeground() + } + } + + function drawOnFocus() { + if (thisObject.isOnFocus === true) { + drawReferenceLine() + drawChainLine() + + if (thisObject.codeEditor !== undefined) { + thisObject.codeEditor.drawBackground() + thisObject.codeEditor.drawForeground() + } + if (thisObject.configEditor !== undefined) { + thisObject.configEditor.drawBackground() + thisObject.configEditor.drawForeground() + } + if (thisObject.conditionEditor !== undefined) { + thisObject.conditionEditor.drawBackground() + thisObject.conditionEditor.drawForeground() + } + if (thisObject.formulaEditor !== undefined) { + thisObject.formulaEditor.drawBackground() + thisObject.formulaEditor.drawForeground() + } + + let drawMenu = true + let drawTitle = true + + if (thisObject.codeEditor !== undefined) { + if (thisObject.codeEditor.visible === true) { + drawMenu = false + drawTitle = false + } + } + if (thisObject.configEditor !== undefined) { + if (thisObject.configEditor.visible === true) { + drawMenu = false + drawTitle = false + } + } + if (thisObject.conditionEditor !== undefined) { + if (thisObject.conditionEditor.visible === true) { + drawMenu = false + drawTitle = false + } + } + if (thisObject.formulaEditor !== undefined) { + if (thisObject.formulaEditor.visible === true) { + drawMenu = false + drawTitle = false + } + } + + if (drawMenu === true) { + drawBodyAndPicture() + if (isDragging === false) { + thisObject.menu.drawBackground() + thisObject.menu.drawForeground() + } + } + + drawErrorMessage() + drawValue() + drawPercentage() + drawStatus() + drawText() + + if (drawTitle === true) { + thisObject.uiObjectTitle.draw() + } + } + } + + function drawChainLine() { + if (canvas.floatingSpace.drawChainLines === false) { return } + if (thisObject.payload.chainParent === undefined) { return } + + let targetPoint = { + x: thisObject.payload.chainParent.payload.floatingObject.container.frame.position.x, + y: thisObject.payload.chainParent.payload.floatingObject.container.frame.position.y + } + + let position = { + x: 0, + y: 0 + } + + targetPoint = canvas.floatingSpace.container.frame.frameThisPoint(targetPoint) + position = thisObject.container.frame.frameThisPoint(position) + + if (canvas.floatingSpace.inMapMode === true) { + targetPoint = canvas.floatingSpace.transformPointToMap(targetPoint) + position = canvas.floatingSpace.transformPointToMap(position) + } + + if (thisObject.container.frame.radius > 1) { + let LINE_STYLE = UI_COLOR.TITANIUM_YELLOW + if (thisObject.payload.floatingObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED) { + LINE_STYLE = UI_COLOR.GOLDEN_ORANGE + } + if (thisObject.payload.floatingObject.isFrozen === true) { + LINE_STYLE = UI_COLOR.TURQUOISE + } + if (newUiObjectCounter > 0) { + LINE_STYLE = UI_COLOR.GREY + } + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(position.x, position.y) + browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) + browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' + browserCanvasContext.setLineDash([0, chainLineCounter, 2, 3, 0, 500 - chainLineCounter]) + browserCanvasContext.lineWidth = 2 + browserCanvasContext.stroke() + browserCanvasContext.setLineDash([0, 0]) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(position.x, position.y) + browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) + browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' + browserCanvasContext.setLineDash([3, 47]) + browserCanvasContext.lineWidth = 3 + browserCanvasContext.stroke() + browserCanvasContext.setLineDash([0, 0]) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(position.x, position.y) + browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) + browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' + browserCanvasContext.setLineDash([1, 9]) + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() + browserCanvasContext.setLineDash([0, 0]) + } + + if (thisObject.container.frame.radius > 0.5) { + let radius = 1 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(targetPoint.x, targetPoint.y, radius, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fill() + } + } + + function drawReferenceLine() { + if (canvas.floatingSpace.drawReferenceLines === false && thisObject.isOnFocus === false) { return } + if (thisObject.payload.referenceParent === undefined) { return } + if (thisObject.payload.referenceParent.payload === undefined) { return } + if (thisObject.payload.referenceParent.payload.floatingObject === undefined) { return } + if (thisObject.payload.referenceParent.payload.floatingObject.isParentCollapsed === true && thisObject.isOnFocus === false) { return } + + let targetPoint = { + x: thisObject.payload.referenceParent.payload.position.x, + y: thisObject.payload.referenceParent.payload.position.y + } + + let position = { + x: 0, + y: 0 + } + + targetPoint = canvas.floatingSpace.container.frame.frameThisPoint(targetPoint) + position = thisObject.container.frame.frameThisPoint(position) + + if (thisObject.isOnFocus === true) { + targetPoint = thisObject.fitFunction(targetPoint) } if (canvas.floatingSpace.inMapMode === true) { - labelPoint.y = labelPoint.y - 20 - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.isHierarchyHead !== true) { - return - } - } + position = canvas.floatingSpace.transformPointToMap(position) + targetPoint = canvas.floatingSpace.transformPointToMap(targetPoint) } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = thisObject.payload.floatingObject.labelStrokeStyle - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - } - } + let LINE_STYLE = UI_COLOR.GREY - function drawErrorMessage () { - if (hasError === false) { return } - -/* Text Follows */ - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - } - - let radius = thisObject.container.frame.radius * 2.5 - /* Label Text */ - let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize * 3 / 4 - let label - - if (radius > 6) { - const MAX_LABEL_LENGTH = 80 - - label = errorMessage - - if (label !== undefined) { - if (label.length > MAX_LABEL_LENGTH) { - label = label.substring(0, MAX_LABEL_LENGTH) + '...' - } - - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 2 / 5 + fontSize * FONT_ASPECT_RATIO + 15 - } - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - } - } - - function drawValue () { - if (currentValue === null) { return } - if (hasValue === false) { return } - if (canvas.floatingSpace.inMapMode === true) { return } - if (thisObject.payload === undefined) { return } - if ((thisObject.payload.floatingObject.isCollapsed === true && thisObject.payload.floatingObject.collapsedManually === false) || thisObject.payload.floatingObject.isParentCollapsed === true) { return } - - // if (currentValue === undefined || currentValue === '') { return } - -/* Text Follows */ - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - } - - let radius = thisObject.container.frame.radius * 1.35 - /* Label Text */ - let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 - let label - - if (radius > 6) { - const MAX_LABEL_LENGTH = 65 - - label = currentValue - if (!isNaN(currentValue)) { - if (currentValue.toFixed !== undefined) { - label = dynamicDecimals(currentValue) - } - } - - if (label !== undefined) { - if (label.length > MAX_LABEL_LENGTH) { - label = label.substring(0, MAX_LABEL_LENGTH) + '...' - } - - if (label.length > 30) { - fontSize = fontSize / 2 - } - - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, - y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 - } - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - } - } - - function drawPercentage () { - if (hasPercentage === false) { return } - if (canvas.floatingSpace.inMapMode === true) { return } - if (thisObject.payload === undefined) { return } - if ((thisObject.payload.floatingObject.isCollapsed === true && thisObject.payload.floatingObject.collapsedManually === false) || thisObject.payload.floatingObject.isParentCollapsed === true) { return } - - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - } - - let radius = thisObject.container.frame.radius * 1.75 - /* Label Text */ - let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 - let label - - if (radius > 6) { - const MAX_LABEL_LENGTH = 65 - - label = Number(currentPercentage).toFixed(0) + '%' - - if (label !== undefined) { - if (label.length > MAX_LABEL_LENGTH) { - label = label.substring(0, MAX_LABEL_LENGTH) + '...' - } - - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 - } - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - } - } - - function drawStatus () { - if (hasStatus === false) { return } - if (canvas.floatingSpace.inMapMode === true) { return } - - let position = { - x: 0, - y: 0 - } - - position = thisObject.container.frame.frameThisPoint(position) - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - } - - let radius = thisObject.container.frame.radius * 0.9 - /* Label Text */ - let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 / 2 - let label - - if (radius > 6) { - const MAX_LABEL_LENGTH = 100 - - label = currentStatus - - if (label !== undefined) { - if (label.length > MAX_LABEL_LENGTH) { - label = label.substring(0, MAX_LABEL_LENGTH) + '...' - } - - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, - y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 - } - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - } - } - - function addIndexNumber (label) { - switch (thisObject.payload.node.type) { - case 'Phase': { - let parent = thisObject.payload.parentNode - if (parent !== undefined) { - let granParent = parent.payload.parentNode - if (granParent !== undefined) { - if (granParent.type === 'Initial Definition') { - return label + ' #' + 0 - } - } - for (let i = 0; i < parent.phases.length; i++) { - let phase = parent.phases[i] - if (phase.id === thisObject.payload.node.id) { - label = label + ' #' + (i + 1) - return label - } - } - } else { - return label - } - - break - } - case 'Situation': { - let parent = thisObject.payload.parentNode - if (parent !== undefined) { - for (let i = 0; i < parent.situations.length; i++) { - let situation = parent.situations[i] - if (situation.id === thisObject.payload.node.id) { - label = label + ' #' + (i + 1) - return label - } - } - } else { - return label - } - - break - } - case 'Condition': { - let parent = thisObject.payload.parentNode - if (parent !== undefined) { - for (let i = 0; i < parent.conditions.length; i++) { - let condition = parent.conditions[i] - if (condition.id === thisObject.payload.node.id) { - label = label + ' #' + (i + 1) - return label - } - } - } else { - return label - } - - break - } - default: { - return label - } - } - } - - function drawBodyAndPicture () { - let position = { - x: thisObject.container.frame.position.x, - y: thisObject.container.frame.position.y - } - - position = thisObject.container.frame.frameThisPoint(position) - - if (thisObject.isShowing === true) { - position = thisObject.fitFunction(position) - } - - if (canvas.floatingSpace.inMapMode === true) { - position = canvas.floatingSpace.transformPointToMap(position) - } - - let radius = thisObject.container.frame.radius - - if (radius > 0.5) { - let VISIBLE_RADIUS = 5 - - let visiblePosition = { - x: thisObject.container.frame.position.x, - y: thisObject.container.frame.position.y - } - - visiblePosition = thisObject.container.frame.frameThisPoint(visiblePosition) - - if (canvas.floatingSpace.inMapMode === true) { - visiblePosition = canvas.floatingSpace.transformPointToMap(visiblePosition) - radius = canvas.floatingSpace.transformRadiusToMap(radius) - VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) - } else { - visiblePosition = thisObject.fitFunction(visiblePosition) - } - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - - browserCanvasContext.fillStyle = thisObject.payload.floatingObject.fillStyle - - browserCanvasContext.fill() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 2, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 1)' - - browserCanvasContext.fill() - - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.isHierarchyHead === true) { - VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 2.8 - if (canvas.floatingSpace.inMapMode === true) { - VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) - } - let OPACITY = 1 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([4, 16]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 1 - if (thisObject.payload.node.isIncluded === true) { + if (thisObject.container.frame.radius > 1) { + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(position.x, position.y) + browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) + browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' + browserCanvasContext.setLineDash([1, 9]) + browserCanvasContext.lineWidth = 0.75 + browserCanvasContext.stroke() + browserCanvasContext.setLineDash([0, 0]) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(position.x, position.y) + browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) + browserCanvasContext.strokeStyle = 'rgba(' + LINE_STYLE + ', 1)' + browserCanvasContext.setLineDash([0, referenceLineCounter, 1, 9, 2, 8, 3, 7, 4, 6, 0, 500 - referenceLineCounter]) + browserCanvasContext.lineWidth = 4 + browserCanvasContext.stroke() browserCanvasContext.setLineDash([0, 0]) - } else { - browserCanvasContext.setLineDash([20, 20]) - } - browserCanvasContext.stroke() } - } - if (thisObject.isOnFocus === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 2, 0, Math.PI * 2, true) - browserCanvasContext.closePath() + if (thisObject.container.frame.radius > 0.5) { + let radius = 1 - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.25)' - - browserCanvasContext.fill() - } - - if (hasError === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 1 - let OPACITY = errorMessageCounter / 30 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' - - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([19, 20]) - browserCanvasContext.stroke() - } - - if (isHighlighted === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 1 - let OPACITY = highlightCounter / 10 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([4, 20]) - browserCanvasContext.stroke() - } - - if (isReadyToChainAttach === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + readyToChainAttachDisplayCounter - readyToChainAttachDisplayCounter / 2 - let OPACITY = readyToChainAttachCounter / 10 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([10, 90]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 5 - browserCanvasContext.setLineDash([5, 45]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.setLineDash([2, 8]) - browserCanvasContext.stroke() - } - - if (isAvailableToChainAttach === true && isReadyToChainAttach === false) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 - let OPACITY = availableToChainAttachCounter / 10 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([8, 32]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 2 - browserCanvasContext.setLineDash([3, 5]) - browserCanvasContext.stroke() - } - - if (isReadyToReferenceAttach === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + readyToReferenceAttachDisplayCounter - readyToReferenceAttachDisplayCounter / 2 - let OPACITY = readyToReferenceAttachCounter / 10 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([10, 90]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 5 - browserCanvasContext.setLineDash([5, 45]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.setLineDash([2, 8]) - browserCanvasContext.stroke() - } - - if (isAvailableToReferenceAttach === true && isReadyToReferenceAttach === false) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 - let OPACITY = availableToReferenceAttachCounter / 10 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([8, 32]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 2 - browserCanvasContext.setLineDash([3, 5]) - browserCanvasContext.stroke() - } + browserCanvasContext.beginPath() + browserCanvasContext.arc(targetPoint.x, targetPoint.y, radius, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fill() + } } + function isEditorVisible() { + if (thisObject.codeEditor !== undefined) { + if (thisObject.codeEditor.visible === true) { return true } + } + + if (thisObject.configEditor !== undefined) { + if (thisObject.configEditor.visible === true) { return true } + } + + if (thisObject.conditionEditor !== undefined) { + if (thisObject.conditionEditor.visible === true) { return true } + } + + if (thisObject.formulaEditor !== undefined) { + if (thisObject.formulaEditor.visible === true) { return true } + } + } + + function drawText() { + if (isEditorVisible() === true) { return } + /* Text Follows */ + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + if (canvas.floatingSpace.inMapMode === true) { + position = canvas.floatingSpace.transformPointToMap(position) + } + + let radius = thisObject.container.frame.radius + /* Label Text */ + let labelPoint + let fontSize = thisObject.payload.floatingObject.currentFontSize + let label + + if (radius > 6) { + const MAX_LABEL_LENGTH = 30 + + label = thisObject.payload.subTitle + label = addIndexNumber(label) + + if (label !== undefined) { + if (label.length > MAX_LABEL_LENGTH) { + label = label.substring(0, MAX_LABEL_LENGTH) + '...' + } + + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, + y: position.y + radius * 4 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + } + + if (canvas.floatingSpace.inMapMode === true) { + labelPoint.y = labelPoint.y - 20 + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.isHierarchyHead !== true) { + return + } + } + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = thisObject.payload.floatingObject.labelStrokeStyle + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } + } + + function drawErrorMessage() { + if (hasError === false) { return } + + /* Text Follows */ + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + if (canvas.floatingSpace.inMapMode === true) { + position = canvas.floatingSpace.transformPointToMap(position) + } + + let radius = thisObject.container.frame.radius * 2.5 + /* Label Text */ + let labelPoint + let fontSize = thisObject.payload.floatingObject.currentFontSize * 3 / 4 + let label + + if (radius > 6) { + const MAX_LABEL_LENGTH = 80 + + label = errorMessage + + if (label !== undefined) { + if (label.length > MAX_LABEL_LENGTH) { + label = label.substring(0, MAX_LABEL_LENGTH) + '...' + } + + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, + y: position.y + radius * 2 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } + } + + function drawValue() { + if (currentValue === null) { return } + if (hasValue === false) { return } + if (canvas.floatingSpace.inMapMode === true) { return } + if (thisObject.payload === undefined) { return } + if ((thisObject.payload.floatingObject.isCollapsed === true && thisObject.payload.floatingObject.collapsedManually === false) || thisObject.payload.floatingObject.isParentCollapsed === true) { return } + + // if (currentValue === undefined || currentValue === '') { return } + + /* Text Follows */ + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + if (canvas.floatingSpace.inMapMode === true) { + position = canvas.floatingSpace.transformPointToMap(position) + } + + let radius = thisObject.container.frame.radius * 1.35 + /* Label Text */ + let labelPoint + let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 + let label + + if (radius > 6) { + const MAX_LABEL_LENGTH = 65 + + label = currentValue + if (!isNaN(currentValue)) { + if (currentValue.toFixed !== undefined) { + label = dynamicDecimals(currentValue) + } + } + + if (label !== undefined) { + if (label.length > MAX_LABEL_LENGTH) { + label = label.substring(0, MAX_LABEL_LENGTH) + '...' + } + + if (label.length > 30) { + fontSize = fontSize / 2 + } + + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, + y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } + } + + function drawPercentage() { + if (hasPercentage === false) { return } + if (canvas.floatingSpace.inMapMode === true) { return } + if (thisObject.payload === undefined) { return } + if ((thisObject.payload.floatingObject.isCollapsed === true && thisObject.payload.floatingObject.collapsedManually === false) || thisObject.payload.floatingObject.isParentCollapsed === true) { return } + + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + if (canvas.floatingSpace.inMapMode === true) { + position = canvas.floatingSpace.transformPointToMap(position) + } + + let radius = thisObject.container.frame.radius * 1.75 + /* Label Text */ + let labelPoint + let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 + let label + + if (radius > 6) { + const MAX_LABEL_LENGTH = 65 + + label = Number(currentPercentage).toFixed(0) + '%' + + if (label !== undefined) { + if (label.length > MAX_LABEL_LENGTH) { + label = label.substring(0, MAX_LABEL_LENGTH) + '...' + } + + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, + y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } + } + + function drawStatus() { + if (hasStatus === false) { return } + if (canvas.floatingSpace.inMapMode === true) { return } + + let position = { + x: 0, + y: 0 + } + + position = thisObject.container.frame.frameThisPoint(position) + + if (canvas.floatingSpace.inMapMode === true) { + position = canvas.floatingSpace.transformPointToMap(position) + } + + let radius = thisObject.container.frame.radius * 0.9 + /* Label Text */ + let labelPoint + let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 / 2 + let label + + if (radius > 6) { + const MAX_LABEL_LENGTH = 100 + + label = currentStatus + + if (label !== undefined) { + if (label.length > MAX_LABEL_LENGTH) { + label = label.substring(0, MAX_LABEL_LENGTH) + '...' + } + + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, + y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + } + } + + function addIndexNumber(label) { + switch (thisObject.payload.node.type) { + case 'Phase': { + let parent = thisObject.payload.parentNode + if (parent !== undefined) { + let granParent = parent.payload.parentNode + if (granParent !== undefined) { + if (granParent.type === 'Initial Definition') { + return label + ' #' + 0 + } + } + for (let i = 0; i < parent.phases.length; i++) { + let phase = parent.phases[i] + if (phase.id === thisObject.payload.node.id) { + label = label + ' #' + (i + 1) + return label + } + } + } else { + return label + } + + break + } + case 'Situation': { + let parent = thisObject.payload.parentNode + if (parent !== undefined) { + for (let i = 0; i < parent.situations.length; i++) { + let situation = parent.situations[i] + if (situation.id === thisObject.payload.node.id) { + label = label + ' #' + (i + 1) + return label + } + } + } else { + return label + } + + break + } + case 'Condition': { + let parent = thisObject.payload.parentNode + if (parent !== undefined) { + for (let i = 0; i < parent.conditions.length; i++) { + let condition = parent.conditions[i] + if (condition.id === thisObject.payload.node.id) { + label = label + ' #' + (i + 1) + return label + } + } + } else { + return label + } + + break + } + default: { + return label + } + } + } + + function drawBodyAndPicture() { + let position = { + x: thisObject.container.frame.position.x, + y: thisObject.container.frame.position.y + } + + position = thisObject.container.frame.frameThisPoint(position) + + if (thisObject.isShowing === true) { + position = thisObject.fitFunction(position) + } + + if (canvas.floatingSpace.inMapMode === true) { + position = canvas.floatingSpace.transformPointToMap(position) + } + + let radius = thisObject.container.frame.radius + + if (radius > 0.5) { + let VISIBLE_RADIUS = 5 + + let visiblePosition = { + x: thisObject.container.frame.position.x, + y: thisObject.container.frame.position.y + } + + visiblePosition = thisObject.container.frame.frameThisPoint(visiblePosition) + + if (canvas.floatingSpace.inMapMode === true) { + visiblePosition = canvas.floatingSpace.transformPointToMap(visiblePosition) + radius = canvas.floatingSpace.transformRadiusToMap(radius) + VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) + } else { + visiblePosition = thisObject.fitFunction(visiblePosition) + } + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + + browserCanvasContext.fillStyle = thisObject.payload.floatingObject.fillStyle + + browserCanvasContext.fill() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 2, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 1)' + + browserCanvasContext.fill() + + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.isHierarchyHead === true) { + VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 2.8 + if (canvas.floatingSpace.inMapMode === true) { + VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) + } + let OPACITY = 1 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([4, 16]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 1 + if (thisObject.payload.node.isIncluded === true) { + browserCanvasContext.setLineDash([0, 0]) + } else { + browserCanvasContext.setLineDash([20, 20]) + } + browserCanvasContext.stroke() + } + } + + if (thisObject.isOnFocus === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 2, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.25)' + + browserCanvasContext.fill() + } + + if (hasError === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 1 + let OPACITY = errorMessageCounter / 30 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' + + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([19, 20]) + browserCanvasContext.stroke() + } + + if (isHighlighted === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 1 + let OPACITY = highlightCounter / 10 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([4, 20]) + browserCanvasContext.stroke() + } + + if (isReadyToChainAttach === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + readyToChainAttachDisplayCounter - readyToChainAttachDisplayCounter / 2 + let OPACITY = readyToChainAttachCounter / 10 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([10, 90]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 5 + browserCanvasContext.setLineDash([5, 45]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.setLineDash([2, 8]) + browserCanvasContext.stroke() + } + + if (isAvailableToChainAttach === true && isReadyToChainAttach === false) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + let OPACITY = availableToChainAttachCounter / 10 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([8, 32]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 2 + browserCanvasContext.setLineDash([3, 5]) + browserCanvasContext.stroke() + } + + if (isReadyToReferenceAttach === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + readyToReferenceAttachDisplayCounter - readyToReferenceAttachDisplayCounter / 2 + let OPACITY = readyToReferenceAttachCounter / 10 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([10, 90]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 5 + browserCanvasContext.setLineDash([5, 45]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.setLineDash([2, 8]) + browserCanvasContext.stroke() + } + + if (isAvailableToReferenceAttach === true && isReadyToReferenceAttach === false) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + let OPACITY = availableToReferenceAttachCounter / 10 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([8, 32]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 2 + browserCanvasContext.setLineDash([3, 5]) + browserCanvasContext.stroke() + } + } + /* Image */ - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - let additionalImageSize = 0 - if (isRunningAtBackend === true || isReadyToReferenceAttach === true || isReadyToChainAttach === true) { additionalImageSize = 20 } - let totalImageSize = additionalImageSize + thisObject.payload.floatingObject.currentImageSize - if (canvas.floatingSpace.inMapMode === true) { - totalImageSize = canvas.floatingSpace.transformImagesizeToMap(totalImageSize) - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.isHierarchyHead !== true) { - totalImageSize = totalImageSize / 4 + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + let additionalImageSize = 0 + if (isRunningAtBackend === true || isReadyToReferenceAttach === true || isReadyToChainAttach === true) { additionalImageSize = 20 } + let totalImageSize = additionalImageSize + thisObject.payload.floatingObject.currentImageSize + if (canvas.floatingSpace.inMapMode === true) { + totalImageSize = canvas.floatingSpace.transformImagesizeToMap(totalImageSize) + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.isHierarchyHead !== true) { + totalImageSize = totalImageSize / 4 + } + } + } + + if (thisObject.isShowing === true) { + totalImageSize = 50 + } + + browserCanvasContext.drawImage( + icon, position.x - totalImageSize / 2, + position.y - totalImageSize / 2, + totalImageSize, + totalImageSize) } - } } - if (thisObject.isShowing === true) { - totalImageSize = 50 - } + if (executingIcon !== undefined) { + if (executingIcon.canDrawIcon === true) { + if (isRunningAtBackend === true) { + const DISTANCE_FROM_CENTER = thisObject.container.frame.radius / 3 + 50 + const EXECUTING_ICON_SIZE = 20 + thisObject.container.frame.radius / 6 - browserCanvasContext.drawImage( - icon, position.x - totalImageSize / 2, - position.y - totalImageSize / 2, - totalImageSize, - totalImageSize) - } + browserCanvasContext.drawImage( + executingIcon, position.x - EXECUTING_ICON_SIZE / 2, + position.y - EXECUTING_ICON_SIZE / 2 - DISTANCE_FROM_CENTER, + EXECUTING_ICON_SIZE, + EXECUTING_ICON_SIZE) + } + } + } } - - if (executingIcon !== undefined) { - if (executingIcon.canDrawIcon === true) { - if (isRunningAtBackend === true) { - const DISTANCE_FROM_CENTER = thisObject.container.frame.radius / 3 + 50 - const EXECUTING_ICON_SIZE = 20 + thisObject.container.frame.radius / 6 - - browserCanvasContext.drawImage( - executingIcon, position.x - EXECUTING_ICON_SIZE / 2, - position.y - EXECUTING_ICON_SIZE / 2 - DISTANCE_FROM_CENTER, - EXECUTING_ICON_SIZE, - EXECUTING_ICON_SIZE) - } - } - } - } } diff --git a/FloatingSpace/UiObjectConstructor.js b/FloatingSpace/UiObjectConstructor.js index 1c17ca23c..83c151737 100644 --- a/FloatingSpace/UiObjectConstructor.js +++ b/FloatingSpace/UiObjectConstructor.js @@ -1,654 +1,654 @@ -function newUiObjectConstructor () { - const MODULE_NAME = 'UI Object Constructor' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newUiObjectConstructor() { + const MODULE_NAME = 'UI Object Constructor' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - createUiObject: createUiObject, - destroyUiObject: destroyUiObject, - initialize: initialize, - finalize: finalize - } - - let floatingLayer - - return thisObject - - function finalize () { - floatingLayer = undefined - } - - function initialize (pFloatingLayer) { - floatingLayer = pFloatingLayer - } - - function createUiObject (userAddingNew, payload) { - let floatingObject = newFloatingObject() - floatingObject.fitFunction = canvas.floatingSpace.fitIntoVisibleArea - floatingObject.container.connectToParent(canvas.floatingSpace.container, false, false, false, false, false, false, false, false) - floatingObject.initialize('UI Object', payload) - payload.floatingObject = floatingObject - - /* - When this object is created based on a backup, share or clone, we will have a savedPayload that we will use to set the initial properties. - If it is a new object being created out of the user interface, we jusst continue with the construction process. - */ - if (userAddingNew === false && payload.node.type !== 'Workspace') { - let position = { - x: 0, - y: 0 - } - - position = { - x: payload.node.savedPayload.position.x, - y: payload.node.savedPayload.position.y - } - - floatingObject.setPosition(position) - payload.node.savedPayload.position = undefined - if (payload.node.savedPayload.floatingObject.isPinned === true) { - floatingObject.pinToggle() - } - if (payload.node.savedPayload.floatingObject.isFrozen === true) { - floatingObject.freezeToggle() - } - if (payload.node.savedPayload.floatingObject.isCollapsed === true) { - floatingObject.collapseToggle() - } - if (payload.node.savedPayload.floatingObject.angleToParent !== undefined) { - floatingObject.angleToParent = payload.node.savedPayload.floatingObject.angleToParent - } - if (payload.node.savedPayload.floatingObject.distanceToParent !== undefined) { - floatingObject.distanceToParent = payload.node.savedPayload.floatingObject.distanceToParent - } - if (payload.node.savedPayload.floatingObject.arrangementStyle !== undefined) { - floatingObject.arrangementStyle = payload.node.savedPayload.floatingObject.arrangementStyle - } + let thisObject = { + createUiObject: createUiObject, + destroyUiObject: destroyUiObject, + initialize: initialize, + finalize: finalize } - /* - For brand new objects being created directly by the user, we will make them inherit some properties - from their closest siblings, and if they don't have, from their parents. - */ + let floatingLayer - if (userAddingNew === true) { - let definition = getNodeDefinition(payload.parentNode) - if (definition.properties !== undefined) { - for (let i = 0; i < definition.properties.length; i++) { - let property = definition.properties[i] - if (property.childType === payload.node.type) { - if (property.type === 'array') { - let parentNode = payload.parentNode - let parentNodeArray = parentNode[property.name] - if (parentNodeArray.length > 1) { // the new node was already added - let closestSibling = parentNodeArray[parentNodeArray.length - 2] - if (closestSibling !== undefined) { - floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent - floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent - floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle - break - } - } + return thisObject + + function finalize() { + floatingLayer = undefined + } + + function initialize(pFloatingLayer) { + floatingLayer = pFloatingLayer + } + + function createUiObject(userAddingNew, payload) { + let floatingObject = newFloatingObject() + floatingObject.fitFunction = canvas.floatingSpace.fitIntoVisibleArea + floatingObject.container.connectToParent(canvas.floatingSpace.container, false, false, false, false, false, false, false, false) + floatingObject.initialize('UI Object', payload) + payload.floatingObject = floatingObject + + /* + When this object is created based on a backup, share or clone, we will have a savedPayload that we will use to set the initial properties. + If it is a new object being created out of the user interface, we jusst continue with the construction process. + */ + if (userAddingNew === false && payload.node.type !== 'Workspace') { + let position = { + x: 0, + y: 0 } + + position = { + x: payload.node.savedPayload.position.x, + y: payload.node.savedPayload.position.y + } + + floatingObject.setPosition(position) + payload.node.savedPayload.position = undefined + if (payload.node.savedPayload.floatingObject.isPinned === true) { + floatingObject.pinToggle() + } + if (payload.node.savedPayload.floatingObject.isFrozen === true) { + floatingObject.freezeToggle() + } + if (payload.node.savedPayload.floatingObject.isCollapsed === true) { + floatingObject.collapseToggle() + } + if (payload.node.savedPayload.floatingObject.angleToParent !== undefined) { + floatingObject.angleToParent = payload.node.savedPayload.floatingObject.angleToParent + } + if (payload.node.savedPayload.floatingObject.distanceToParent !== undefined) { + floatingObject.distanceToParent = payload.node.savedPayload.floatingObject.distanceToParent + } + if (payload.node.savedPayload.floatingObject.arrangementStyle !== undefined) { + floatingObject.arrangementStyle = payload.node.savedPayload.floatingObject.arrangementStyle + } + } + + /* + For brand new objects being created directly by the user, we will make them inherit some properties + from their closest siblings, and if they don't have, from their parents. + */ + + if (userAddingNew === true) { + let definition = getNodeDefinition(payload.parentNode) + if (definition.properties !== undefined) { + for (let i = 0; i < definition.properties.length; i++) { + let property = definition.properties[i] + if (property.childType === payload.node.type) { + if (property.type === 'array') { + let parentNode = payload.parentNode + let parentNodeArray = parentNode[property.name] + if (parentNodeArray.length > 1) { // the new node was already added + let closestSibling = parentNodeArray[parentNodeArray.length - 2] + if (closestSibling !== undefined) { + floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent + floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent + floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle + break + } + } + } + if (floatingObject.angleToParent === undefined) { + for (let j = i - 1; j >= 0; j--) { + let siblingProperty = definition.properties[j] + let parentNode = payload.parentNode + let parentNodeProperty = parentNode[siblingProperty.name] + if (parentNodeProperty !== undefined) { + if (siblingProperty.type === 'array') { + if (parentNodeProperty.length > 0) { + let closestSibling = parentNodeProperty[parentNodeProperty.length - 1] + if (closestSibling !== undefined) { + floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent + floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent + floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle + break + } + } + } else { + let closestSibling = parentNodeProperty + if (closestSibling !== undefined) { + floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent + floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent + floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle + break + } + } + } + } + for (let j = i + 1; j < definition.properties.length; j++) { + let siblingProperty = definition.properties[j] + let parentNode = payload.parentNode + let parentNodeProperty = parentNode[siblingProperty.name] + if (parentNodeProperty !== undefined) { + if (siblingProperty.type === 'array') { + if (parentNodeProperty.length > 0) { + let closestSibling = parentNodeProperty[parentNodeProperty.length - 1] + if (closestSibling !== undefined) { + floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent + floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent + floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle + break + } + } + } else { + let closestSibling = parentNodeProperty + if (closestSibling !== undefined) { + floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent + floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent + floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle + break + } + } + } + } + } + } + } + } + if (floatingObject.angleToParent === undefined) { - for (let j = i - 1; j >= 0; j--) { - let siblingProperty = definition.properties[j] - let parentNode = payload.parentNode - let parentNodeProperty = parentNode[siblingProperty.name] - if (parentNodeProperty !== undefined) { - if (siblingProperty.type === 'array') { - if (parentNodeProperty.length > 0) { - let closestSibling = parentNodeProperty[parentNodeProperty.length - 1] - if (closestSibling !== undefined) { - floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent - floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent - floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle - break - } + floatingObject.angleToParent = payload.parentNode.payload.floatingObject.angleToParent + floatingObject.distanceToParent = payload.parentNode.payload.floatingObject.distanceToParent + floatingObject.arrangementStyle = payload.parentNode.payload.floatingObject.arrangementStyle + } + } + + /* Default Values in case there was no way to set a value previous to this. */ + if (floatingObject.angleToParent === undefined) { + floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_360 + } + if (floatingObject.distanceToParent === undefined) { + floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X + } + if (floatingObject.arrangementStyle === undefined) { + floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE + } + + let uiObject = newUiObject() + payload.uiObject = uiObject + uiObject.fitFunction = canvas.floatingSpace.fitIntoVisibleArea + uiObject.isVisibleFunction = canvas.floatingSpace.isThisPointVisible + let menuItemsInitialValues = getMenuItemsInitialValues(uiObject, floatingObject, payload) + + for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { + let schemaNode = APP_SCHEMA_ARRAY[i] + if (schemaNode.type === payload.node.type) { + let menuItems = schemaNode.menuItems + for (let j = 0; j < menuItems.length; j++) { + let item = menuItems[j] + item.angle = undefined + if (item.action.indexOf('Add Missing Children') >= 0) { + item.action = 'Add Missing Children' } - } else { - let closestSibling = parentNodeProperty - if (closestSibling !== undefined) { - floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent - floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent - floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle - break + if (item.action.indexOf('Delete ') >= 0) { + // item.action = 'Delete UI Object' + } + if (item.action.indexOf('Configure ') >= 0) { + if (schemaNode.editors.config === true) { + // item.actionFunction = 'uiObject.configEditor.activate' + } + } + if (item.action.indexOf('Edit ') >= 0) { + if (schemaNode.editors.code === true) { + // item.actionFunction = 'uiObject.codeEditor.activate' + } + } + if (item.actionFunction === undefined) { + // item.actionFunction = 'payload.onMenuItemClick' } - } } - } - for (let j = i + 1; j < definition.properties.length; j++) { - let siblingProperty = definition.properties[j] - let parentNode = payload.parentNode - let parentNodeProperty = parentNode[siblingProperty.name] - if (parentNodeProperty !== undefined) { - if (siblingProperty.type === 'array') { - if (parentNodeProperty.length > 0) { - let closestSibling = parentNodeProperty[parentNodeProperty.length - 1] - if (closestSibling !== undefined) { - floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent - floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent - floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle - break - } - } - } else { - let closestSibling = parentNodeProperty - if (closestSibling !== undefined) { - floatingObject.angleToParent = closestSibling.payload.floatingObject.angleToParent - floatingObject.distanceToParent = closestSibling.payload.floatingObject.distanceToParent - floatingObject.arrangementStyle = closestSibling.payload.floatingObject.arrangementStyle - break - } - } + } + } + + uiObject.initialize(payload, menuItemsInitialValues) + uiObject.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true, true, true) + + setFloatingObjectBasicProperties(floatingObject, payload) + + if (payload.node.savedPayload !== undefined) { + if (payload.node.savedPayload.uiObject !== undefined) { + payload.uiObject.shortcutKey = payload.node.savedPayload.uiObject.shortcutKey + } + } + + floatingLayer.addFloatingObject(floatingObject) + + return + } + + function addLeftIcons(menuItemsInitialValues, floatingObject, isPersonalData) { + menuItemsInitialValues.push( + { + action: 'Pin / Unpin', + actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, + currentStatus: false, + label: undefined, + visible: true, + iconPathOn: 'menu-fix-pinned', + iconPathOff: 'menu-fix-unpinned', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 1 + } + ) + menuItemsInitialValues.push( + { + action: 'Change Tension Level', + actionFunction: floatingObject.angleToParentToggle, + actionStatus: floatingObject.getAngleToParent, + currentStatus: true, + label: undefined, + visible: true, + icons: ['angle-to-parent-000', 'angle-to-parent-360', 'angle-to-parent-180', 'angle-to-parent-090', 'angle-to-parent-045'], + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 1 + } + ) + menuItemsInitialValues.push( + { + action: 'Change Distance to Paarent', + actionFunction: floatingObject.distanceToParentToggle, + actionStatus: floatingObject.getDistanceToParent, + currentStatus: true, + label: undefined, + visible: true, + icons: ['distance-to-parent-000', 'distance-to-parent-025', 'distance-to-parent-050', 'distance-to-parent-100', 'distance-to-parent-150', 'distance-to-parent-200'], + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 1 + } + ) + menuItemsInitialValues.push( + { + action: 'Change Arrangement Style', + actionFunction: floatingObject.arrangementStyleToggle, + actionStatus: floatingObject.getArrangementStyle, + currentStatus: true, + label: undefined, + visible: true, + icons: ['arrangement-concave', 'arrangement-convex', 'arrangement-vertical-right', 'arrangement-vertical-left', 'arrangement-horizontal-bottom', 'arrangement-horizontal-top'], + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 1 + } + ) + menuItemsInitialValues.push( + { + action: 'Freeze / Unfreeze', + actionFunction: floatingObject.freezeToggle, + actionStatus: floatingObject.getFreezeStatus, + currentStatus: true, + label: undefined, + visible: true, + iconPathOn: 'menu-mobility-unfreeze', + iconPathOff: 'menu-mobility-freeze', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 1 + } + ) + menuItemsInitialValues.push( + { + action: 'Collapse / Uncollapse', + actionFunction: floatingObject.collapseToggle, + actionStatus: floatingObject.getCollapseStatus, + currentStatus: false, + label: undefined, + visible: true, + iconPathOn: 'menu-tree-plus', + iconPathOff: 'menu-tree-minus', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 1 + } + ) + menuItemsInitialValues.push( + { + action: 'Backup', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: true, + iconPathOn: 'menu-backup', + iconPathOff: 'menu-backup', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 2 + } + ) + menuItemsInitialValues.push( + { + action: 'Clone', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: true, + iconPathOn: 'clone', + iconPathOff: 'clone', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 2 + } + ) + if (isPersonalData !== true) { + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 2 } - } - } - } - } - } - - if (floatingObject.angleToParent === undefined) { - floatingObject.angleToParent = payload.parentNode.payload.floatingObject.angleToParent - floatingObject.distanceToParent = payload.parentNode.payload.floatingObject.distanceToParent - floatingObject.arrangementStyle = payload.parentNode.payload.floatingObject.arrangementStyle - } - } - - /* Default Values in case there was no way to set a value previous to this. */ - if (floatingObject.angleToParent === undefined) { - floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_360 - } - if (floatingObject.distanceToParent === undefined) { - floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X - } - if (floatingObject.arrangementStyle === undefined) { - floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE - } - - let uiObject = newUiObject() - payload.uiObject = uiObject - uiObject.fitFunction = canvas.floatingSpace.fitIntoVisibleArea - uiObject.isVisibleFunction = canvas.floatingSpace.isThisPointVisible - let menuItemsInitialValues = getMenuItemsInitialValues(uiObject, floatingObject, payload) - - for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { - let schemaNode = APP_SCHEMA_ARRAY[i] - if (schemaNode.type === payload.node.type) { - let menuItems = schemaNode.menuItems - for (let j = 0; j < menuItems.length; j++) { - let item = menuItems[j] - item.angle = undefined - if (item.action.indexOf('Add Missing Children') >= 0) { - item.action = 'Add Missing Children' - } - if (item.action.indexOf('Delete ') >= 0) { - // item.action = 'Delete UI Object' - } - if (item.action.indexOf('Configure ') >= 0) { - if (schemaNode.editors.config === true) { - // item.actionFunction = 'uiObject.configEditor.activate' - } - } - if (item.action.indexOf('Edit ') >= 0) { - if (schemaNode.editors.code === true) { - // item.actionFunction = 'uiObject.codeEditor.activate' - } - } - if (item.actionFunction === undefined) { - // item.actionFunction = 'payload.onMenuItemClick' - } - } - } - } - - uiObject.initialize(payload, menuItemsInitialValues) - uiObject.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true, true, true) - - setFloatingObjectBasicProperties(floatingObject, payload) - - if (payload.node.savedPayload !== undefined) { - if (payload.node.savedPayload.uiObject !== undefined) { - payload.uiObject.shortcutKey = payload.node.savedPayload.uiObject.shortcutKey - } - } - - floatingLayer.addFloatingObject(floatingObject) - - return - } - - function addLeftIcons (menuItemsInitialValues, floatingObject, isPersonalData) { - menuItemsInitialValues.push( - { - action: 'Pin / Unpin', - actionFunction: floatingObject.pinToggle, - actionStatus: floatingObject.getPinStatus, - currentStatus: false, - label: undefined, - visible: true, - iconPathOn: 'menu-fix-pinned', - iconPathOff: 'menu-fix-unpinned', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 1 - } - ) - menuItemsInitialValues.push( - { - action: 'Change Tension Level', - actionFunction: floatingObject.angleToParentToggle, - actionStatus: floatingObject.getAngleToParent, - currentStatus: true, - label: undefined, - visible: true, - icons: ['angle-to-parent-000', 'angle-to-parent-360', 'angle-to-parent-180', 'angle-to-parent-090', 'angle-to-parent-045'], - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 1 - } - ) - menuItemsInitialValues.push( - { - action: 'Change Distance to Paarent', - actionFunction: floatingObject.distanceToParentToggle, - actionStatus: floatingObject.getDistanceToParent, - currentStatus: true, - label: undefined, - visible: true, - icons: ['distance-to-parent-000', 'distance-to-parent-025', 'distance-to-parent-050', 'distance-to-parent-100', 'distance-to-parent-150', 'distance-to-parent-200'], - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 1 - } - ) - menuItemsInitialValues.push( - { - action: 'Change Arrangement Style', - actionFunction: floatingObject.arrangementStyleToggle, - actionStatus: floatingObject.getArrangementStyle, - currentStatus: true, - label: undefined, - visible: true, - icons: ['arrangement-concave', 'arrangement-convex', 'arrangement-vertical-right', 'arrangement-vertical-left', 'arrangement-horizontal-bottom', 'arrangement-horizontal-top'], - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 1 - } ) - menuItemsInitialValues.push( - { - action: 'Freeze / Unfreeze', - actionFunction: floatingObject.freezeToggle, - actionStatus: floatingObject.getFreezeStatus, - currentStatus: true, - label: undefined, - visible: true, - iconPathOn: 'menu-mobility-unfreeze', - iconPathOff: 'menu-mobility-freeze', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 1 - } - ) - menuItemsInitialValues.push( - { - action: 'Collapse / Uncollapse', - actionFunction: floatingObject.collapseToggle, - actionStatus: floatingObject.getCollapseStatus, - currentStatus: false, - label: undefined, - visible: true, - iconPathOn: 'menu-tree-plus', - iconPathOff: 'menu-tree-minus', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 1 - } - ) - menuItemsInitialValues.push( - { - action: 'Backup', - actionFunction: floatingObject.payload.onMenuItemClick, - label: undefined, - visible: true, - iconPathOn: 'menu-backup', - iconPathOff: 'menu-backup', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 2 - } - ) - menuItemsInitialValues.push( - { - action: 'Clone', - actionFunction: floatingObject.payload.onMenuItemClick, - label: undefined, - visible: true, - iconPathOn: 'clone', - iconPathOff: 'clone', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 2 - } + } + menuItemsInitialValues.push( + { + action: 'Remove Parent', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: true, + iconPathOn: 'detach', + iconPathOff: 'detach', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 3 + } ) - if (isPersonalData !== true) { - menuItemsInitialValues.push( - { - action: 'Share', - actionFunction: floatingObject.payload.onMenuItemClick, - label: undefined, - visible: true, - iconPathOn: 'menu-share', - iconPathOff: 'menu-share', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 2 - } - ) - } - menuItemsInitialValues.push( - { - action: 'Remove Parent', - actionFunction: floatingObject.payload.onMenuItemClick, - label: undefined, - visible: true, - iconPathOn: 'detach', - iconPathOff: 'detach', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 3 - } + menuItemsInitialValues.push( + { + action: 'Remove Reference', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: true, + iconPathOn: 'delink', + iconPathOff: 'delink', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 3 + } ) - menuItemsInitialValues.push( - { - action: 'Remove Reference', - actionFunction: floatingObject.payload.onMenuItemClick, - label: undefined, - visible: true, - iconPathOn: 'delink', - iconPathOff: 'delink', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 3 - } - ) - menuItemsInitialValues.push( - { - action: 'Open Documentation', - actionFunction: floatingObject.payload.onMenuItemClick, - label: undefined, - visible: true, - iconPathOn: 'help', - iconPathOff: 'help', - rawRadius: 12, - targetRadius: 0, - currentRadius: 0, - ring: 4 - } - ) - } - - function getMenuItemsInitialValues (uiObject, floatingObject, payload) { - let menuItemsInitialValues = [] - - let nodeDefinition = getNodeDefinition(payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.editors !== undefined) { - if (nodeDefinition.editors.config === true) { - uiObject.configEditor = newConfigEditor() - uiObject.configEditor.isVisibleFunction = uiObject.isVisibleFunction - uiObject.configEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false) - uiObject.configEditor.initialize() - } - if (nodeDefinition.editors.code === true) { - uiObject.codeEditor = newCodeEditor() - uiObject.codeEditor.isVisibleFunction = uiObject.isVisibleFunction - uiObject.codeEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false) - uiObject.codeEditor.initialize() - } - if (nodeDefinition.editors.formula === true) { - uiObject.formulaEditor = newFormulaEditor() - uiObject.formulaEditor.isVisibleFunction = uiObject.isVisibleFunction - uiObject.formulaEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false) - uiObject.formulaEditor.initialize() - } - if (nodeDefinition.editors.condition === true) { - uiObject.conditionEditor = newConditionEditor() - uiObject.conditionEditor.isVisibleFunction = uiObject.isVisibleFunction - uiObject.conditionEditor.container.connectToParent(uiObject.container, false, false, false, true, false, false, false, false) - uiObject.conditionEditor.initialize() - } - } - if (nodeDefinition.addLeftIcons === true) { - addLeftIcons(menuItemsInitialValues, floatingObject, nodeDefinition.isPersonalData) - } - if (nodeDefinition.isPinned === true) { - floatingObject.isPinned = true - } - if (nodeDefinition.positionLocked === true) { - floatingObject.positionLocked = true - } - - for (let i = 0; i < nodeDefinition.menuItems.length; i++) { - let menutItemDefinition = nodeDefinition.menuItems[i] - let newMenuItem = JSON.parse(JSON.stringify(menutItemDefinition)) - - /* We need to reference the real function based on its name */ - if (menutItemDefinition.actionFunction !== undefined) { - try { - newMenuItem.actionFunction = eval(menutItemDefinition.actionFunction) - } catch (err) { - console.log('Error at Menu Item Action Function: ' + menutItemDefinition.actionFunction + ' ' + err.stack) - continue - } - } - - /* Adding default values */ - if (newMenuItem.visible === undefined) { - newMenuItem.visible = true - } - - if (newMenuItem.rawRadius === undefined) { - newMenuItem.rawRadius = 12 - } - - if (newMenuItem.targetRadius === undefined) { - newMenuItem.targetRadius = 0 - } - - if (newMenuItem.currentRadius === undefined) { - newMenuItem.currentRadius = 0 - } - - menuItemsInitialValues.push(newMenuItem) - } - } else { - if (ERROR_LOG === true) { logger.write('[ERROR] getMenuItemsInitialValues -> UI Object Type not Recognized -> type = ' + payload.node.type) } + menuItemsInitialValues.push( + { + action: 'Open Documentation', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: true, + iconPathOn: 'help', + iconPathOff: 'help', + rawRadius: 12, + targetRadius: 0, + currentRadius: 0, + ring: 4 + } + ) } - return menuItemsInitialValues - } + function getMenuItemsInitialValues(uiObject, floatingObject, payload) { + let menuItemsInitialValues = [] - function setFloatingObjectBasicProperties (floatingObject, payload) { - const FRICTION = 0.95 - const INITIAL_FRICTION = 0.97 - const INITIAL_FONT_SIZE = 12 * 1.5 - const INITIAL_RADIOUS = 45 * 1.5 - const INITIAL_IMAGE_SIZE = 80 * 1.2 - const INITIAL_HIERARCHY_RING = 20 - - switch (payload.node.type) { - case 'Workspace': { - level_0() - floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_360 - break - } - - default: { let nodeDefinition = getNodeDefinition(payload.node) if (nodeDefinition !== undefined) { - switch (nodeDefinition.level) { - case 0: { - level_0() - break + if (nodeDefinition.editors !== undefined) { + if (nodeDefinition.editors.config === true) { + uiObject.configEditor = newConfigEditor() + uiObject.configEditor.isVisibleFunction = uiObject.isVisibleFunction + uiObject.configEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false) + uiObject.configEditor.initialize() + } + if (nodeDefinition.editors.code === true) { + uiObject.codeEditor = newCodeEditor() + uiObject.codeEditor.isVisibleFunction = uiObject.isVisibleFunction + uiObject.codeEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false) + uiObject.codeEditor.initialize() + } + if (nodeDefinition.editors.formula === true) { + uiObject.formulaEditor = newFormulaEditor() + uiObject.formulaEditor.isVisibleFunction = uiObject.isVisibleFunction + uiObject.formulaEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false) + uiObject.formulaEditor.initialize() + } + if (nodeDefinition.editors.condition === true) { + uiObject.conditionEditor = newConditionEditor() + uiObject.conditionEditor.isVisibleFunction = uiObject.isVisibleFunction + uiObject.conditionEditor.container.connectToParent(uiObject.container, false, false, false, true, false, false, false, false) + uiObject.conditionEditor.initialize() + } } - case 1: { - level_1() - break + if (nodeDefinition.addLeftIcons === true) { + addLeftIcons(menuItemsInitialValues, floatingObject, nodeDefinition.isPersonalData) } - case 2: { - level_2() - break + if (nodeDefinition.isPinned === true) { + floatingObject.isPinned = true } - case 3: { - level_3() - break + if (nodeDefinition.positionLocked === true) { + floatingObject.positionLocked = true } - case 4: { - level_4() - break + + for (let i = 0; i < nodeDefinition.menuItems.length; i++) { + let menutItemDefinition = nodeDefinition.menuItems[i] + let newMenuItem = JSON.parse(JSON.stringify(menutItemDefinition)) + + /* We need to reference the real function based on its name */ + if (menutItemDefinition.actionFunction !== undefined) { + try { + newMenuItem.actionFunction = eval(menutItemDefinition.actionFunction) + } catch (err) { + console.log('Error at Menu Item Action Function: ' + menutItemDefinition.actionFunction + ' ' + err.stack) + continue + } + } + + /* Adding default values */ + if (newMenuItem.visible === undefined) { + newMenuItem.visible = true + } + + if (newMenuItem.rawRadius === undefined) { + newMenuItem.rawRadius = 12 + } + + if (newMenuItem.targetRadius === undefined) { + newMenuItem.targetRadius = 0 + } + + if (newMenuItem.currentRadius === undefined) { + newMenuItem.currentRadius = 0 + } + + menuItemsInitialValues.push(newMenuItem) } - case 5: { - level_5() - break - } - } + } else { + if (ERROR_LOG === true) { logger.write('[ERROR] getMenuItemsInitialValues -> UI Object Type not Recognized -> type = ' + payload.node.type) } } - } + + return menuItemsInitialValues } - function level_0 () { - floatingObject.targetFriction = 0.93 - floatingObject.friction = INITIAL_FRICTION + function setFloatingObjectBasicProperties(floatingObject, payload) { + const FRICTION = 0.95 + const INITIAL_FRICTION = 0.97 + const INITIAL_FONT_SIZE = 12 * 1.5 + const INITIAL_RADIOUS = 45 * 1.5 + const INITIAL_IMAGE_SIZE = 80 * 1.2 + const INITIAL_HIERARCHY_RING = 20 - floatingObject.initializeMass(500) - floatingObject.initializeRadius(INITIAL_RADIOUS) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + switch (payload.node.type) { + case 'Workspace': { + level_0() + floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_360 + break + } - floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - } - function level_1 () { - floatingObject.targetFriction = 0.94 - floatingObject.friction = INITIAL_FRICTION + default: { + let nodeDefinition = getNodeDefinition(payload.node) + if (nodeDefinition !== undefined) { + switch (nodeDefinition.level) { + case 0: { + level_0() + break + } + case 1: { + level_1() + break + } + case 2: { + level_2() + break + } + case 3: { + level_3() + break + } + case 4: { + level_4() + break + } + case 5: { + level_5() + break + } + } + } + } + } - floatingObject.initializeMass(600) - floatingObject.initializeRadius(INITIAL_RADIOUS) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + function level_0() { + floatingObject.targetFriction = 0.93 + floatingObject.friction = INITIAL_FRICTION - floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + floatingObject.initializeMass(500) + floatingObject.initializeRadius(INITIAL_RADIOUS) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) - if (payload.node.savedPayload === undefined) { - // floatingObject.angleToParentToggle() - } - } - function level_2 () { - floatingObject.targetFriction = FRICTION - floatingObject.friction = INITIAL_FRICTION + floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + } + function level_1() { + floatingObject.targetFriction = 0.94 + floatingObject.friction = INITIAL_FRICTION - floatingObject.initializeMass(300) - floatingObject.initializeRadius(INITIAL_RADIOUS - 5) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 10) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + floatingObject.initializeMass(600) + floatingObject.initializeRadius(INITIAL_RADIOUS) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) - floatingObject.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', 1)' + floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - if (payload.node.savedPayload === undefined) { - // floatingObject.angleToParentToggle() - } - } - function level_3 () { - floatingObject.targetFriction = FRICTION - floatingObject.friction = INITIAL_FRICTION + if (payload.node.savedPayload === undefined) { + // floatingObject.angleToParentToggle() + } + } + function level_2() { + floatingObject.targetFriction = FRICTION + floatingObject.friction = INITIAL_FRICTION - floatingObject.initializeMass(150) - floatingObject.initializeRadius(INITIAL_RADIOUS - 10) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 20) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + floatingObject.initializeMass(300) + floatingObject.initializeRadius(INITIAL_RADIOUS - 5) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 10) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) - floatingObject.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 1)' + floatingObject.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', 1)' - if (payload.node.savedPayload === undefined) { - // floatingObject.angleToParentToggle() - } - } - function level_4 () { - floatingObject.targetFriction = FRICTION - floatingObject.friction = INITIAL_FRICTION + if (payload.node.savedPayload === undefined) { + // floatingObject.angleToParentToggle() + } + } + function level_3() { + floatingObject.targetFriction = FRICTION + floatingObject.friction = INITIAL_FRICTION - floatingObject.initializeMass(75) - floatingObject.initializeRadius(INITIAL_RADIOUS - 15) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 30) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + floatingObject.initializeMass(150) + floatingObject.initializeRadius(INITIAL_RADIOUS - 10) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 20) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) - floatingObject.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' + floatingObject.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 1)' - if (payload.node.savedPayload === undefined) { - // floatingObject.angleToParentToggle() - } - } - function level_5 () { - floatingObject.targetFriction = FRICTION - floatingObject.friction = INITIAL_FRICTION + if (payload.node.savedPayload === undefined) { + // floatingObject.angleToParentToggle() + } + } + function level_4() { + floatingObject.targetFriction = FRICTION + floatingObject.friction = INITIAL_FRICTION - floatingObject.initializeMass(50) - floatingObject.initializeRadius(INITIAL_RADIOUS - 20) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 40) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + floatingObject.initializeMass(75) + floatingObject.initializeRadius(INITIAL_RADIOUS - 15) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 30) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) - floatingObject.fillStyle = 'rgba(' + UI_COLOR.RED + ', 1)' - } - function level_6 () { - floatingObject.targetFriction = FRICTION - floatingObject.friction = INITIAL_FRICTION + floatingObject.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' - floatingObject.initializeMass(25) - floatingObject.initializeRadius(INITIAL_RADIOUS - 25) - floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) - floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 50) - floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + if (payload.node.savedPayload === undefined) { + // floatingObject.angleToParentToggle() + } + } + function level_5() { + floatingObject.targetFriction = FRICTION + floatingObject.friction = INITIAL_FRICTION - floatingObject.fillStyle = 'rgba(' + UI_COLOR.RED + ', 1)' + floatingObject.initializeMass(50) + floatingObject.initializeRadius(INITIAL_RADIOUS - 20) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 40) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + + floatingObject.fillStyle = 'rgba(' + UI_COLOR.RED + ', 1)' + } + function level_6() { + floatingObject.targetFriction = FRICTION + floatingObject.friction = INITIAL_FRICTION + + floatingObject.initializeMass(25) + floatingObject.initializeRadius(INITIAL_RADIOUS - 25) + floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) + floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 50) + floatingObject.initializeFontSize(INITIAL_FONT_SIZE) + + floatingObject.fillStyle = 'rgba(' + UI_COLOR.RED + ', 1)' + } + + floatingObject.labelStrokeStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' } - floatingObject.labelStrokeStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - } + function destroyUiObject(payload) { + if (payload === undefined) { return } + floatingLayer.removeFloatingObject(payload.floatingObject.handle) - function destroyUiObject (payload) { - if (payload === undefined) { return } - floatingLayer.removeFloatingObject(payload.floatingObject.handle) + payload.floatingObject.finalize() + payload.floatingObject = undefined - payload.floatingObject.finalize() - payload.floatingObject = undefined + payload.uiObject.finalize() + payload.uiObject = undefined - payload.uiObject.finalize() - payload.uiObject = undefined - - payload.referenceParent = undefined - payload.parent = undefined - payload.chainParent = undefined - payload.node.savedPayload = undefined - } + payload.referenceParent = undefined + payload.parent = undefined + payload.chainParent = undefined + payload.node.savedPayload = undefined + } } diff --git a/FloatingSpace/UiObjectTitle.js b/FloatingSpace/UiObjectTitle.js index 2a6215ac5..2e387ef81 100644 --- a/FloatingSpace/UiObjectTitle.js +++ b/FloatingSpace/UiObjectTitle.js @@ -1,358 +1,358 @@ -function newUiObjectTitle () { - const MODULE_NAME = 'UI Object Title' - const ERROR_LOG = true +function newUiObjectTitle() { + const MODULE_NAME = 'UI Object Title' + const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - fitFunction: undefined, - isVisibleFunction: undefined, - allwaysVisible: undefined, - editMode: undefined, - container: undefined, - payload: undefined, - isDefault: undefined, - enterEditMode: enterEditMode, - exitEditMode: exitEditMode, - physics: physics, - draw: draw, - getContainer: getContainer, - finalize: finalize, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.frame.radius = 0 - - let selfFocusEventSubscriptionId - let selfNotFocuskEventSubscriptionId - let selfMouseClickEventSubscriptionId - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.payload = undefined - thisObject.isVisibleFunction = undefined - thisObject.fitFunction = undefined - } - - function initialize (payload) { - thisObject.payload = payload - - thisObject.allwaysVisible = false // Default value - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.isTitleAllwaysVisible === true) { - thisObject.allwaysVisible = true - } + let thisObject = { + fitFunction: undefined, + isVisibleFunction: undefined, + allwaysVisible: undefined, + editMode: undefined, + container: undefined, + payload: undefined, + isDefault: undefined, + enterEditMode: enterEditMode, + exitEditMode: exitEditMode, + physics: physics, + draw: draw, + getContainer: getContainer, + finalize: finalize, + initialize: initialize } - selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) - selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) - selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.frame.radius = 0 - function getContainer (point) { - if (AT_FULL_SCREEN_MODE === true) { return } // Fullscreen mode does not allow INPUT elements + let selfFocusEventSubscriptionId + let selfNotFocuskEventSubscriptionId + let selfMouseClickEventSubscriptionId - let container + return thisObject - if (thisObject.editMode === true) { - if (point.x === VERY_LARGE_NUMBER) { - /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that - anyone can react. In our case, this object has an html input element that is not part of the canvas, so the event is - triggered. We compensate recognizing this coordinate and returning our container. */ - return thisObject.container - } + function finalize() { + thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.isVisibleFunction = undefined + thisObject.fitFunction = undefined } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - function physics () { - inheritancePhysics() - defaultPhysics() - } + function initialize(payload) { + thisObject.payload = payload - function defaultPhysics () { - if (thisObject.payload.title !== 'New ' + thisObject.payload.node.type && thisObject.payload.title !== 'My ' + thisObject.payload.node.type) { - thisObject.isDefault = false - } else { - thisObject.isDefault = true - } - } - - function inheritancePhysics () { - if (thisObject.payload.title === undefined) { return } - - /* It is possible to override the default title by setting the APP SCHEMA property 'title' */ - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition.title !== undefined) { - thisObject.payload.title = '' - thisObject.payload.node.name = '' - let separator = '' - for (let i = 0; i < nodeDefinition.title.length; i++) { - let titleReference = nodeDefinition.title[i] - switch (titleReference) { - case 'Use Reference Parent': { - let nodeToUse = thisObject.payload.node.payload.referenceParent - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title - thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + thisObject.allwaysVisible = false // Default value + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.isTitleAllwaysVisible === true) { + thisObject.allwaysVisible = true } - break - } - case 'Use Reference Grandparent': { - let nodeToUse = thisObject.payload.node.payload.referenceParent - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.referenceParent - if (nodeToUse !== undefined) { - thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title - thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name - } + } + + selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) + selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + } + + function getContainer(point) { + if (AT_FULL_SCREEN_MODE === true) { return } // Fullscreen mode does not allow INPUT elements + + let container + + if (thisObject.editMode === true) { + if (point.x === VERY_LARGE_NUMBER) { + /* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that + anyone can react. In our case, this object has an html input element that is not part of the canvas, so the event is + triggered. We compensate recognizing this coordinate and returning our container. */ + return thisObject.container } - break - } - case 'Use Reference Parent Parent': { - let nodeToUse = thisObject.payload.node.payload.referenceParent - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title - thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name - } - } - break - } - case 'Use Reference Parent Parent Parent': { - let nodeToUse = thisObject.payload.node.payload.referenceParent - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode.payload.parentNode - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title - thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function physics() { + inheritancePhysics() + defaultPhysics() + } + + function defaultPhysics() { + if (thisObject.payload.title !== 'New ' + thisObject.payload.node.type && thisObject.payload.title !== 'My ' + thisObject.payload.node.type) { + thisObject.isDefault = false + } else { + thisObject.isDefault = true + } + } + + function inheritancePhysics() { + if (thisObject.payload.title === undefined) { return } + + /* It is possible to override the default title by setting the APP SCHEMA property 'title' */ + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition.title !== undefined) { + thisObject.payload.title = '' + thisObject.payload.node.name = '' + let separator = '' + for (let i = 0; i < nodeDefinition.title.length; i++) { + let titleReference = nodeDefinition.title[i] + switch (titleReference) { + case 'Use Reference Parent': { + let nodeToUse = thisObject.payload.node.payload.referenceParent + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + break + } + case 'Use Reference Grandparent': { + let nodeToUse = thisObject.payload.node.payload.referenceParent + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.referenceParent + if (nodeToUse !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + } + break + } + case 'Use Reference Parent Parent': { + let nodeToUse = thisObject.payload.node.payload.referenceParent + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + } + break + } + case 'Use Reference Parent Parent Parent': { + let nodeToUse = thisObject.payload.node.payload.referenceParent + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode.payload.parentNode + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + } + } + break + } + case 'Use Reference Parent Parent Parent': { + let nodeToUse = thisObject.payload.node.payload.referenceParent + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode.payload.parentNode + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + } + } + break + } + default: { + if (titleReference.indexOf('Use Child @') === 0) { + let propertyName = titleReference.substring(titleReference.indexOf('@') + 1, titleReference.length) + let childNode = thisObject.payload.node[propertyName] + if (childNode === undefined) { break } + thisObject.payload.title = thisObject.payload.title + separator + childNode.name + thisObject.payload.node.name = thisObject.payload.node.name + separator + childNode.name + } + } } - } + separator = ' ' } - break - } - case 'Use Reference Parent Parent Parent': { - let nodeToUse = thisObject.payload.node.payload.referenceParent - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode.payload.parentNode - if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { - thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title - thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + + /* The name becomes the title. */ + if (thisObject.payload.node.name !== undefined) { + thisObject.payload.title = thisObject.payload.node.name + } + + let title = trimTitle(thisObject.payload.title) + + /* Here we set the dimensions and position of this object */ + const FRAME_HEIGHT = 25 + const Y_OFFSET = -20 + const FRAME_WIDTH = (title.length + 2) / 2 * thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO * 1.2 * 2 + thisObject.container.frame.position.x = 0 - FRAME_WIDTH / 2 + thisObject.container.frame.position.y = 0 - thisObject.container.frame.radius * 1 / 2 - thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO + Y_OFFSET - FRAME_HEIGHT + + thisObject.container.frame.width = FRAME_WIDTH + thisObject.container.frame.height = FRAME_HEIGHT + + if (thisObject.editMode === true) { + let inputPosition = { + x: 0, + y: 0 + CURRENT_TOP_MARGIN + Y_OFFSET + } + + inputPosition = thisObject.container.frame.frameThisPoint(inputPosition) + + if (inputPosition.y < CURRENT_TOP_MARGIN) { exitEditMode() } + + let inputDiv = document.getElementById('inputDiv') + inputDiv.style = 'position:absolute; top:' + inputPosition.y + 'px; left:' + inputPosition.x + 'px; z-index:1; ' + } + } + + function onFocus() { + thisObject.isOnFocus = true + } + + function onNotFocus() { + thisObject.isOnFocus = false + exitEditMode() + } + + function onMouseClick(event) { + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition.title !== undefined) { return } + + let checkPoint = { + x: 0, + y: 0 + } + checkPoint = thisObject.container.frame.frameThisPoint(checkPoint) + + if (thisObject.isVisibleFunction(checkPoint) === true) { + enterEditMode() + } + } + + function exitEditMode() { + if (thisObject.editMode === true) { + thisObject.editMode = false + let input = document.getElementById('input') + input.style.display = 'none' + if (input.value.length > 2) { + thisObject.payload.title = input.value + thisObject.payload.node.name = input.value + } + } + let inputDiv = document.getElementById('inputDiv') + inputDiv.style = 'position:absolute; top:' + '-100' + 'px; left:' + '-100' + 'px; z-index:1; ' + } + + function enterEditMode() { + const WIDTH = thisObject.container.frame.width + const HEIGHT = thisObject.container.frame.height + let fontSize = thisObject.payload.floatingObject.currentFontSize + + thisObject.editMode = true + let input = document.getElementById('input') + input.value = thisObject.payload.title + + let backgroundColor = '0, 0, 0' + if (thisObject.payload.uiObject.codeEditor !== undefined) { + if (thisObject.payload.uiObject.codeEditor.visible === true) { + backgroundColor = '204, 88, 53' + } + } + + input.style = 'resize: none; border: none; outline: none; box-shadow: none; overflow:hidden; font-family: Saira Condensed; font-size: ' + fontSize + 'px; background-color: rgb(' + backgroundColor + ');color:rgb(255, 255, 255); width: ' + WIDTH + 'px; height: ' + HEIGHT + 'px' + input.style.display = 'block' + input.focus() + } + + function draw() { + if (thisObject.isOnFocus === true || thisObject.allwaysVisible === true || thisObject.isDefault === false) { + if (thisObject.payload.uiObject.codeEditor !== undefined) { + if (thisObject.payload.uiObject.codeEditor.visible !== true) { + drawTitleBackground() } - } + } else { + drawTitleBackground() } - break - } - default: { - if (titleReference.indexOf('Use Child @') === 0) { - let propertyName = titleReference.substring(titleReference.indexOf('@') + 1, titleReference.length) - let childNode = thisObject.payload.node[propertyName] - if (childNode === undefined) { break } - thisObject.payload.title = thisObject.payload.title + separator + childNode.name - thisObject.payload.node.name = thisObject.payload.node.name + separator + childNode.name + + drawText() + } + } + + function drawTitleBackground() { + if (thisObject.editMode !== true) { + let params = { + cornerRadius: 3, + lineWidth: 0.1, + container: thisObject.container, + borderColor: UI_COLOR.BLACK, + backgroundColor: UI_COLOR.BLACK, + castShadow: false, + opacity: 0.25 } - } + + roundedCornersBackground(params) } - separator = ' ' - } } - /* The name becomes the title. */ - if (thisObject.payload.node.name !== undefined) { - thisObject.payload.title = thisObject.payload.node.name - } + function drawText() { + if (thisObject.editMode !== true) { + let radius = thisObject.container.frame.radius + let labelPoint + let fontSize = thisObject.payload.floatingObject.currentFontSize + let label - let title = trimTitle(thisObject.payload.title) + if (radius > 6 && (thisObject.isOnFocus === true || thisObject.allwaysVisible === true || thisObject.isDefault === false)) { + browserCanvasContext.strokeStyle = thisObject.payload.floatingObject.labelStrokeStyle - /* Here we set the dimensions and position of this object */ - const FRAME_HEIGHT = 25 - const Y_OFFSET = -20 - const FRAME_WIDTH = (title.length + 2) / 2 * thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO * 1.2 * 2 - thisObject.container.frame.position.x = 0 - FRAME_WIDTH / 2 - thisObject.container.frame.position.y = 0 - thisObject.container.frame.radius * 1 / 2 - thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO + Y_OFFSET - FRAME_HEIGHT + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - thisObject.container.frame.width = FRAME_WIDTH - thisObject.container.frame.height = FRAME_HEIGHT + label = thisObject.payload.title - if (thisObject.editMode === true) { - let inputPosition = { - x: 0, - y: 0 + CURRENT_TOP_MARGIN + Y_OFFSET - } + if (label !== undefined) { + label = trimTitle(label) - inputPosition = thisObject.container.frame.frameThisPoint(inputPosition) + labelPoint = { + x: 5, + y: thisObject.container.frame.height * 0.8 + } - if (inputPosition.y < CURRENT_TOP_MARGIN) { exitEditMode() } + labelPoint = thisObject.container.frame.frameThisPoint(labelPoint) - let inputDiv = document.getElementById('inputDiv') - inputDiv.style = 'position:absolute; top:' + inputPosition.y + 'px; left:' + inputPosition.x + 'px; z-index:1; ' - } - } + if (canvas.floatingSpace.inMapMode === true) { + labelPoint = canvas.floatingSpace.transformPointToMap(labelPoint) + labelPoint.x = labelPoint.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO + labelPoint.y = labelPoint.y - 35 - function onFocus () { - thisObject.isOnFocus = true - } + let nodeDefinition = getNodeDefinition(thisObject.payload.node) + if (nodeDefinition !== undefined) { + if (nodeDefinition.isHierarchyHead !== true) { + return + } + } + } - function onNotFocus () { - thisObject.isOnFocus = false - exitEditMode() - } - - function onMouseClick (event) { - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition.title !== undefined) { return } - - let checkPoint = { - x: 0, - y: 0 - } - checkPoint = thisObject.container.frame.frameThisPoint(checkPoint) - - if (thisObject.isVisibleFunction(checkPoint) === true) { - enterEditMode() - } - } - - function exitEditMode () { - if (thisObject.editMode === true) { - thisObject.editMode = false - let input = document.getElementById('input') - input.style.display = 'none' - if (input.value.length > 2) { - thisObject.payload.title = input.value - thisObject.payload.node.name = input.value - } - } - let inputDiv = document.getElementById('inputDiv') - inputDiv.style = 'position:absolute; top:' + '-100' + 'px; left:' + '-100' + 'px; z-index:1; ' - } - - function enterEditMode () { - const WIDTH = thisObject.container.frame.width - const HEIGHT = thisObject.container.frame.height - let fontSize = thisObject.payload.floatingObject.currentFontSize - - thisObject.editMode = true - let input = document.getElementById('input') - input.value = thisObject.payload.title - - let backgroundColor = '0, 0, 0' - if (thisObject.payload.uiObject.codeEditor !== undefined) { - if (thisObject.payload.uiObject.codeEditor.visible === true) { - backgroundColor = '204, 88, 53' - } - } - - input.style = 'resize: none; border: none; outline: none; box-shadow: none; overflow:hidden; font-family: Saira Condensed; font-size: ' + fontSize + 'px; background-color: rgb(' + backgroundColor + ');color:rgb(255, 255, 255); width: ' + WIDTH + 'px; height: ' + HEIGHT + 'px' - input.style.display = 'block' - input.focus() - } - - function draw () { - if (thisObject.isOnFocus === true || thisObject.allwaysVisible === true || thisObject.isDefault === false) { - if (thisObject.payload.uiObject.codeEditor !== undefined) { - if (thisObject.payload.uiObject.codeEditor.visible !== true) { - drawTitleBackground() - } - } else { - drawTitleBackground() - } - - drawText() - } - } - - function drawTitleBackground () { - if (thisObject.editMode !== true) { - let params = { - cornerRadius: 3, - lineWidth: 0.1, - container: thisObject.container, - borderColor: UI_COLOR.BLACK, - backgroundColor: UI_COLOR.BLACK, - castShadow: false, - opacity: 0.25 - } - - roundedCornersBackground(params) - } - } - - function drawText () { - if (thisObject.editMode !== true) { - let radius = thisObject.container.frame.radius - let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize - let label - - if (radius > 6 && (thisObject.isOnFocus === true || thisObject.allwaysVisible === true || thisObject.isDefault === false)) { - browserCanvasContext.strokeStyle = thisObject.payload.floatingObject.labelStrokeStyle - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - - label = thisObject.payload.title - - if (label !== undefined) { - label = trimTitle(label) - - labelPoint = { - x: 5, - y: thisObject.container.frame.height * 0.8 - } - - labelPoint = thisObject.container.frame.frameThisPoint(labelPoint) - - if (canvas.floatingSpace.inMapMode === true) { - labelPoint = canvas.floatingSpace.transformPointToMap(labelPoint) - labelPoint.x = labelPoint.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - labelPoint.y = labelPoint.y - 35 - - let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - if (nodeDefinition.isHierarchyHead !== true) { - return - } + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = thisObject.payload.floatingObject.labelStrokeStyle + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } } - } - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = thisObject.payload.floatingObject.labelStrokeStyle - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } - } } - } - function trimTitle (title) { - if (title === undefined) { return } - const MAX_LABEL_LENGTH = 50 - if (title.length > MAX_LABEL_LENGTH) { - title = title.substring(0, MAX_LABEL_LENGTH) + '...' + function trimTitle(title) { + if (title === undefined) { return } + const MAX_LABEL_LENGTH = 50 + if (title.length > MAX_LABEL_LENGTH) { + title = title.substring(0, MAX_LABEL_LENGTH) + '...' + } + return title } - return title - } } diff --git a/Frame.js b/Frame.js index 7e27a2242..2f2405134 100644 --- a/Frame.js +++ b/Frame.js @@ -1,537 +1,537 @@ -function newFrame () { - const PANEL_CORNERS_RADIUS = 5 - const TITLE_BAR_HEIGHT = 15 // this must be grater than radius +function newFrame() { + const PANEL_CORNERS_RADIUS = 5 + const TITLE_BAR_HEIGHT = 15 // this must be grater than radius - let thisObject = { - type: 'Rectangle', - containerName: '', // This is for debugging purposes only. - parentFrame: undefined, // Here we store the parent cointainer zoom object. - radius: 0, - offset: undefined, - position: undefined, - container: undefined, - width: browserCanvas.width, - height: browserCanvas.height, - getBodyHeight: getBodyHeight, - draw: draw, - fitIntoFrame: fitIntoFrame, - frameThisPoint: frameThisPoint, // This function changes the actual frame coordinate system to the screen coordinate system. - unframeThisPoint: unframeThisPoint, - isThisPointHere: isThisPointHere, // This function return true is the point received as parameter lives within this frame. - isThisScreenPointHere: isThisScreenPointHere, - isInViewPort: isInViewPort, - isCenterInViewPort: isCenterInViewPort, - initialize: initialize, - finalize: finalize - } - - return thisObject - - function finalize () { - thisObject.parentFrame = undefined - thisObject.position = undefined - thisObject.offset = undefined - } - - function initialize (pType) { - if (pType !== undefined) { thisObject.type = pType } - - thisObject.position = { - x: 0, - y: 0 + let thisObject = { + type: 'Rectangle', + containerName: '', // This is for debugging purposes only. + parentFrame: undefined, // Here we store the parent cointainer zoom object. + radius: 0, + offset: undefined, + position: undefined, + container: undefined, + width: browserCanvas.width, + height: browserCanvas.height, + getBodyHeight: getBodyHeight, + draw: draw, + fitIntoFrame: fitIntoFrame, + frameThisPoint: frameThisPoint, // This function changes the actual frame coordinate system to the screen coordinate system. + unframeThisPoint: unframeThisPoint, + isThisPointHere: isThisPointHere, // This function return true is the point received as parameter lives within this frame. + isThisScreenPointHere: isThisScreenPointHere, + isInViewPort: isInViewPort, + isCenterInViewPort: isCenterInViewPort, + initialize: initialize, + finalize: finalize } - thisObject.offset = { - x: 0, - y: 0 - } - } + return thisObject - function getBodyHeight () { - return thisObject.height - TITLE_BAR_HEIGHT - } - - function isInViewPort () { - /* This function is usefull to know if the object who has this frame is currently appearing at least in part at the canvas.chartingSpace.viewport */ - - point1 = { - x: 0, - y: 0 + function finalize() { + thisObject.parentFrame = undefined + thisObject.position = undefined + thisObject.offset = undefined } - point3 = { - x: thisObject.width, - y: thisObject.height + function initialize(pType) { + if (pType !== undefined) { thisObject.type = pType } + + thisObject.position = { + x: 0, + y: 0 + } + + thisObject.offset = { + x: 0, + y: 0 + } } - /* Now the transformations. */ - - point1 = transformThisPoint(point1, thisObject.container) - point3 = transformThisPoint(point3, thisObject.container) - - if (point1.x < canvas.chartingSpace.viewport.visibleArea.topRight.x && point1.y < canvas.chartingSpace.viewport.visibleArea.bottomRight.y && point3.x > canvas.chartingSpace.viewport.visibleArea.bottomLeft.x && point3.y > canvas.chartingSpace.viewport.visibleArea.topLeft.y) { - return true - } else { - return false - } - } - - function isCenterInViewPort () { - /* This function is usefull to know if the object who has this frame is currently appearing at least in part at the canvas.chartingSpace.viewport */ - - point1 = { - x: thisObject.width * 40 / 100, - y: thisObject.height * 40 / 100 + function getBodyHeight() { + return thisObject.height - TITLE_BAR_HEIGHT } - point3 = { - x: thisObject.width * 40 / 100, - y: thisObject.height * 40 / 100 - } + function isInViewPort() { + /* This function is usefull to know if the object who has this frame is currently appearing at least in part at the canvas.chartingSpace.viewport */ + + point1 = { + x: 0, + y: 0 + } + + point3 = { + x: thisObject.width, + y: thisObject.height + } /* Now the transformations. */ - point1 = transformThisPoint(point1, thisObject.container) - point3 = transformThisPoint(point3, thisObject.container) + point1 = transformThisPoint(point1, thisObject.container) + point3 = transformThisPoint(point3, thisObject.container) - if (point1.x < canvas.chartingSpace.viewport.visibleArea.topRight.x && point1.y < canvas.chartingSpace.viewport.visibleArea.bottomRight.y && point3.x > canvas.chartingSpace.viewport.visibleArea.bottomLeft.x && point3.y > canvas.chartingSpace.viewport.visibleArea.topLeft.y) { - return true - } else { - return false - } - } - - function frameThisPoint (point) { - /* We need not to modify the point received, so me make a copy of it. */ - - let checkPoint = { - x: point.x, - y: point.y + if (point1.x < canvas.chartingSpace.viewport.visibleArea.topRight.x && point1.y < canvas.chartingSpace.viewport.visibleArea.bottomRight.y && point3.x > canvas.chartingSpace.viewport.visibleArea.bottomLeft.x && point3.y > canvas.chartingSpace.viewport.visibleArea.topLeft.y) { + return true + } else { + return false + } } - let parentPoint = { - x: 0, - y: 0 + function isCenterInViewPort() { + /* This function is usefull to know if the object who has this frame is currently appearing at least in part at the canvas.chartingSpace.viewport */ + + point1 = { + x: thisObject.width * 40 / 100, + y: thisObject.height * 40 / 100 + } + + point3 = { + x: thisObject.width * 40 / 100, + y: thisObject.height * 40 / 100 + } + + /* Now the transformations. */ + + point1 = transformThisPoint(point1, thisObject.container) + point3 = transformThisPoint(point3, thisObject.container) + + if (point1.x < canvas.chartingSpace.viewport.visibleArea.topRight.x && point1.y < canvas.chartingSpace.viewport.visibleArea.bottomRight.y && point3.x > canvas.chartingSpace.viewport.visibleArea.bottomLeft.x && point3.y > canvas.chartingSpace.viewport.visibleArea.topLeft.y) { + return true + } else { + return false + } } - let returnPoint = { - x: 0, - y: 0 + function frameThisPoint(point) { + /* We need not to modify the point received, so me make a copy of it. */ + + let checkPoint = { + x: point.x, + y: point.y + } + + let parentPoint = { + x: 0, + y: 0 + } + + let returnPoint = { + x: 0, + y: 0 + } + + if (thisObject.parentFrame !== undefined) { + parentPoint = thisObject.parentFrame.frameThisPoint(checkPoint) + + returnPoint.x = parentPoint.x + thisObject.position.x + thisObject.offset.x + returnPoint.y = parentPoint.y + thisObject.position.y + thisObject.offset.y + } else { + returnPoint.x = checkPoint.x + thisObject.position.x + thisObject.offset.x + returnPoint.y = checkPoint.y + thisObject.position.y + thisObject.offset.y + } + + return returnPoint } - if (thisObject.parentFrame !== undefined) { - parentPoint = thisObject.parentFrame.frameThisPoint(checkPoint) + function unframeThisPoint(point) { + /* We need not to modify the point received, so me make a copy of it. */ - returnPoint.x = parentPoint.x + thisObject.position.x + thisObject.offset.x - returnPoint.y = parentPoint.y + thisObject.position.y + thisObject.offset.y - } else { - returnPoint.x = checkPoint.x + thisObject.position.x + thisObject.offset.x - returnPoint.y = checkPoint.y + thisObject.position.y + thisObject.offset.y + let checkPoint = { + x: point.x, + y: point.y + } + + let parentPoint = { + x: 0, + y: 0 + } + + let returnPoint = { + x: 0, + y: 0 + } + + if (thisObject.parentFrame !== undefined) { + parentPoint = thisObject.parentFrame.unframeThisPoint(checkPoint) + + returnPoint.x = parentPoint.x - thisObject.position.x + returnPoint.y = parentPoint.y - thisObject.position.y + } else { + returnPoint.x = checkPoint.x - thisObject.position.x + returnPoint.y = checkPoint.y - thisObject.position.y + } + + return returnPoint } - return returnPoint - } - - function unframeThisPoint (point) { - /* We need not to modify the point received, so me make a copy of it. */ - - let checkPoint = { - x: point.x, - y: point.y - } - - let parentPoint = { - x: 0, - y: 0 - } - - let returnPoint = { - x: 0, - y: 0 - } - - if (thisObject.parentFrame !== undefined) { - parentPoint = thisObject.parentFrame.unframeThisPoint(checkPoint) - - returnPoint.x = parentPoint.x - thisObject.position.x - returnPoint.y = parentPoint.y - thisObject.position.y - } else { - returnPoint.x = checkPoint.x - thisObject.position.x - returnPoint.y = checkPoint.y - thisObject.position.y - } - - return returnPoint - } - - function fitIntoFrame (point) { + function fitIntoFrame(point) { /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ - if (point.x > thisObject.width) { - point.x = thisObject.width + if (point.x > thisObject.width) { + point.x = thisObject.width + } + + if (point.x < 0) { + point.x = 0 + } + + if (point.y > thisObject.height) { + point.y = thisObject.height + } + + if (point.y < 0) { + point.y = 0 + } + + return point } - if (point.x < 0) { - point.x = 0 + function isThisPointHere(point, outsideViewPort, dontTransform, padding) { + // The second parameter is usefull when you want to check a point that you already know is outside the viewport. + // The padding is a distance to the borders of the container. Can be either negative (outside, to increase the cointainer size) or positive (inside to decrease the cointainer size) + + if (padding === undefined) { padding = 0 } + + /* We need not to modify the point received, so me make a copy of it. */ + let checkPoint = { + x: point.x, + y: point.y + } + + /* The point received is on the screen coordinates system, which already has zoom and displacement applied. We need to remove the zoom and displacement + in order to have the point on the containers coordinate system and be able to compare it with its dimmensions. */ + if (dontTransform === false || dontTransform === undefined) { + if (outsideViewPort === true) { + checkPoint = thisObject.container.frame.unframeThisPoint(checkPoint) + } else { + checkPoint = unTransformThisPoint(checkPoint, thisObject.container) + } + } + + /* Now we check if the resulting point is whin the current Frame. */ + if (isNaN(checkPoint.x) || isNaN(checkPoint.y)) { return false } + if (thisObject.type === 'Circle') { + let distance = Math.sqrt(Math.pow(thisObject.position.x - checkPoint.x, 2) + Math.pow(thisObject.position.y - checkPoint.y, 2)) + + if (distance < thisObject.radius) { + return true + } else { + return false + } + } + + if (thisObject.type === 'Rectangle') { + if (checkPoint.x < 0 + padding || checkPoint.y < 0 + padding || checkPoint.x > thisObject.width - padding || checkPoint.y > thisObject.height - padding) { + return false + } else { + return true + } + } } - if (point.y > thisObject.height) { - point.y = thisObject.height + function isThisScreenPointHere(point) { + let checkPoint = { + x: point.x, + y: point.y + } + + let thisPoint = { + x: thisObject.position.x, + y: thisObject.position.y + } + + if (thisObject.parentFrame !== undefined) { + thisPoint = thisObject.parentFrame.frameThisPoint(thisPoint) + } + + /* Now we check if the resulting point is whin the current Frame. */ + + if (thisObject.type === 'Circle') { + let distance = Math.sqrt(Math.pow(thisPoint.x - checkPoint.x, 2) + Math.pow(thisPoint.y - checkPoint.y, 2)) + + if (distance < thisObject.radius) { + return true + } else { + return false + } + } + + if (thisObject.type === 'Rectangle') { + if (checkPoint.x < 0 || checkPoint.y < 0 || checkPoint.x > thisObject.width || checkPoint.y > thisObject.height) { + return false + } else { + return true + } + } } - if (point.y < 0) { - point.y = 0 + function draw(drawGrid, drawBorders, drawBackground, fitFunction, style) { + if (drawBorders === true) { + borders(fitFunction, style) + } + + if (drawGrid === true) { + grid(fitFunction) + } + + if (drawBackground === true) { + background(fitFunction) + } } - return point - } + function background(fitFunction) { + let params = { + cornerRadius: 5, + lineWidth: 0.1, + opacity: 0.75, + container: thisObject.container, + borderColor: UI_COLOR.DARK, + backgroundColor: UI_COLOR.WHITE, + fitFunction: fitFunction + } - function isThisPointHere (point, outsideViewPort, dontTransform, padding) { - // The second parameter is usefull when you want to check a point that you already know is outside the viewport. - // The padding is a distance to the borders of the container. Can be either negative (outside, to increase the cointainer size) or positive (inside to decrease the cointainer size) + roundedCornersBackground(params) - if (padding === undefined) { padding = 0 } - - /* We need not to modify the point received, so me make a copy of it. */ - let checkPoint = { - x: point.x, - y: point.y - } - - /* The point received is on the screen coordinates system, which already has zoom and displacement applied. We need to remove the zoom and displacement - in order to have the point on the containers coordinate system and be able to compare it with its dimmensions. */ - if (dontTransform === false || dontTransform === undefined) { - if (outsideViewPort === true) { - checkPoint = thisObject.container.frame.unframeThisPoint(checkPoint) - } else { - checkPoint = unTransformThisPoint(checkPoint, thisObject.container) - } - } - - /* Now we check if the resulting point is whin the current Frame. */ - if (isNaN(checkPoint.x) || isNaN(checkPoint.y)) { return false } - if (thisObject.type === 'Circle') { - let distance = Math.sqrt(Math.pow(thisObject.position.x - checkPoint.x, 2) + Math.pow(thisObject.position.y - checkPoint.y, 2)) - - if (distance < thisObject.radius) { - return true - } else { - return false - } - } - - if (thisObject.type === 'Rectangle') { - if (checkPoint.x < 0 + padding || checkPoint.y < 0 + padding || checkPoint.x > thisObject.width - padding || checkPoint.y > thisObject.height - padding) { - return false - } else { - return true - } - } - } - - function isThisScreenPointHere (point) { - let checkPoint = { - x: point.x, - y: point.y - } - - let thisPoint = { - x: thisObject.position.x, - y: thisObject.position.y - } - - if (thisObject.parentFrame !== undefined) { - thisPoint = thisObject.parentFrame.frameThisPoint(thisPoint) - } - - /* Now we check if the resulting point is whin the current Frame. */ - - if (thisObject.type === 'Circle') { - let distance = Math.sqrt(Math.pow(thisPoint.x - checkPoint.x, 2) + Math.pow(thisPoint.y - checkPoint.y, 2)) - - if (distance < thisObject.radius) { - return true - } else { - return false - } - } - - if (thisObject.type === 'Rectangle') { - if (checkPoint.x < 0 || checkPoint.y < 0 || checkPoint.x > thisObject.width || checkPoint.y > thisObject.height) { - return false - } else { - return true - } - } - } - - function draw (drawGrid, drawBorders, drawBackground, fitFunction, style) { - if (drawBorders === true) { - borders(fitFunction, style) - } - - if (drawGrid === true) { - grid(fitFunction) - } - - if (drawBackground === true) { - background(fitFunction) - } - } - - function background (fitFunction) { - let params = { - cornerRadius: 5, - lineWidth: 0.1, - opacity: 0.75, - container: thisObject.container, - borderColor: UI_COLOR.DARK, - backgroundColor: UI_COLOR.WHITE, - fitFunction: fitFunction - } - - roundedCornersBackground(params) - - titleBarPoint1 = { - x: 0, - y: TITLE_BAR_HEIGHT - } - - titleBarPoint2 = { - x: thisObject.width, - y: TITLE_BAR_HEIGHT - } - - /* Now the transformations. */ - - titleBarPoint1 = frameThisPoint(titleBarPoint1) - titleBarPoint2 = frameThisPoint(titleBarPoint2) - - if (fitFunction !== undefined) { - titleBarPoint1 = fitFunction(titleBarPoint1) - titleBarPoint2 = fitFunction(titleBarPoint2) - } - - /* We paint the title bar now */ - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 1)' - browserCanvasContext.beginPath() - - browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y) - browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIUS, borderPoint1.y) - browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI) - browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIUS) - browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIUS, 1.5 * Math.PI, 2.0 * Math.PI) - browserCanvasContext.lineTo(titleBarPoint2.x, titleBarPoint2.y) - - browserCanvasContext.closePath() - browserCanvasContext.fill() - - browserCanvasContext.lineWidth = 0.1 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 0.75)' - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.stroke() - - /* print the title */ - - let labelPoint - let fontSize = 10 - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - - let label = thisObject.containerName - - let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO - let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2 - - labelPoint = { - x: thisObject.width / 2 - xOffset, - y: TITLE_BAR_HEIGHT - yOffset - } - - labelPoint = thisObject.frameThisPoint(labelPoint) - - if (fitFunction !== undefined) { - labelPoint = fitFunction(labelPoint) - } - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - - function borders (fitFunction, style) { - /* Lest get the important points of the drawing so as to apply the needed transformations. */ - - let point1 - let point2 - let point3 - let point4 - - point1 = { - x: 0, - y: 0 - } - - point2 = { - x: thisObject.width, - y: 0 - } - - point3 = { - x: thisObject.width, - y: thisObject.height - } - - point4 = { - x: 0, - y: thisObject.height - } - - /* Now the transformations. */ - point1 = transformThisPoint(point1, thisObject.container) - point2 = transformThisPoint(point2, thisObject.container) - point3 = transformThisPoint(point3, thisObject.container) - point4 = transformThisPoint(point4, thisObject.container) - - if (fitFunction !== undefined) { - point1 = fitFunction(point1) - point2 = fitFunction(point2) - point3 = fitFunction(point3) - point4 = fitFunction(point4) - } - - /* Lets start the drawing. */ - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.lineTo(point4.x, point4.y) - browserCanvasContext.lineTo(point1.x, point1.y) - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = 'rgba(' + style.color + ', ' + style.opacity + ')' - browserCanvasContext.lineWidth = style.lineWidth - browserCanvasContext.setLineDash(style.lineDash) - browserCanvasContext.stroke() - - browserCanvasContext.closePath() - } - - function grid (fitFunction, smallLines) { - if (smallLines === true) { - /* Small Lines */ - - let step = thisObject.width / 100 - - browserCanvasContext.beginPath() - - for (let i = 0; i < thisObject.width; i = i + step) { - for (let j = 0; j < thisObject.height; j = j + step) { - let point1 = { + titleBarPoint1 = { x: 0, - y: j - } + y: TITLE_BAR_HEIGHT + } - let point2 = { + titleBarPoint2 = { x: thisObject.width, - y: j - } - - point1 = transformThisPoint(point1, thisObject.container) - point2 = transformThisPoint(point2, thisObject.container) - - if (fitFunction !== undefined) { - point1 = fitFunction(point1) - point2 = fitFunction(point2) - } - - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) + y: TITLE_BAR_HEIGHT } - let point3 = { - x: thisObject.width, - y: thisObject.height + /* Now the transformations. */ + + titleBarPoint1 = frameThisPoint(titleBarPoint1) + titleBarPoint2 = frameThisPoint(titleBarPoint2) + + if (fitFunction !== undefined) { + titleBarPoint1 = fitFunction(titleBarPoint1) + titleBarPoint2 = fitFunction(titleBarPoint2) } - let point4 = { - x: 0, - y: thisObject.height + /* We paint the title bar now */ + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 1)' + browserCanvasContext.beginPath() + + browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y) + browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIUS, borderPoint1.y) + browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI) + browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIUS) + browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIUS, 1.5 * Math.PI, 2.0 * Math.PI) + browserCanvasContext.lineTo(titleBarPoint2.x, titleBarPoint2.y) + + browserCanvasContext.closePath() + browserCanvasContext.fill() + + browserCanvasContext.lineWidth = 0.1 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 0.75)' + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke() + + /* print the title */ + + let labelPoint + let fontSize = 10 + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + + let label = thisObject.containerName + + let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2 + + labelPoint = { + x: thisObject.width / 2 - xOffset, + y: TITLE_BAR_HEIGHT - yOffset } + labelPoint = thisObject.frameThisPoint(labelPoint) + + if (fitFunction !== undefined) { + labelPoint = fitFunction(labelPoint) + } + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + } + + function borders(fitFunction, style) { + /* Lest get the important points of the drawing so as to apply the needed transformations. */ + + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: thisObject.width, + y: 0 + } + + point3 = { + x: thisObject.width, + y: thisObject.height + } + + point4 = { + x: 0, + y: thisObject.height + } + + /* Now the transformations. */ + point1 = transformThisPoint(point1, thisObject.container) + point2 = transformThisPoint(point2, thisObject.container) point3 = transformThisPoint(point3, thisObject.container) point4 = transformThisPoint(point4, thisObject.container) if (fitFunction !== undefined) { - point3 = fitFunction(point3) - point4 = fitFunction(point4) - } - - browserCanvasContext.moveTo(point3.x, point3.y) - browserCanvasContext.lineTo(point4.x, point4.y) - } - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.1)' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.stroke() - } - - /* Main Lines */ - - let step = thisObject.width / 20 - - browserCanvasContext.beginPath() - - for (let i = 0; i < thisObject.width; i = i + step) { - for (let j = 0; j < thisObject.height; j = j + step) { - let point1 = { - x: 0, - y: j - } - - let point2 = { - x: thisObject.width, - y: j - } - - point1 = transformThisPoint(point1, thisObject.container) - point2 = transformThisPoint(point2, thisObject.container) - - if (fitFunction !== undefined) { - point1 = fitFunction(point1) - point2 = fitFunction(point2) + point1 = fitFunction(point1) + point2 = fitFunction(point2) + point3 = fitFunction(point3) + point4 = fitFunction(point4) } + /* Lets start the drawing. */ + browserCanvasContext.beginPath() browserCanvasContext.moveTo(point1.x, point1.y) browserCanvasContext.lineTo(point2.x, point2.y) - } + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() - let point3 = { - x: i, - y: 0 - } + browserCanvasContext.strokeStyle = 'rgba(' + style.color + ', ' + style.opacity + ')' + browserCanvasContext.lineWidth = style.lineWidth + browserCanvasContext.setLineDash(style.lineDash) + browserCanvasContext.stroke() - let point4 = { - x: i, - y: thisObject.height - } + browserCanvasContext.closePath() + } - point3 = transformThisPoint(point3, thisObject.container) - point4 = transformThisPoint(point4, thisObject.container) + function grid(fitFunction, smallLines) { + if (smallLines === true) { + /* Small Lines */ - if (fitFunction !== undefined) { - point3 = fitFunction(point3) - point4 = fitFunction(point4) - } + let step = thisObject.width / 100 - browserCanvasContext.moveTo(point3.x, point3.y) - browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.beginPath() + + for (let i = 0; i < thisObject.width; i = i + step) { + for (let j = 0; j < thisObject.height; j = j + step) { + let point1 = { + x: 0, + y: j + } + + let point2 = { + x: thisObject.width, + y: j + } + + point1 = transformThisPoint(point1, thisObject.container) + point2 = transformThisPoint(point2, thisObject.container) + + if (fitFunction !== undefined) { + point1 = fitFunction(point1) + point2 = fitFunction(point2) + } + + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + } + + let point3 = { + x: thisObject.width, + y: thisObject.height + } + + let point4 = { + x: 0, + y: thisObject.height + } + + point3 = transformThisPoint(point3, thisObject.container) + point4 = transformThisPoint(point4, thisObject.container) + + if (fitFunction !== undefined) { + point3 = fitFunction(point3) + point4 = fitFunction(point4) + } + + browserCanvasContext.moveTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + } + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.1)' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke() + } + + /* Main Lines */ + + let step = thisObject.width / 20 + + browserCanvasContext.beginPath() + + for (let i = 0; i < thisObject.width; i = i + step) { + for (let j = 0; j < thisObject.height; j = j + step) { + let point1 = { + x: 0, + y: j + } + + let point2 = { + x: thisObject.width, + y: j + } + + point1 = transformThisPoint(point1, thisObject.container) + point2 = transformThisPoint(point2, thisObject.container) + + if (fitFunction !== undefined) { + point1 = fitFunction(point1) + point2 = fitFunction(point2) + } + + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + } + + let point3 = { + x: i, + y: 0 + } + + let point4 = { + x: i, + y: thisObject.height + } + + point3 = transformThisPoint(point3, thisObject.container) + point4 = transformThisPoint(point4, thisObject.container) + + if (fitFunction !== undefined) { + point3 = fitFunction(point3) + point4 = fitFunction(point4) + } + + browserCanvasContext.moveTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + } + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(100, 100, 100, 0.2)' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke() } - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(100, 100, 100, 0.2)' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.stroke() - } } diff --git a/Globals.js b/Globals.js index f47174216..88ede4643 100644 --- a/Globals.js +++ b/Globals.js @@ -1,5 +1,5 @@ - /* User Interface Colors */ +/* User Interface Colors */ const CANVAS_APP_NAME = 'Canvas App' @@ -49,36 +49,36 @@ let FONT_ASPECT_RATIO = 0.32; let ANIMATION_FRAME_PER_SECONDS const GET_CONTAINER_PURPOSE = { - MOUSE_OVER: 1, - MOUSE_WHEEL: 2, - MOUSE_CLICK: 3, - DRAGGING: 4 + MOUSE_OVER: 1, + MOUSE_WHEEL: 2, + MOUSE_CLICK: 3, + DRAGGING: 4 } const ANGLE_TO_PARENT = { - NOT_FIXED: 0, - RANGE_360: 1, - RANGE_180: 2, - RANGE_90: 3, - RANGE_45: 4 + NOT_FIXED: 0, + RANGE_360: 1, + RANGE_180: 2, + RANGE_90: 3, + RANGE_45: 4 } const DISTANCE_TO_PARENT = { - NOT_FIXED: 0, - PARENT_025X: 1, - PARENT_050X: 2, - PARENT_100X: 3, - PARENT_150X: 4, - PARENT_200X: 5 + NOT_FIXED: 0, + PARENT_025X: 1, + PARENT_050X: 2, + PARENT_100X: 3, + PARENT_150X: 4, + PARENT_200X: 5 } const ARRANGEMENT_STYLE = { - CONCAVE: 0, - CONVEX: 1, - VERTICAL_RIGHT: 2, - VERTICAL_LEFT: 3, - HORIZONTAL_BOTTOM: 4, - HORIZONTAL_TOP: 5 + CONCAVE: 0, + CONVEX: 1, + VERTICAL_RIGHT: 2, + VERTICAL_LEFT: 3, + HORIZONTAL_BOTTOM: 4, + HORIZONTAL_TOP: 5 } /* User Interface Panels */ @@ -138,11 +138,11 @@ let LOGGED_IN_USER_LOCAL_STORAGE_KEY let LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY if (testUser !== null) { - LOGGED_IN_USER_LOCAL_STORAGE_KEY = "test_user" - LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY = "test_access_token" + LOGGED_IN_USER_LOCAL_STORAGE_KEY = "test_user" + LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY = "test_access_token" } else { - LOGGED_IN_USER_LOCAL_STORAGE_KEY = "user" - LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY = "access_token" + LOGGED_IN_USER_LOCAL_STORAGE_KEY = "user" + LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY = "access_token" } const MAX_DEFAULT_RATE_SCALE_VALUE = 35000; // This is needed to know the scale of the market time line. @@ -222,7 +222,7 @@ const TIME_MACHINE_WIDTH = 8; const TIME_MACHINE_HEIGHT = 8; let mediaRecorder // to downloadText canvas animation as a mediaRecorder -let marketPanoramaCanvas +let marketPanoramaCanvas let ARE_WE_RECORDING_A_VIDEO = false let ARE_WE_RECORDING_A_MARKET_PANORAMA = false let PANORAMA_WAS_PANNED = false diff --git a/Panels/Layer.js b/Panels/Layer.js index 8d4d16611..180378e5d 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -1,648 +1,648 @@ function newLayer() { - const MODULE_NAME = 'Layer' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + const MODULE_NAME = 'Layer' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - container: undefined, - status: LAYER_STATUS.OFF, - fitFunction: undefined, - payload: undefined, - definition: undefined, - panels: undefined, - baseAsset: undefined, - quotedAsset: undefined, - market: undefined, - exchange: undefined, - plotterModule: undefined, - exchangeIcon: undefined, - plotterTypeIcon: undefined, - baseAssetIcon: undefined, - quotedAssetIcon: undefined, - networkNode: undefined, - checkStatusAtShutDown: checkStatusAtShutDown, - physics: physics, - draw: draw, - turnOff: turnOff, - turnOn: turnOn, - setDatetime: setDatetime, - setTimeFrame: setTimeFrame, - onMarketFileLoaded: onMarketFileLoaded, - onDailyFileLoaded: onDailyFileLoaded, - onSingleFileLoaded: onSingleFileLoaded, - onFileSequenceLoaded: onFileSequenceLoaded, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } - - let LOADING_FILL_STYLE = 'rgba(234, 143, 23, @Opacity)' - let LOADED_FILL_STYLE = 'rgba(45, 232, 28, @Opacity)' - let UNLOADED_FILL_STYLE = 'rgba(226, 226, 226, @Opacity)' - - let LOADING_STROKE_STYLE = 'rgba(234, 143, 23, @Opacity)' - let LOADED_STROKE_STYLE = 'rgba(45, 232, 28, @Opacity)' - let UNLOADED_STROKE_STYLE = 'rgba(226, 226, 226, @Opacity)' - - let marketFileProgressBar = { - value: 0, - animatedValue: 0, - fillStyle: UNLOADED_FILL_STYLE, - strokeStyle: UNLOADED_STROKE_STYLE, - opacity: 0.00 - } - - let dailyFileProgressBar = { - value: 0, - animatedValue: 0, - fillStyle: UNLOADED_FILL_STYLE, - strokeStyle: UNLOADED_STROKE_STYLE, - opacity: 0.00 - } - - let singleFileProgressBar = { - value: 0, - animatedValue: 0, - fillStyle: UNLOADED_FILL_STYLE, - strokeStyle: UNLOADED_STROKE_STYLE, - opacity: 0.00 - } - - let fileSequenceProgressBar = { - value: 0, - animatedValue: 0, - fillStyle: UNLOADED_FILL_STYLE, - strokeStyle: UNLOADED_STROKE_STYLE, - opacity: 0.00 - } - - let timeFrame = INITIAL_TIME_PERIOD - let datetime = NEW_SESSION_INITIAL_DATE - - /* Add an Event Handler */ - - thisObject.eventHandler = newEventHandler() - let imagesLoaded = 0 - let onMouseClickEventSuscriptionId - let panelsVisibleButton - - return thisObject - - function finalize() { - thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) - - thisObject.container.finalize() - thisObject.eventHandler.finalize() - thisObject.container = undefined - thisObject.eventHandler = undefined - thisObject.status = undefined - thisObject.fitFunction = undefined - thisObject.payload = undefined - thisObject.definition = undefined - thisObject.panels = undefined - - timeFrame = undefined - datetime = undefined - - LOADING_FILL_STYLE = undefined - LOADED_FILL_STYLE = undefined - UNLOADED_FILL_STYLE = undefined - - LOADING_STROKE_STYLE = undefined - LOADED_STROKE_STYLE = undefined - UNLOADED_STROKE_STYLE = undefined - - marketFileProgressBar = undefined - dailyFileProgressBar = undefined - singleFileProgressBar = undefined - fileSequenceProgressBar = undefined - - panelsVisibleButton = undefined - - thisObject.baseAsset = undefined - thisObject.quotedAsset = undefined - thisObject.market = undefined - thisObject.exchange = undefined - thisObject.plotterModule = undefined - thisObject.exchangeIcon = undefined - thisObject.plotterTypeIcon = undefined - thisObject.baseAssetIcon = undefined - thisObject.quotedAssetIcon = undefined - thisObject.networkNode = undefined - } - - function initialize(callBackFunction) { - /* Create this objects continer */ - try { - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME + ' ' + thisObject.payload.node.id) - thisObject.container.isDraggeable = false - thisObject.container.isClickeable = true - - /* Lets set the basic dimensions of this thisObject. */ - let position = { - x: 0, - y: 0 - } - - thisObject.container.frame.position = position - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL - thisObject.container.frame.height = 70 - - let functionLibraryProtocolNode = newProtocolNode() - let lightingPath = - '->Layer->' + - 'Data Product->Single Market Data->Exchange Data Products->' + - 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + - 'Data Storage->Network Node->' + - 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + - 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + - 'Market->Market Base Asset->Asset->' + - 'Market Quoted Asset->Asset->' + - 'Exchange Markets->Crypto Exchange->' + - 'Product Definition->' + - 'Sensor Bot->Indicator Bot->Trading Bot->' + - 'Data Mine->' + - 'Dataset Definition->' + - 'Record Definition->Record Property->Formula->' + - 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + - 'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + - 'Plotter Module->Plotter->' + - 'Shapes->' + - 'Chart Points->Point->Point Formula->' + - 'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' + - 'Polygon Border->Style->Style Condition->Style->' + - 'Polygon Vertex->Point->' + - 'Image->Image Condition->Image Position->Point->' + - 'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' + - 'Plotter Panel->Javascript Code->Panel Data->Data Formula->' + - 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' - thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) - - /* Here we validate that we have all the needed information */ - if (thisObject.definition.referenceParent === undefined) { return } // Data Product - if (thisObject.definition.referenceParent.parentNode === undefined) { return } // Single Market Data - if (thisObject.definition.referenceParent.parentNode.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode === undefined) { return } - - /* Lets listen to our own events to react when we have a Mouse Click */ - onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - - /* Get ready to draw this layer */ - thisObject.baseAsset = thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent - thisObject.quotedAsset = thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent - thisObject.market = thisObject.baseAsset.config.codeName + '/' + thisObject.quotedAsset.config.codeName - thisObject.exchange = thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode - - /* Some basic validations. */ - if (thisObject.definition.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.type + ' ' + thisObject.definition.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - if (thisObject.definition.referenceParent.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.type + ' ' + thisObject.definition.referenceParent.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - if (thisObject.definition.referenceParent.referenceParent.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.referenceParent.type + ' ' + thisObject.definition.referenceParent.referenceParent.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - thisObject.plotterModule = thisObject.definition.referenceParent.referenceParent.referenceParent - thisObject.exchangeIcon = getIcon(thisObject.exchange) - - if (thisObject.plotterModule.config.icon !== undefined) { - thisObject.plotterTypeIcon = canvas.designSpace.iconCollection.get(thisObject.plotterModule.config.icon) - } - - thisObject.baseAssetIcon = getIcon(thisObject.baseAsset) - thisObject.quotedAssetIcon = getIcon(thisObject.quotedAsset) - - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.type === 'Data Storage') { - thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode - } else { - thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode - } - - function getIcon(node) { - let nodeDefinition = getNodeDefinition(node) - let iconName - if (nodeDefinition.alternativeIcons !== undefined) { - for (let i = 0; i < nodeDefinition.alternativeIcons.length; i++) { - alternativeIcon = nodeDefinition.alternativeIcons[i] - if (alternativeIcon.codeName === node.config.codeName) { - iconName = alternativeIcon.iconName - } - } - } - if (iconName !== undefined) { - icon = canvas.designSpace.iconCollection.get(iconName) - } else { - icon = canvas.designSpace.iconCollection.get(nodeDefinition.icon) - } - return icon - } - - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } + let thisObject = { + container: undefined, + status: LAYER_STATUS.OFF, + fitFunction: undefined, + payload: undefined, + definition: undefined, + panels: undefined, + baseAsset: undefined, + quotedAsset: undefined, + market: undefined, + exchange: undefined, + plotterModule: undefined, + exchangeIcon: undefined, + plotterTypeIcon: undefined, + baseAssetIcon: undefined, + quotedAssetIcon: undefined, + networkNode: undefined, + checkStatusAtShutDown: checkStatusAtShutDown, + physics: physics, + draw: draw, + turnOff: turnOff, + turnOn: turnOn, + setDatetime: setDatetime, + setTimeFrame: setTimeFrame, + onMarketFileLoaded: onMarketFileLoaded, + onDailyFileLoaded: onDailyFileLoaded, + onSingleFileLoaded: onSingleFileLoaded, + onFileSequenceLoaded: onFileSequenceLoaded, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize } - } - function checkStatusAtShutDown() { - /* Mechanism to recover a layer that was left loading the last time the browser was shut dowm. */ - let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status') - if (storedValue !== undefined) { - if (storedValue === LAYER_STATUS.LOADING) { - resetProgressBars() - changeStatusTo(LAYER_STATUS.LOADING) - } + let LOADING_FILL_STYLE = 'rgba(234, 143, 23, @Opacity)' + let LOADED_FILL_STYLE = 'rgba(45, 232, 28, @Opacity)' + let UNLOADED_FILL_STYLE = 'rgba(226, 226, 226, @Opacity)' + + let LOADING_STROKE_STYLE = 'rgba(234, 143, 23, @Opacity)' + let LOADED_STROKE_STYLE = 'rgba(45, 232, 28, @Opacity)' + let UNLOADED_STROKE_STYLE = 'rgba(226, 226, 226, @Opacity)' + + let marketFileProgressBar = { + value: 0, + animatedValue: 0, + fillStyle: UNLOADED_FILL_STYLE, + strokeStyle: UNLOADED_STROKE_STYLE, + opacity: 0.00 } - } - function getContainer(point) { - if (panelsVisibleButton !== undefined) { - let container = panelsVisibleButton.getContainer(point) - if (container !== undefined) { - return container - } + let dailyFileProgressBar = { + value: 0, + animatedValue: 0, + fillStyle: UNLOADED_FILL_STYLE, + strokeStyle: UNLOADED_STROKE_STYLE, + opacity: 0.00 } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container + + let singleFileProgressBar = { + value: 0, + animatedValue: 0, + fillStyle: UNLOADED_FILL_STYLE, + strokeStyle: UNLOADED_STROKE_STYLE, + opacity: 0.00 } - } - function setDatetime(pDatetime) { - /* - When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and - get ready to receive events on files loaded. - */ - let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) - let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS) - - datetime = pDatetime - - if (currentDate !== newDate) { - if (timeFrame <= _1_HOUR_IN_MILISECONDS) { - dailyFileProgressBar.animatedValue = 0 - } + let fileSequenceProgressBar = { + value: 0, + animatedValue: 0, + fillStyle: UNLOADED_FILL_STYLE, + strokeStyle: UNLOADED_STROKE_STYLE, + opacity: 0.00 } - } - function setTimeFrame(pTimeFrame) { - /* - When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and - get ready to receive events on files loaded. - */ - if (timeFrame !== pTimeFrame) { - timeFrame = pTimeFrame + let timeFrame = INITIAL_TIME_PERIOD + let datetime = NEW_SESSION_INITIAL_DATE - if (timeFrame <= _1_HOUR_IN_MILISECONDS) { - dailyFileProgressBar.animatedValue = 0 - } + /* Add an Event Handler */ + + thisObject.eventHandler = newEventHandler() + let imagesLoaded = 0 + let onMouseClickEventSuscriptionId + let panelsVisibleButton + + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) + + thisObject.container.finalize() + thisObject.eventHandler.finalize() + thisObject.container = undefined + thisObject.eventHandler = undefined + thisObject.status = undefined + thisObject.fitFunction = undefined + thisObject.payload = undefined + thisObject.definition = undefined + thisObject.panels = undefined + + timeFrame = undefined + datetime = undefined + + LOADING_FILL_STYLE = undefined + LOADED_FILL_STYLE = undefined + UNLOADED_FILL_STYLE = undefined + + LOADING_STROKE_STYLE = undefined + LOADED_STROKE_STYLE = undefined + UNLOADED_STROKE_STYLE = undefined + + marketFileProgressBar = undefined + dailyFileProgressBar = undefined + singleFileProgressBar = undefined + fileSequenceProgressBar = undefined + + panelsVisibleButton = undefined + + thisObject.baseAsset = undefined + thisObject.quotedAsset = undefined + thisObject.market = undefined + thisObject.exchange = undefined + thisObject.plotterModule = undefined + thisObject.exchangeIcon = undefined + thisObject.plotterTypeIcon = undefined + thisObject.baseAssetIcon = undefined + thisObject.quotedAssetIcon = undefined + thisObject.networkNode = undefined } - } - function onMarketFileLoaded(event) { - if (event.totalValue === 0) { - marketFileProgressBar.value = 100 - return - } - marketFileProgressBar.value = Math.trunc((event.currentValue + event.filesNotLoaded) * 100 / event.totalValue) - marketFileProgressBar.fillStyle = LOADING_FILL_STYLE - marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE + function initialize(callBackFunction) { + /* Create this objects continer */ + try { + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME + ' ' + thisObject.payload.node.id) + thisObject.container.isDraggeable = false + thisObject.container.isClickeable = true - if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100 } - } - - function onDailyFileLoaded(event) { - if (event.totalValue === 0) { - dailyFileProgressBar.value = 100 - return - } - dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) - dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE - dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE - - if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100 } - } - - function onSingleFileLoaded(event) { - if (event.totalValue === 0) { - singleFileProgressBar.value = 100 - return - } - singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) - singleFileProgressBar.fillStyle = LOADING_FILL_STYLE - singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE - - if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100 } - } - - function onFileSequenceLoaded(event) { - if (event.totalValue === 0) { - fileSequenceProgressBar.value = 100 - return - } - fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) - fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE - fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE - - if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100 } - } - - function turnOff() { - if (thisObject.status !== LAYER_STATUS.OFF) { - resetProgressBars() - changeStatusTo(LAYER_STATUS.OFF) - } - } - - function turnOn() { - if (thisObject.status === LAYER_STATUS.OFF) { - resetProgressBars() - changeStatusTo(LAYER_STATUS.LOADING) - } - } - - function onMouseClick(event) { - switch (thisObject.status) { - case LAYER_STATUS.ON: - resetProgressBars() - changeStatusTo(LAYER_STATUS.OFF) - break - case LAYER_STATUS.OFF: - resetProgressBars() - changeStatusTo(LAYER_STATUS.LOADING) - break - case LAYER_STATUS.LOADING: - changeStatusTo(LAYER_STATUS.OFF) - break - } - } - - function resetProgressBars() { - marketFileProgressBar.animatedValue = 0 - marketFileProgressBar.value = 0 - marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE - marketFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE - - dailyFileProgressBar.animatedValue = 0 - dailyFileProgressBar.value = 0 - dailyFileProgressBar.fillStyle = UNLOADED_FILL_STYLE - dailyFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE - - singleFileProgressBar.animatedValue = 0 - singleFileProgressBar.value = 0 - singleFileProgressBar.fillStyle = UNLOADED_FILL_STYLE - singleFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE - - fileSequenceProgressBar.animatedValue = 0 - fileSequenceProgressBar.value = 0 - fileSequenceProgressBar.fillStyle = UNLOADED_FILL_STYLE - fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE - } - - function physics() { - statusPhysics() - childrenPhysics() - } - - function childrenPhysics() { - /* Panels Visible Button Setup */ - if (thisObject.status === LAYER_STATUS.ON) { - if (panelsVisibleButton === undefined) { - if (thisObject.panels !== undefined) { - if (thisObject.panels.length > 0) { - panelsVisibleButton = newPanelsVisibleButton() - - let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'showPanels') - if (storedValue !== undefined) { - if (storedValue === true || storedValue === false) { - panelsVisibleButton.showPanels = storedValue - } + /* Lets set the basic dimensions of this thisObject. */ + let position = { + x: 0, + y: 0 } - panelsVisibleButton.initialize(thisObject.panels) - panelsVisibleButton.container.connectToParent(thisObject.container) - } + thisObject.container.frame.position = position + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL + thisObject.container.frame.height = 70 + + let functionLibraryProtocolNode = newProtocolNode() + let lightingPath = + '->Layer->' + + 'Data Product->Single Market Data->Exchange Data Products->' + + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + + 'Data Storage->Network Node->' + + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + + 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + + 'Market->Market Base Asset->Asset->' + + 'Market Quoted Asset->Asset->' + + 'Exchange Markets->Crypto Exchange->' + + 'Product Definition->' + + 'Sensor Bot->Indicator Bot->Trading Bot->' + + 'Data Mine->' + + 'Dataset Definition->' + + 'Record Definition->Record Property->Formula->' + + 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + + 'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + + 'Plotter Module->Plotter->' + + 'Shapes->' + + 'Chart Points->Point->Point Formula->' + + 'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' + + 'Polygon Border->Style->Style Condition->Style->' + + 'Polygon Vertex->Point->' + + 'Image->Image Condition->Image Position->Point->' + + 'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' + + 'Plotter Panel->Javascript Code->Panel Data->Data Formula->' + + 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' + thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) + + /* Here we validate that we have all the needed information */ + if (thisObject.definition.referenceParent === undefined) { return } // Data Product + if (thisObject.definition.referenceParent.parentNode === undefined) { return } // Single Market Data + if (thisObject.definition.referenceParent.parentNode.referenceParent === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent === undefined) { return } + if (thisObject.definition.referenceParent.referenceParent === undefined) { return } + if (thisObject.definition.referenceParent.referenceParent.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.referenceParent.parentNode.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return } + if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode === undefined) { return } + + /* Lets listen to our own events to react when we have a Mouse Click */ + onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + + /* Get ready to draw this layer */ + thisObject.baseAsset = thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent + thisObject.quotedAsset = thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent + thisObject.market = thisObject.baseAsset.config.codeName + '/' + thisObject.quotedAsset.config.codeName + thisObject.exchange = thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode + + /* Some basic validations. */ + if (thisObject.definition.referenceParent === undefined) { + console.log('[WARN] Could not start plotter because ' + thisObject.definition.type + ' ' + thisObject.definition.name + ' does not have a Reference Parent.') + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + if (thisObject.definition.referenceParent.referenceParent === undefined) { + console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.type + ' ' + thisObject.definition.referenceParent.name + ' does not have a Reference Parent.') + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + if (thisObject.definition.referenceParent.referenceParent.referenceParent === undefined) { + console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.referenceParent.type + ' ' + thisObject.definition.referenceParent.referenceParent.name + ' does not have a Reference Parent.') + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + thisObject.plotterModule = thisObject.definition.referenceParent.referenceParent.referenceParent + thisObject.exchangeIcon = getIcon(thisObject.exchange) + + if (thisObject.plotterModule.config.icon !== undefined) { + thisObject.plotterTypeIcon = canvas.designSpace.iconCollection.get(thisObject.plotterModule.config.icon) + } + + thisObject.baseAssetIcon = getIcon(thisObject.baseAsset) + thisObject.quotedAssetIcon = getIcon(thisObject.quotedAsset) + + if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.type === 'Data Storage') { + thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode + } else { + thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode + } + + function getIcon(node) { + let nodeDefinition = getNodeDefinition(node) + let iconName + if (nodeDefinition.alternativeIcons !== undefined) { + for (let i = 0; i < nodeDefinition.alternativeIcons.length; i++) { + alternativeIcon = nodeDefinition.alternativeIcons[i] + if (alternativeIcon.codeName === node.config.codeName) { + iconName = alternativeIcon.iconName + } + } + } + if (iconName !== undefined) { + icon = canvas.designSpace.iconCollection.get(iconName) + } else { + icon = canvas.designSpace.iconCollection.get(nodeDefinition.icon) + } + return icon + } + + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } } - } else { - savePropertyAtNodeConfig(thisObject.payload, 'showPanels', panelsVisibleButton.showPanels) - } } - } - function statusPhysics() { - /* We retrieve the stored status at the config. */ - try { - let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status') + function checkStatusAtShutDown() { + /* Mechanism to recover a layer that was left loading the last time the browser was shut dowm. */ + let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status') + if (storedValue !== undefined) { + if (storedValue === LAYER_STATUS.LOADING) { + resetProgressBars() + changeStatusTo(LAYER_STATUS.LOADING) + } + } + } - if (storedValue !== undefined) { - if (storedValue !== thisObject.status) { - if (storedValue === LAYER_STATUS.ON) { - resetProgressBars() - changeStatusTo(LAYER_STATUS.LOADING) - } - if (storedValue === LAYER_STATUS.OFF) { + function getContainer(point) { + if (panelsVisibleButton !== undefined) { + let container = panelsVisibleButton.getContainer(point) + if (container !== undefined) { + return container + } + } + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } + } + + function setDatetime(pDatetime) { + /* + When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and + get ready to receive events on files loaded. + */ + let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) + let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS) + + datetime = pDatetime + + if (currentDate !== newDate) { + if (timeFrame <= _1_HOUR_IN_MILISECONDS) { + dailyFileProgressBar.animatedValue = 0 + } + } + } + + function setTimeFrame(pTimeFrame) { + /* + When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and + get ready to receive events on files loaded. + */ + if (timeFrame !== pTimeFrame) { + timeFrame = pTimeFrame + + if (timeFrame <= _1_HOUR_IN_MILISECONDS) { + dailyFileProgressBar.animatedValue = 0 + } + } + } + + function onMarketFileLoaded(event) { + if (event.totalValue === 0) { + marketFileProgressBar.value = 100 + return + } + marketFileProgressBar.value = Math.trunc((event.currentValue + event.filesNotLoaded) * 100 / event.totalValue) + marketFileProgressBar.fillStyle = LOADING_FILL_STYLE + marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE + + if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100 } + } + + function onDailyFileLoaded(event) { + if (event.totalValue === 0) { + dailyFileProgressBar.value = 100 + return + } + dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) + dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE + dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE + + if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100 } + } + + function onSingleFileLoaded(event) { + if (event.totalValue === 0) { + singleFileProgressBar.value = 100 + return + } + singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) + singleFileProgressBar.fillStyle = LOADING_FILL_STYLE + singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE + + if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100 } + } + + function onFileSequenceLoaded(event) { + if (event.totalValue === 0) { + fileSequenceProgressBar.value = 100 + return + } + fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue) + fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE + fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE + + if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100 } + } + + function turnOff() { + if (thisObject.status !== LAYER_STATUS.OFF) { resetProgressBars() changeStatusTo(LAYER_STATUS.OFF) - } } - } else { - resetProgressBars() - changeStatusTo(LAYER_STATUS.OFF) - } - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. } - /* Check when the loading finishes */ - if ( - thisObject.status === LAYER_STATUS.LOADING && - marketFileProgressBar.value === 100 && - dailyFileProgressBar.value === 100 - ) { - changeStatusTo(LAYER_STATUS.ON) + function turnOn() { + if (thisObject.status === LAYER_STATUS.OFF) { + resetProgressBars() + changeStatusTo(LAYER_STATUS.LOADING) + } } - } - function changeStatusTo(newStatus) { - if (thisObject.status !== newStatus) { - thisObject.status = newStatus + function onMouseClick(event) { + switch (thisObject.status) { + case LAYER_STATUS.ON: + resetProgressBars() + changeStatusTo(LAYER_STATUS.OFF) + break + case LAYER_STATUS.OFF: + resetProgressBars() + changeStatusTo(LAYER_STATUS.LOADING) + break + case LAYER_STATUS.LOADING: + changeStatusTo(LAYER_STATUS.OFF) + break + } + } - if (thisObject.status === LAYER_STATUS.OFF) { + function resetProgressBars() { + marketFileProgressBar.animatedValue = 0 + marketFileProgressBar.value = 0 + marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE + marketFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE + + dailyFileProgressBar.animatedValue = 0 + dailyFileProgressBar.value = 0 + dailyFileProgressBar.fillStyle = UNLOADED_FILL_STYLE + dailyFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE + + singleFileProgressBar.animatedValue = 0 + singleFileProgressBar.value = 0 + singleFileProgressBar.fillStyle = UNLOADED_FILL_STYLE + singleFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE + + fileSequenceProgressBar.animatedValue = 0 + fileSequenceProgressBar.value = 0 + fileSequenceProgressBar.fillStyle = UNLOADED_FILL_STYLE + fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE + } + + function physics() { + statusPhysics() + childrenPhysics() + } + + function childrenPhysics() { + /* Panels Visible Button Setup */ + if (thisObject.status === LAYER_STATUS.ON) { + if (panelsVisibleButton === undefined) { + if (thisObject.panels !== undefined) { + if (thisObject.panels.length > 0) { + panelsVisibleButton = newPanelsVisibleButton() + + let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'showPanels') + if (storedValue !== undefined) { + if (storedValue === true || storedValue === false) { + panelsVisibleButton.showPanels = storedValue + } + } + + panelsVisibleButton.initialize(thisObject.panels) + panelsVisibleButton.container.connectToParent(thisObject.container) + } + } + } else { + savePropertyAtNodeConfig(thisObject.payload, 'showPanels', panelsVisibleButton.showPanels) + } + } + } + + function statusPhysics() { + /* We retrieve the stored status at the config. */ + try { + let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status') + + if (storedValue !== undefined) { + if (storedValue !== thisObject.status) { + if (storedValue === LAYER_STATUS.ON) { + resetProgressBars() + changeStatusTo(LAYER_STATUS.LOADING) + } + if (storedValue === LAYER_STATUS.OFF) { + resetProgressBars() + changeStatusTo(LAYER_STATUS.OFF) + } + } + } else { + resetProgressBars() + changeStatusTo(LAYER_STATUS.OFF) + } + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } + + /* Check when the loading finishes */ + if ( + thisObject.status === LAYER_STATUS.LOADING && + marketFileProgressBar.value === 100 && + dailyFileProgressBar.value === 100 + ) { + changeStatusTo(LAYER_STATUS.ON) + } + } + + function changeStatusTo(newStatus) { + if (thisObject.status !== newStatus) { + thisObject.status = newStatus + + if (thisObject.status === LAYER_STATUS.OFF) { + if (panelsVisibleButton !== undefined) { + panelsVisibleButton.finalize() + panelsVisibleButton = undefined + } + } + + savePropertyAtNodeConfig(thisObject.payload, 'status', thisObject.status) + let eventData = thisObject + thisObject.container.eventHandler.raiseEvent('Status Changed', eventData) + } + } + + function draw() { + drawLayer() if (panelsVisibleButton !== undefined) { - panelsVisibleButton.finalize() - panelsVisibleButton = undefined + panelsVisibleButton.draw() } - } - - savePropertyAtNodeConfig(thisObject.payload, 'status', thisObject.status) - let eventData = thisObject - thisObject.container.eventHandler.raiseEvent('Status Changed', eventData) - } - } - - function draw() { - drawLayer() - if (panelsVisibleButton !== undefined) { - panelsVisibleButton.draw() - } - } - - function drawLayer() { - drawLayerDisplay() - } - - function drawProgressBar(progressBar, lineWidth, offsetY) { - const ANIMATED_INCREMENT = 5 - const OPACITY_INCREMENT = 0.01 - const OPACITY_MIN = 1 - - let point1 - let point2 - let horizontalMargin = 12 - - if (progressBar.value === 0) { - return } - /* Animate */ - if (progressBar.animatedValue < progressBar.value) { - progressBar.animatedValue = progressBar.animatedValue + ANIMATED_INCREMENT - progressBar.opacity = progressBar.opacity + OPACITY_INCREMENT + function drawLayer() { + drawLayerDisplay() } - if (progressBar.animatedValue >= 100) { - progressBar.animatedValue = 100 + function drawProgressBar(progressBar, lineWidth, offsetY) { + const ANIMATED_INCREMENT = 5 + const OPACITY_INCREMENT = 0.01 + const OPACITY_MIN = 1 - progressBar.opacity = progressBar.opacity - OPACITY_INCREMENT - if (progressBar.opacity < OPACITY_MIN) { progressBar.opacity = OPACITY_MIN } + let point1 + let point2 + let horizontalMargin = 12 - progressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', progressBar.opacity.toString()) + if (progressBar.value === 0) { + return + } + + /* Animate */ + if (progressBar.animatedValue < progressBar.value) { + progressBar.animatedValue = progressBar.animatedValue + ANIMATED_INCREMENT + progressBar.opacity = progressBar.opacity + OPACITY_INCREMENT + } + + if (progressBar.animatedValue >= 100) { + progressBar.animatedValue = 100 + + progressBar.opacity = progressBar.opacity - OPACITY_INCREMENT + if (progressBar.opacity < OPACITY_MIN) { progressBar.opacity = OPACITY_MIN } + + progressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', progressBar.opacity.toString()) + } + + point1 = { + x: 0 + horizontalMargin, + y: thisObject.container.frame.height + offsetY + } + + point2 = { + x: (thisObject.container.frame.width - horizontalMargin * 2) * progressBar.animatedValue / 100 + horizontalMargin, + y: thisObject.container.frame.height + offsetY + } + + /* Now the transformations. */ + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + + point1 = thisObject.fitFunction(point1) + point2 = thisObject.fitFunction(point2) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = progressBar.strokeStyle.replace('@Opacity', progressBar.opacity.toString()) + + browserCanvasContext.setLineDash([1, 4]) + browserCanvasContext.lineWidth = lineWidth + browserCanvasContext.stroke() } - point1 = { - x: 0 + horizontalMargin, - y: thisObject.container.frame.height + offsetY + function drawLayerDisplay() { + let label1 = thisObject.payload.node.name + let label2 = thisObject.exchange.name.substring(0, 15) + ' - ' + thisObject.market + let label3 = thisObject.status.toUpperCase() + + if (label1 !== undefined) { + label1 = label1.substring(0, 30) + } + + let backgroundColor = UI_COLOR.BLACK + + const RED_LINE_HIGHT = 4 + const OPACITY = 0.75 + + let params = { + cornerRadius: 0, + lineWidth: 1, + container: thisObject.container, + borderColor: UI_COLOR.RUSTED_RED, + castShadow: false, + backgroundColor: backgroundColor, + opacity: OPACITY + } + + roundedCornersBackground(params) + + let parentLabel1FontSize = loadPropertyFromNodeConfig(thisObject.payload.parentNode.payload, 'label1FontSize') + let parentLabel2FontSize = loadPropertyFromNodeConfig(thisObject.payload.parentNode.payload, 'label2FontSize') + let parentLabel3FontSize = loadPropertyFromNodeConfig(thisObject.payload.parentNode.payload, 'label3FontSize') + + let label1FontSize = loadPropertyFromNodeConfig(thisObject.payload, 'label1FontSize') + let label2FontSize = loadPropertyFromNodeConfig(thisObject.payload, 'label2FontSize') + let label3FontSize = loadPropertyFromNodeConfig(thisObject.payload, 'label3FontSize') + + if (parentLabel1FontSize !== undefined) { + label1FontSize = parentLabel1FontSize + } + if (parentLabel2FontSize !== undefined) { + label2FontSize = parentLabel2FontSize + } + if (parentLabel3FontSize !== undefined) { + label3FontSize = parentLabel3FontSize + } + + if (label1FontSize === undefined) { + if (label1.length > 20) { + label1FontSize = 12 + } else { + label1FontSize = 15 + } + } + + if (label2FontSize === undefined) { + label2FontSize = 10 + } + + if (label3FontSize === undefined) { + label3FontSize = 9 + } + + drawLabel(label1, 1 / 2, 6 / 10, -5, 0, label1FontSize, thisObject.container) + drawLabel(label2, 1 / 2, 8.2 / 10, -5, 0, label2FontSize, thisObject.container) + drawLabel(label3, 1 / 2, 9.5 / 10, -5, 0, label3FontSize, thisObject.container) + + drawProgressBar(marketFileProgressBar, 1, -45) + drawProgressBar(dailyFileProgressBar, 1, -46) + drawProgressBar(singleFileProgressBar, 1, -47) + drawProgressBar(fileSequenceProgressBar, 1, -48) + + drawIcon(thisObject.exchangeIcon, 1 / 8, 2 / 10, 0, 0, 14, thisObject.container) + drawIcon(thisObject.plotterTypeIcon, 7 / 8, 2 / 10, 0, 0, 14, thisObject.container) + drawIcon(thisObject.baseAssetIcon, 3.4 / 8, 2 / 10, 0, 0, 14, thisObject.container) + drawIcon(thisObject.quotedAssetIcon, 4.6 / 8, 2 / 10, 0, 0, 14, thisObject.container) } - - point2 = { - x: (thisObject.container.frame.width - horizontalMargin * 2) * progressBar.animatedValue / 100 + horizontalMargin, - y: thisObject.container.frame.height + offsetY - } - - /* Now the transformations. */ - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - - point1 = thisObject.fitFunction(point1) - point2 = thisObject.fitFunction(point2) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = progressBar.strokeStyle.replace('@Opacity', progressBar.opacity.toString()) - - browserCanvasContext.setLineDash([1, 4]) - browserCanvasContext.lineWidth = lineWidth - browserCanvasContext.stroke() - } - - function drawLayerDisplay() { - let label1 = thisObject.payload.node.name - let label2 = thisObject.exchange.name.substring(0, 15) + ' - ' + thisObject.market - let label3 = thisObject.status.toUpperCase() - - if (label1 !== undefined) { - label1 = label1.substring(0, 30) - } - - let backgroundColor = UI_COLOR.BLACK - - const RED_LINE_HIGHT = 4 - const OPACITY = 0.75 - - let params = { - cornerRadius: 0, - lineWidth: 1, - container: thisObject.container, - borderColor: UI_COLOR.RUSTED_RED, - castShadow: false, - backgroundColor: backgroundColor, - opacity: OPACITY - } - - roundedCornersBackground(params) - - let parentLabel1FontSize = loadPropertyFromNodeConfig(thisObject.payload.parentNode.payload, 'label1FontSize') - let parentLabel2FontSize = loadPropertyFromNodeConfig(thisObject.payload.parentNode.payload, 'label2FontSize') - let parentLabel3FontSize = loadPropertyFromNodeConfig(thisObject.payload.parentNode.payload, 'label3FontSize') - - let label1FontSize = loadPropertyFromNodeConfig(thisObject.payload, 'label1FontSize') - let label2FontSize = loadPropertyFromNodeConfig(thisObject.payload, 'label2FontSize') - let label3FontSize = loadPropertyFromNodeConfig(thisObject.payload, 'label3FontSize') - - if (parentLabel1FontSize !== undefined) { - label1FontSize = parentLabel1FontSize - } - if (parentLabel2FontSize !== undefined) { - label2FontSize = parentLabel2FontSize - } - if (parentLabel3FontSize !== undefined) { - label3FontSize = parentLabel3FontSize - } - - if (label1FontSize === undefined) { - if (label1.length > 20) { - label1FontSize = 12 - } else { - label1FontSize = 15 - } - } - - if (label2FontSize === undefined) { - label2FontSize = 10 - } - - if (label3FontSize === undefined) { - label3FontSize = 9 - } - - drawLabel(label1, 1 / 2, 6 / 10, -5, 0, label1FontSize, thisObject.container) - drawLabel(label2, 1 / 2, 8.2 / 10, -5, 0, label2FontSize, thisObject.container) - drawLabel(label3, 1 / 2, 9.5 / 10, -5, 0, label3FontSize, thisObject.container) - - drawProgressBar(marketFileProgressBar, 1, -45) - drawProgressBar(dailyFileProgressBar, 1, -46) - drawProgressBar(singleFileProgressBar, 1, -47) - drawProgressBar(fileSequenceProgressBar, 1, -48) - - drawIcon(thisObject.exchangeIcon, 1 / 8, 2 / 10, 0, 0, 14, thisObject.container) - drawIcon(thisObject.plotterTypeIcon, 7 / 8, 2 / 10, 0, 0, 14, thisObject.container) - drawIcon(thisObject.baseAssetIcon, 3.4 / 8, 2 / 10, 0, 0, 14, thisObject.container) - drawIcon(thisObject.quotedAssetIcon, 4.6 / 8, 2 / 10, 0, 0, 14, thisObject.container) - } } diff --git a/Panels/LayersPanel.js b/Panels/LayersPanel.js index 1d50fc947..11d165da5 100644 --- a/Panels/LayersPanel.js +++ b/Panels/LayersPanel.js @@ -1,519 +1,519 @@ -function newLayersPanel () { - let thisObject = { - name: 'Layers Panel', - fitFunction: undefined, - container: undefined, - layers: [], - payload: undefined, - isVisible: true, - upDownButton: undefined, - leftRightButton: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize() - thisObject.container.isDraggeable = true - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - - let isInitialized = false - let mouseOverCounter = 0 - - let layersMap = new Map() - let visibleLayers = [] - let firstVisibleLayer = 1 - - const LAYER_SEPARATION = 0 - - let headerHeight = 40 - let footerHeight = 10 - let layerHeight = 70 - let desiredVisibleLayers = 5 - let posibleVisibleLayers = 5 - let desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight - let posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + footerHeight - - let onMouseWheelEventSuscriptionId - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - - let isMouseOver - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSuscriptionId) - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - - thisObject.upDownButton.finalize() - thisObject.upDownButton = undefined - - thisObject.leftRightButton.finalize() - thisObject.leftRightButton = undefined - - layersMap = undefined - visibleLayers = undefined - - thisObject.container.finalize() - thisObject.container = undefined - - thisObject.payload = undefined - thisObject = undefined - } - - function initialize () { - thisObject.container.name = thisObject.payload.node.name - thisObject.container.frame.containerName = thisObject.container.name - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL - thisObject.container.frame.height = headerHeight - - let position = { // Default position - x: canvas.chartingSpace.viewport.visibleArea.topLeft.x, - y: canvas.chartingSpace.viewport.visibleArea.topLeft.y +function newLayersPanel() { + let thisObject = { + name: 'Layers Panel', + fitFunction: undefined, + container: undefined, + layers: [], + payload: undefined, + isVisible: true, + upDownButton: undefined, + leftRightButton: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - thisObject.container.frame.position = position - loadFrame(thisObject.payload, thisObject.container.frame) + thisObject.container = newContainer() + thisObject.container.initialize() + thisObject.container.isDraggeable = true + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true - thisObject.upDownButton = newUpDownButton() - thisObject.upDownButton.parentContainer = thisObject.container - thisObject.upDownButton.container.frame.parentFrame = thisObject.container.frame - thisObject.upDownButton.fitFunction = thisObject.fitFunction - thisObject.upDownButton.initialize() + let isInitialized = false + let mouseOverCounter = 0 - thisObject.leftRightButton = newLeftRightButton() - thisObject.leftRightButton.parentContainer = thisObject.container - thisObject.leftRightButton.container.frame.parentFrame = thisObject.container.frame - thisObject.leftRightButton.fitFunction = thisObject.fitFunction - thisObject.leftRightButton.initialize() + let layersMap = new Map() + let visibleLayers = [] + let firstVisibleLayer = 1 - onMouseWheelEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + const LAYER_SEPARATION = 0 - readObjectState() + let headerHeight = 40 + let footerHeight = 10 + let layerHeight = 70 + let desiredVisibleLayers = 5 + let posibleVisibleLayers = 5 + let desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight + let posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + footerHeight - isInitialized = true - } + let onMouseWheelEventSuscriptionId + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId - function onMouseOver (event) { - isMouseOver = true - } + let isMouseOver + return thisObject - function onMouseNotOver () { - isMouseOver = false - } + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSuscriptionId) + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - function saveObjectStateVisibleLayers () { - savePropertyAtNodeConfig(thisObject.payload, 'visibleLayers', desiredVisibleLayers) - } + thisObject.upDownButton.finalize() + thisObject.upDownButton = undefined - function saveObjectStatePanelLocation () { - let panelLocation = { - upOrDown: thisObject.upDownButton.status, - leftOrRight: thisObject.leftRightButton.status + thisObject.leftRightButton.finalize() + thisObject.leftRightButton = undefined + + layersMap = undefined + visibleLayers = undefined + + thisObject.container.finalize() + thisObject.container = undefined + + thisObject.payload = undefined + thisObject = undefined } - savePropertyAtNodeConfig(thisObject.payload, 'panelLocation', panelLocation) - } - function readObjectState () { - let storedValue + function initialize() { + thisObject.container.name = thisObject.payload.node.name + thisObject.container.frame.containerName = thisObject.container.name + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL + thisObject.container.frame.height = headerHeight - storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'visibleLayers') + let position = { // Default position + x: canvas.chartingSpace.viewport.visibleArea.topLeft.x, + y: canvas.chartingSpace.viewport.visibleArea.topLeft.y + } - if (isNaN(storedValue) || storedValue === null || storedValue === undefined) { - // not using this value - saveObjectStateVisibleLayers() // this overrides any invalid value at the config. - return - } else { - if (storedValue < 0) { storedValue = 0 } - if (storedValue > thisObject.layers.length) { - storedValue = thisObject.layers.length - } + thisObject.container.frame.position = position + loadFrame(thisObject.payload, thisObject.container.frame) - if (storedValue !== desiredVisibleLayers) { - desiredVisibleLayers = storedValue + thisObject.upDownButton = newUpDownButton() + thisObject.upDownButton.parentContainer = thisObject.container + thisObject.upDownButton.container.frame.parentFrame = thisObject.container.frame + thisObject.upDownButton.fitFunction = thisObject.fitFunction + thisObject.upDownButton.initialize() + + thisObject.leftRightButton = newLeftRightButton() + thisObject.leftRightButton.parentContainer = thisObject.container + thisObject.leftRightButton.container.frame.parentFrame = thisObject.container.frame + thisObject.leftRightButton.fitFunction = thisObject.fitFunction + thisObject.leftRightButton.initialize() + + onMouseWheelEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + + readObjectState() + + isInitialized = true + } + + function onMouseOver(event) { + isMouseOver = true + } + + function onMouseNotOver() { + isMouseOver = false + } + + function saveObjectStateVisibleLayers() { + savePropertyAtNodeConfig(thisObject.payload, 'visibleLayers', desiredVisibleLayers) + } + + function saveObjectStatePanelLocation() { + let panelLocation = { + upOrDown: thisObject.upDownButton.status, + leftOrRight: thisObject.leftRightButton.status + } + savePropertyAtNodeConfig(thisObject.payload, 'panelLocation', panelLocation) + } + + function readObjectState() { + let storedValue + + storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'visibleLayers') + + if (isNaN(storedValue) || storedValue === null || storedValue === undefined) { + // not using this value + saveObjectStateVisibleLayers() // this overrides any invalid value at the config. + return + } else { + if (storedValue < 0) { storedValue = 0 } + if (storedValue > thisObject.layers.length) { + storedValue = thisObject.layers.length + } + + if (storedValue !== desiredVisibleLayers) { + desiredVisibleLayers = storedValue + desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight + calculateVisbleLayers() + } + } + + storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'panelLocation') + + if (storedValue === null || storedValue === undefined) { + // not using this value + saveObjectStatePanelLocation() // this overrides any invalid value at the config. + return + } else { + if (storedValue.upOrDown !== 'up' && storedValue.upOrDown !== 'down') { + saveObjectStatePanelLocation() // this overrides any invalid value at the config. + return + } + if (storedValue.leftOrRight !== 'left' && storedValue.leftOrRight !== 'right') { + saveObjectStatePanelLocation() // this overrides any invalid value at the config. + return + } + thisObject.upDownButton.setStatus(storedValue.upOrDown) + thisObject.leftRightButton.setStatus(storedValue.leftOrRight) + saveObjectStatePanelLocation() + } + } + + function removeLayer(id) { + let layer = layersMap.get(id) + layersMap.delete(id) + layer.turnOff() + layer.container.eventHandler.stopListening(layer.onLayerStatusChangedEventSuscriptionId) + layer.container.eventHandler.stopListening(layer.onMouseWheelEventSuscriptionId) + layer.finalize() + } + + function addLayer(layerNode) { + /* Now we create Product objects */ + let layer = newLayer() + layer.payload = layerNode.payload + layer.nodeId = layerNode.payload.node.id + layer.fitFunction = thisObject.fitFunction + + /* Initialize it */ + layer.initialize(onInitialized) + + function onInitialized(err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + layersMap.set(layerNode.id, layer) + + /* Container Stuff */ + layer.container.frame.parentFrame = thisObject.container.frame + layer.container.parentContainer = thisObject.container + layer.container.isWheelable = true + + /* Add to the Product Array */ + thisObject.layers.push(layer) + + /* Listen to Status Changes Events */ + layer.onLayerStatusChangedEventSuscriptionId = layer.container.eventHandler.listenToEvent('Status Changed', onLayerStatusChanged) + layer.onMouseWheelEventSuscriptionId = layer.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + + layer.checkStatusAtShutDown() + + return + } + } + } + + function onMouseWheel(event) { + delta = event.wheelDelta + if (delta > 0) { + delta = -1 + } else { + delta = 1 + } + + if (event.y - thisObject.container.frame.position.y - CURRENT_TOP_MARGIN < headerHeight) { // Mouse wheel over the header, not a layer + desiredVisibleLayers = desiredVisibleLayers + delta + if (desiredVisibleLayers < 0) { desiredVisibleLayers = 0 } + if (desiredVisibleLayers > thisObject.layers.length) { desiredVisibleLayers = thisObject.layers.length } + } else { + firstVisibleLayer = firstVisibleLayer + delta + } desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight calculateVisbleLayers() - } + saveObjectStateVisibleLayers() } - storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'panelLocation') + function panelSizePhysics() { + if (isInitialized === false || thisObject.isHidden === true) { return } - if (storedValue === null || storedValue === undefined) { - // not using this value - saveObjectStatePanelLocation() // this overrides any invalid value at the config. - return - } else { - if (storedValue.upOrDown !== 'up' && storedValue.upOrDown !== 'down') { - saveObjectStatePanelLocation() // this overrides any invalid value at the config. - return - } - if (storedValue.leftOrRight !== 'left' && storedValue.leftOrRight !== 'right') { - saveObjectStatePanelLocation() // this overrides any invalid value at the config. - return - } - thisObject.upDownButton.setStatus(storedValue.upOrDown) - thisObject.leftRightButton.setStatus(storedValue.leftOrRight) - saveObjectStatePanelLocation() - } - } + let viewPortHeight = canvas.chartingSpace.viewport.visibleArea.bottomLeft.y - canvas.chartingSpace.viewport.visibleArea.topLeft.y - function removeLayer (id) { - let layer = layersMap.get(id) - layersMap.delete(id) - layer.turnOff() - layer.container.eventHandler.stopListening(layer.onLayerStatusChangedEventSuscriptionId) - layer.container.eventHandler.stopListening(layer.onMouseWheelEventSuscriptionId) - layer.finalize() - } - - function addLayer (layerNode) { - /* Now we create Product objects */ - let layer = newLayer() - layer.payload = layerNode.payload - layer.nodeId = layerNode.payload.node.id - layer.fitFunction = thisObject.fitFunction - - /* Initialize it */ - layer.initialize(onInitialized) - - function onInitialized (err) { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - layersMap.set(layerNode.id, layer) - - /* Container Stuff */ - layer.container.frame.parentFrame = thisObject.container.frame - layer.container.parentContainer = thisObject.container - layer.container.isWheelable = true - - /* Add to the Product Array */ - thisObject.layers.push(layer) - - /* Listen to Status Changes Events */ - layer.onLayerStatusChangedEventSuscriptionId = layer.container.eventHandler.listenToEvent('Status Changed', onLayerStatusChanged) - layer.onMouseWheelEventSuscriptionId = layer.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - - layer.checkStatusAtShutDown() - - return - } - } - } - - function onMouseWheel (event) { - delta = event.wheelDelta - if (delta > 0) { - delta = -1 - } else { - delta = 1 - } - - if (event.y - thisObject.container.frame.position.y - CURRENT_TOP_MARGIN < headerHeight) { // Mouse wheel over the header, not a layer - desiredVisibleLayers = desiredVisibleLayers + delta - if (desiredVisibleLayers < 0) { desiredVisibleLayers = 0 } - if (desiredVisibleLayers > thisObject.layers.length) { desiredVisibleLayers = thisObject.layers.length } - } else { - firstVisibleLayer = firstVisibleLayer + delta - } - desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight - calculateVisbleLayers() - saveObjectStateVisibleLayers() - } - - function panelSizePhysics () { - if (isInitialized === false || thisObject.isHidden === true) { return } - - let viewPortHeight = canvas.chartingSpace.viewport.visibleArea.bottomLeft.y - canvas.chartingSpace.viewport.visibleArea.topLeft.y - - if (viewPortHeight < headerHeight) { - thisObject.visible = false - } else { - thisObject.visible = true - } - - if (thisObject.visible === false) { return } - - if (desiredPanelHeight > viewPortHeight) { - posibleVisibleLayers = Math.trunc((viewPortHeight - headerHeight - footerHeight) / (layerHeight + LAYER_SEPARATION)) - } else { - posibleVisibleLayers = desiredVisibleLayers - } - if (thisObject.layers.length < posibleVisibleLayers) { posibleVisibleLayers = thisObject.layers.length } - - if (posibleVisibleLayers === 0) { - posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight - } else { - posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + footerHeight - } - - thisObject.container.frame.height = posiblePanelHeight - } - - function calculateVisbleLayers () { - panelSizePhysics() - let availableSlots = posibleVisibleLayers - - if (firstVisibleLayer < 1) { firstVisibleLayer = 1 } - if (firstVisibleLayer > (thisObject.layers.length - availableSlots + 1)) { firstVisibleLayer = thisObject.layers.length - availableSlots + 1 } - - visibleLayers = [] - - for (let i = 0; i < thisObject.layers.length; i++) { - if (i + 1 >= firstVisibleLayer && i + 1 < firstVisibleLayer + availableSlots) { - let layer = thisObject.layers[i] - - layer.container.frame.position.x = 0 - layer.container.frame.position.y = (layerHeight + LAYER_SEPARATION) * visibleLayers.length + headerHeight - - /* Add to Visible Product Array */ - visibleLayers.push(layer) - } - } - } - - function onLayerStatusChanged (layer) { - thisObject.container.eventHandler.raiseEvent('Layer Status Changed', layer) - } - - function getContainer (point, purpose) { - if (isInitialized === false || thisObject.visible === false || thisObject.isHidden === true) { return } - let container - - if (isMouseOver === true && purpose !== GET_CONTAINER_PURPOSE.MOUSE_OVER) { - container = thisObject.upDownButton.getContainer(point) - if (container !== undefined) { return container } - - container = thisObject.leftRightButton.getContainer(point) - if (container !== undefined) { return container } - } - - /* First we check if thisObject point is inside thisObject space. */ - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - /* Now we see which is the inner most container that has it */ - for (let i = 0; i < visibleLayers.length; i++) { - container = visibleLayers[i].getContainer(point) - - if (container !== undefined) { - let checkPoint = { - x: point.x, - y: point.y - } - - checkPoint = thisObject.fitFunction(checkPoint) - - if (point.x === checkPoint.x && point.y === checkPoint.y) { - if (purpose !== GET_CONTAINER_PURPOSE.MOUSE_OVER) { - return container - } - } + if (viewPortHeight < headerHeight) { + thisObject.visible = false + } else { + thisObject.visible = true } - } - /* The point does not belong to any inner container, so we return the current container. */ - let checkPoint = { - x: point.x, - y: point.y - } + if (thisObject.visible === false) { return } - checkPoint = thisObject.fitFunction(checkPoint) - - if (point.x === checkPoint.x && point.y === checkPoint.y) { - return thisObject.container - } - } - } - - function childrenPhysics () { - for (let i = 0; i < thisObject.layers.length; i++) { - let layer = thisObject.layers[i] - layer.physics() - } - } - - function syncWithConfigPhysics () { - readObjectState() - } - - function physics () { - if (isInitialized === false) { return } - if (thisObject.payload.node === undefined) { return } - - thisObject.upDownButton.physics() - thisObject.leftRightButton.physics() - saveFrame(thisObject.payload, thisObject.container.frame) - syncWithConfigPhysics() - - /* - The overall idea here is that we need to keep syncronized the panel with the layers that are - defined at the Designer. Users can connect or disconnect any objext resulting in changes in which - are valid layers and which not at any point in time. So what we do here is trying to keep the panel - only with the layers that are connected to the Charting Space hiriarcy. - - To achieve this, first we are going to move all session related cards to a local array. Then we are - going to check for layers at the designer, and will move back the cards which still have layers well - defined to where they were. - - If we find new layers we will add them at that point. Finally, the cards that still remain at the - local array after all the layers at the designer have been processed, are turned off and discarded. - */ - childrenPhysics() - - let localLayers = [] - moveToLocalLayers() - syncWithDesignerLayers() - - /* At this poins all the cards still at the local array need to be removed from the panel. */ - turnOffUnusedLayers() - calculateVisbleLayers() - - function syncWithDesignerLayers () { - if (thisObject.payload.node === undefined) { return } - let layerManager = thisObject.payload.node - for (let p = 0; p < layerManager.layers.length; p++) { - let layerNode = layerManager.layers[p] - - let found = removeFromLocalLayers(layerNode.id) - if (found !== true) { - layer = addLayer(layerNode) - if (layer !== undefined) { - onLayerStatusChanged(layer) - } + if (desiredPanelHeight > viewPortHeight) { + posibleVisibleLayers = Math.trunc((viewPortHeight - headerHeight - footerHeight) / (layerHeight + LAYER_SEPARATION)) + } else { + posibleVisibleLayers = desiredVisibleLayers } - } + if (thisObject.layers.length < posibleVisibleLayers) { posibleVisibleLayers = thisObject.layers.length } + + if (posibleVisibleLayers === 0) { + posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + } else { + posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + footerHeight + } + + thisObject.container.frame.height = posiblePanelHeight } - function moveToLocalLayers () { - removeNext() + function calculateVisbleLayers() { + panelSizePhysics() + let availableSlots = posibleVisibleLayers + + if (firstVisibleLayer < 1) { firstVisibleLayer = 1 } + if (firstVisibleLayer > (thisObject.layers.length - availableSlots + 1)) { firstVisibleLayer = thisObject.layers.length - availableSlots + 1 } + + visibleLayers = [] - function removeNext () { for (let i = 0; i < thisObject.layers.length; i++) { - let layer = thisObject.layers[i] + if (i + 1 >= firstVisibleLayer && i + 1 < firstVisibleLayer + availableSlots) { + let layer = thisObject.layers[i] - thisObject.layers.splice(i, 1) - localLayers.push(layer) - removeNext() + layer.container.frame.position.x = 0 + layer.container.frame.position.y = (layerHeight + LAYER_SEPARATION) * visibleLayers.length + headerHeight + + /* Add to Visible Product Array */ + visibleLayers.push(layer) + } } - } } - function removeFromLocalLayers (id) { - for (let i = 0; i < localLayers.length; i++) { - let layer = localLayers[i] - if (layer.payload.node.id === id) { - thisObject.layers.push(layer) - localLayers.splice(i, 1) - return true + function onLayerStatusChanged(layer) { + thisObject.container.eventHandler.raiseEvent('Layer Status Changed', layer) + } + + function getContainer(point, purpose) { + if (isInitialized === false || thisObject.visible === false || thisObject.isHidden === true) { return } + let container + + if (isMouseOver === true && purpose !== GET_CONTAINER_PURPOSE.MOUSE_OVER) { + container = thisObject.upDownButton.getContainer(point) + if (container !== undefined) { return container } + + container = thisObject.leftRightButton.getContainer(point) + if (container !== undefined) { return container } + } + + /* First we check if thisObject point is inside thisObject space. */ + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + /* Now we see which is the inner most container that has it */ + for (let i = 0; i < visibleLayers.length; i++) { + container = visibleLayers[i].getContainer(point) + + if (container !== undefined) { + let checkPoint = { + x: point.x, + y: point.y + } + + checkPoint = thisObject.fitFunction(checkPoint) + + if (point.x === checkPoint.x && point.y === checkPoint.y) { + if (purpose !== GET_CONTAINER_PURPOSE.MOUSE_OVER) { + return container + } + } + } + } + + /* The point does not belong to any inner container, so we return the current container. */ + let checkPoint = { + x: point.x, + y: point.y + } + + checkPoint = thisObject.fitFunction(checkPoint) + + if (point.x === checkPoint.x && point.y === checkPoint.y) { + return thisObject.container + } } - } } - function turnOffUnusedLayers () { - for (let i = 0; i < localLayers.length; i++) { - let layer = localLayers[i] - removeLayer(layer.nodeId) - } - } - } - - function draw () { - if (isInitialized === false || thisObject.visible === false || thisObject.isHidden === true) { return } - - // thisObject.container.frame.draw(false, false, false, thisObject.fitFunction) - - drawHeader() - for (let i = 0; i < visibleLayers.length; i++) { - visibleLayers[i].draw() - } - drawScrollBar() - if (isMouseOver === true) { - thisObject.upDownButton.draw() - thisObject.leftRightButton.draw() - } - } - - function drawHeader () { - if (thisObject.payload === undefined) { return } - if (thisObject.payload.node === undefined) { return } - if (thisObject.payload.node.payload.parentNode === undefined) { return } - if (thisObject.payload.node.payload.parentNode.payload.parentNode === undefined) { return } - - let label1 = thisObject.payload.node.payload.parentNode.payload.parentNode.name.substring(0, 18) - let label2 = thisObject.payload.node.payload.parentNode.name.substring(0, 18) - let label3 = '' - - let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.payload.parentNode.type) - let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) - - let backgroundColor = UI_COLOR.BLACK - - let params = { - cornerRadius: 5, - lineWidth: 1, - container: thisObject.container, - borderColor: UI_COLOR.RUSTED_RED, - castShadow: false, - backgroundColor: backgroundColor, - opacity: 1 + function childrenPhysics() { + for (let i = 0; i < thisObject.layers.length; i++) { + let layer = thisObject.layers[i] + layer.physics() + } } - roundedCornersBackground(params) - - drawLabel(label1, 1 / 2, 0, 0, 15, 9, thisObject.container) - drawLabel(label2, 1 / 2, 0, 0, 30, 9, thisObject.container) - - drawIcon(icon1, 1 / 8, 0, 0, 20, 28, thisObject.container) - drawIcon(icon2, 7 / 8, 0, 0, 20, 28, thisObject.container) - } - - function drawScrollBar () { - if (thisObject.layers.length > posibleVisibleLayers && posibleVisibleLayers > 0) { - let xOffset = 4 - let barTopPoint = { - x: thisObject.container.frame.width - xOffset, - y: headerHeight - } - let barBottomPoint = { - x: thisObject.container.frame.width - xOffset, - y: thisObject.container.frame.height - footerHeight - } - let ratio = posibleVisibleLayers / thisObject.layers.length - let handleHeight = (posibleVisibleLayers * (layerHeight + LAYER_SEPARATION)) * ratio - let handleTopPoint = { - x: thisObject.container.frame.width - xOffset, - y: headerHeight + (layerHeight + LAYER_SEPARATION) * ratio * (firstVisibleLayer - 1) - } - let handleBottomPoint = { - x: thisObject.container.frame.width - xOffset, - y: handleTopPoint.y + handleHeight - } - barTopPoint = thisObject.container.frame.frameThisPoint(barTopPoint) - barBottomPoint = thisObject.container.frame.frameThisPoint(barBottomPoint) - handleTopPoint = thisObject.container.frame.frameThisPoint(handleTopPoint) - handleBottomPoint = thisObject.container.frame.frameThisPoint(handleBottomPoint) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(barTopPoint.x, barTopPoint.y) - browserCanvasContext.lineTo(barBottomPoint.x, barBottomPoint.y) - browserCanvasContext.closePath() - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.lineWidth = 1 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')' - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(handleTopPoint.x, handleTopPoint.y) - browserCanvasContext.lineTo(handleBottomPoint.x, handleBottomPoint.y) - browserCanvasContext.closePath() - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.lineWidth = 4 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + 1 + ')' - browserCanvasContext.stroke() + function syncWithConfigPhysics() { + readObjectState() + } + + function physics() { + if (isInitialized === false) { return } + if (thisObject.payload.node === undefined) { return } + + thisObject.upDownButton.physics() + thisObject.leftRightButton.physics() + saveFrame(thisObject.payload, thisObject.container.frame) + syncWithConfigPhysics() + + /* + The overall idea here is that we need to keep syncronized the panel with the layers that are + defined at the Designer. Users can connect or disconnect any objext resulting in changes in which + are valid layers and which not at any point in time. So what we do here is trying to keep the panel + only with the layers that are connected to the Charting Space hiriarcy. + + To achieve this, first we are going to move all session related cards to a local array. Then we are + going to check for layers at the designer, and will move back the cards which still have layers well + defined to where they were. + + If we find new layers we will add them at that point. Finally, the cards that still remain at the + local array after all the layers at the designer have been processed, are turned off and discarded. + */ + childrenPhysics() + + let localLayers = [] + moveToLocalLayers() + syncWithDesignerLayers() + + /* At this poins all the cards still at the local array need to be removed from the panel. */ + turnOffUnusedLayers() + calculateVisbleLayers() + + function syncWithDesignerLayers() { + if (thisObject.payload.node === undefined) { return } + let layerManager = thisObject.payload.node + for (let p = 0; p < layerManager.layers.length; p++) { + let layerNode = layerManager.layers[p] + + let found = removeFromLocalLayers(layerNode.id) + if (found !== true) { + layer = addLayer(layerNode) + if (layer !== undefined) { + onLayerStatusChanged(layer) + } + } + } + } + + function moveToLocalLayers() { + removeNext() + + function removeNext() { + for (let i = 0; i < thisObject.layers.length; i++) { + let layer = thisObject.layers[i] + + thisObject.layers.splice(i, 1) + localLayers.push(layer) + removeNext() + } + } + } + + function removeFromLocalLayers(id) { + for (let i = 0; i < localLayers.length; i++) { + let layer = localLayers[i] + if (layer.payload.node.id === id) { + thisObject.layers.push(layer) + localLayers.splice(i, 1) + return true + } + } + } + + function turnOffUnusedLayers() { + for (let i = 0; i < localLayers.length; i++) { + let layer = localLayers[i] + removeLayer(layer.nodeId) + } + } + } + + function draw() { + if (isInitialized === false || thisObject.visible === false || thisObject.isHidden === true) { return } + + // thisObject.container.frame.draw(false, false, false, thisObject.fitFunction) + + drawHeader() + for (let i = 0; i < visibleLayers.length; i++) { + visibleLayers[i].draw() + } + drawScrollBar() + if (isMouseOver === true) { + thisObject.upDownButton.draw() + thisObject.leftRightButton.draw() + } + } + + function drawHeader() { + if (thisObject.payload === undefined) { return } + if (thisObject.payload.node === undefined) { return } + if (thisObject.payload.node.payload.parentNode === undefined) { return } + if (thisObject.payload.node.payload.parentNode.payload.parentNode === undefined) { return } + + let label1 = thisObject.payload.node.payload.parentNode.payload.parentNode.name.substring(0, 18) + let label2 = thisObject.payload.node.payload.parentNode.name.substring(0, 18) + let label3 = '' + + let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.payload.parentNode.type) + let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) + + let backgroundColor = UI_COLOR.BLACK + + let params = { + cornerRadius: 5, + lineWidth: 1, + container: thisObject.container, + borderColor: UI_COLOR.RUSTED_RED, + castShadow: false, + backgroundColor: backgroundColor, + opacity: 1 + } + + roundedCornersBackground(params) + + drawLabel(label1, 1 / 2, 0, 0, 15, 9, thisObject.container) + drawLabel(label2, 1 / 2, 0, 0, 30, 9, thisObject.container) + + drawIcon(icon1, 1 / 8, 0, 0, 20, 28, thisObject.container) + drawIcon(icon2, 7 / 8, 0, 0, 20, 28, thisObject.container) + } + + function drawScrollBar() { + if (thisObject.layers.length > posibleVisibleLayers && posibleVisibleLayers > 0) { + let xOffset = 4 + let barTopPoint = { + x: thisObject.container.frame.width - xOffset, + y: headerHeight + } + let barBottomPoint = { + x: thisObject.container.frame.width - xOffset, + y: thisObject.container.frame.height - footerHeight + } + let ratio = posibleVisibleLayers / thisObject.layers.length + let handleHeight = (posibleVisibleLayers * (layerHeight + LAYER_SEPARATION)) * ratio + let handleTopPoint = { + x: thisObject.container.frame.width - xOffset, + y: headerHeight + (layerHeight + LAYER_SEPARATION) * ratio * (firstVisibleLayer - 1) + } + let handleBottomPoint = { + x: thisObject.container.frame.width - xOffset, + y: handleTopPoint.y + handleHeight + } + barTopPoint = thisObject.container.frame.frameThisPoint(barTopPoint) + barBottomPoint = thisObject.container.frame.frameThisPoint(barBottomPoint) + handleTopPoint = thisObject.container.frame.frameThisPoint(handleTopPoint) + handleBottomPoint = thisObject.container.frame.frameThisPoint(handleBottomPoint) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(barTopPoint.x, barTopPoint.y) + browserCanvasContext.lineTo(barBottomPoint.x, barBottomPoint.y) + browserCanvasContext.closePath() + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.lineWidth = 1 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')' + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(handleTopPoint.x, handleTopPoint.y) + browserCanvasContext.lineTo(handleBottomPoint.x, handleBottomPoint.y) + browserCanvasContext.closePath() + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.lineWidth = 4 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + 1 + ')' + browserCanvasContext.stroke() + } } - } } diff --git a/Panels/LeftRightButton.js b/Panels/LeftRightButton.js index cac7c7345..9478e83ee 100644 --- a/Panels/LeftRightButton.js +++ b/Panels/LeftRightButton.js @@ -1,244 +1,244 @@ -function newLeftRightButton () { - let thisObject = { - container: undefined, - fitFunction: undefined, - parentContainer: undefined, - status: undefined, - setStatus: setStatus, - physics: physics, - draw: draw, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } - - let isInitialized = false - /* Cointainer stuff */ - - thisObject.container = newContainer() - thisObject.container.name = 'Left Right Button' - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.frame.containerName = 'Left Right Button' - - thisObject.status = 'left' - let leftPosition = {} - let rightPosition = {} - let transitionPosition = {} - - let onMouseClickEventSuscriptionId - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.parentContainer = undefined - - thisObject.status = undefined - leftPosition = undefined - rightPosition = undefined - transitionPosition = undefined - } - - function initialize () { - thisObject.container.frame.width = 12 - thisObject.container.frame.height = 12 - - let position = { - x: thisObject.container.frame.parentFrame.width * 2.25 / 8 - thisObject.container.frame.width / 2, - y: 40 * 4 / 8 - thisObject.container.frame.height / 2 +function newLeftRightButton() { + let thisObject = { + container: undefined, + fitFunction: undefined, + parentContainer: undefined, + status: undefined, + setStatus: setStatus, + physics: physics, + draw: draw, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize } - thisObject.container.frame.position = position + let isInitialized = false + /* Cointainer stuff */ - leftPosition.x = thisObject.parentContainer.frame.position.x - leftPosition.y = thisObject.parentContainer.frame.position.y + thisObject.container = newContainer() + thisObject.container.name = 'Left Right Button' + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.frame.containerName = 'Left Right Button' - rightPosition.x = thisObject.parentContainer.frame.position.x - rightPosition.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y + thisObject.status = 'left' + let leftPosition = {} + let rightPosition = {} + let transitionPosition = {} - transitionPosition.x = leftPosition.x - transitionPosition.y = leftPosition.y + let onMouseClickEventSuscriptionId + return thisObject - /* Lets listen to our own events to react when we have a Mouse Click */ - onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.parentContainer = undefined - isInitialized = true - } - - function setStatus (value) { - if (value === 'left' && thisObject.status === 'right') { - thisObject.status = 'going left' + thisObject.status = undefined + leftPosition = undefined + rightPosition = undefined + transitionPosition = undefined } - if (value === 'right' && thisObject.status === 'left') { - thisObject.status = 'going right' + + function initialize() { + thisObject.container.frame.width = 12 + thisObject.container.frame.height = 12 + + let position = { + x: thisObject.container.frame.parentFrame.width * 2.25 / 8 - thisObject.container.frame.width / 2, + y: 40 * 4 / 8 - thisObject.container.frame.height / 2 + } + + thisObject.container.frame.position = position + + leftPosition.x = thisObject.parentContainer.frame.position.x + leftPosition.y = thisObject.parentContainer.frame.position.y + + rightPosition.x = thisObject.parentContainer.frame.position.x + rightPosition.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y + + transitionPosition.x = leftPosition.x + transitionPosition.y = leftPosition.y + + /* Lets listen to our own events to react when we have a Mouse Click */ + onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + + isInitialized = true } - } - function onMouseClick (event) { - if (thisObject.status === 'left') { - transitionPosition.x = leftPosition.x - transitionPosition.y = leftPosition.y - - thisObject.status = 'going right' - } else { - transitionPosition.x = rightPosition.x - transitionPosition.y = rightPosition.y - - thisObject.status = 'going left' + function setStatus(value) { + if (value === 'left' && thisObject.status === 'right') { + thisObject.status = 'going left' + } + if (value === 'right' && thisObject.status === 'left') { + thisObject.status = 'going right' + } } - } - function physics () { - if (isInitialized === false) { return } + function onMouseClick(event) { + if (thisObject.status === 'left') { + transitionPosition.x = leftPosition.x + transitionPosition.y = leftPosition.y - leftPosition.x = canvas.chartingSpace.viewport.visibleArea.topLeft.x - leftPosition.y = thisObject.parentContainer.frame.position.y + thisObject.status = 'going right' + } else { + transitionPosition.x = rightPosition.x + transitionPosition.y = rightPosition.y - rightPosition.x = canvas.chartingSpace.viewport.visibleArea.bottomRight.x - rightPosition.y = thisObject.parentContainer.frame.position.y - - if (thisObject.status === 'going right') { - if (transitionPosition.x < rightPosition.x) { - transitionPosition.x = transitionPosition.x + 50 - thisObject.parentContainer.frame.position.x = transitionPosition.x - } else { - thisObject.parentContainer.frame.position.x = rightPosition.x - thisObject.status = 'right' - } + thisObject.status = 'going left' + } } - if (thisObject.status === 'going left') { - if (transitionPosition.x > leftPosition.x) { - transitionPosition.x = transitionPosition.x - 50 - thisObject.parentContainer.frame.position.x = transitionPosition.x - } else { - thisObject.parentContainer.frame.position.x = leftPosition.x - thisObject.status = 'left' - } + + function physics() { + if (isInitialized === false) { return } + + leftPosition.x = canvas.chartingSpace.viewport.visibleArea.topLeft.x + leftPosition.y = thisObject.parentContainer.frame.position.y + + rightPosition.x = canvas.chartingSpace.viewport.visibleArea.bottomRight.x + rightPosition.y = thisObject.parentContainer.frame.position.y + + if (thisObject.status === 'going right') { + if (transitionPosition.x < rightPosition.x) { + transitionPosition.x = transitionPosition.x + 50 + thisObject.parentContainer.frame.position.x = transitionPosition.x + } else { + thisObject.parentContainer.frame.position.x = rightPosition.x + thisObject.status = 'right' + } + } + if (thisObject.status === 'going left') { + if (transitionPosition.x > leftPosition.x) { + transitionPosition.x = transitionPosition.x - 50 + thisObject.parentContainer.frame.position.x = transitionPosition.x + } else { + thisObject.parentContainer.frame.position.x = leftPosition.x + thisObject.status = 'left' + } + } } - } - function draw () { - if (isInitialized === false) { return } + function draw() { + if (isInitialized === false) { return } - drawButton() - } - - function getContainer (point, purpose) { - let container - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container + drawButton() } - } - function drawButton () { - let point1 - let point2 - let point3 - - switch (thisObject.status) { - case 'left': { - point1 = { - x: 3, - y: 3 + function getContainer(point, purpose) { + let container + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container } - - point2 = { - x: 3, - y: thisObject.container.frame.height - 3 - } - - point3 = { - x: thisObject.container.frame.width - 3, - y: thisObject.container.frame.height / 2 - } - break - } - - case 'going right': { - point1 = { - x: 4, - y: 4 - } - - point2 = { - x: 4, - y: thisObject.container.frame.height - 4 - } - - point3 = { - x: thisObject.container.frame.width - 4, - y: thisObject.container.frame.height / 2 - } - break - } - - case 'going left': { - point1 = { - x: thisObject.container.frame.width - 4, - y: 4 - } - - point2 = { - x: thisObject.container.frame.width - 4, - y: thisObject.container.frame.height - 4 - } - - point3 = { - x: 4, - y: thisObject.container.frame.height / 2 - } - break - } - - case 'right': { - point1 = { - x: thisObject.container.frame.width - 3, - y: 3 - } - - point2 = { - x: thisObject.container.frame.width - 3, - y: thisObject.container.frame.height - 3 - } - - point3 = { - x: 3, - y: thisObject.container.frame.height / 2 - } - break - } } + function drawButton() { + let point1 + let point2 + let point3 + + switch (thisObject.status) { + case 'left': { + point1 = { + x: 3, + y: 3 + } + + point2 = { + x: 3, + y: thisObject.container.frame.height - 3 + } + + point3 = { + x: thisObject.container.frame.width - 3, + y: thisObject.container.frame.height / 2 + } + break + } + + case 'going right': { + point1 = { + x: 4, + y: 4 + } + + point2 = { + x: 4, + y: thisObject.container.frame.height - 4 + } + + point3 = { + x: thisObject.container.frame.width - 4, + y: thisObject.container.frame.height / 2 + } + break + } + + case 'going left': { + point1 = { + x: thisObject.container.frame.width - 4, + y: 4 + } + + point2 = { + x: thisObject.container.frame.width - 4, + y: thisObject.container.frame.height - 4 + } + + point3 = { + x: 4, + y: thisObject.container.frame.height / 2 + } + break + } + + case 'right': { + point1 = { + x: thisObject.container.frame.width - 3, + y: 3 + } + + point2 = { + x: thisObject.container.frame.width - 3, + y: thisObject.container.frame.height - 3 + } + + point3 = { + x: 3, + y: thisObject.container.frame.height / 2 + } + break + } + } + /* Now the transformations. */ - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) - if (thisObject.fitFunction !== undefined) { - point1 = thisObject.fitFunction(point1) - point2 = thisObject.fitFunction(point2) - point3 = thisObject.fitFunction(point3) - } + if (thisObject.fitFunction !== undefined) { + point1 = thisObject.fitFunction(point1) + point2 = thisObject.fitFunction(point2) + point3 = thisObject.fitFunction(point3) + } /* Lets start the drawing. */ - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.lineTo(point1.x, point1.y) - browserCanvasContext.closePath() + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(250, 250, 250, 1)' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.stroke() + browserCanvasContext.strokeStyle = 'rgba(250, 250, 250, 1)' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() - browserCanvasContext.fillStyle = 'rgba(250, 250, 250, 1)' - browserCanvasContext.fill() - } + browserCanvasContext.fillStyle = 'rgba(250, 250, 250, 1)' + browserCanvasContext.fill() + } } diff --git a/Panels/PanelsVisibleButton.js b/Panels/PanelsVisibleButton.js index b2266845e..7c2528eba 100644 --- a/Panels/PanelsVisibleButton.js +++ b/Panels/PanelsVisibleButton.js @@ -1,84 +1,84 @@ -function newPanelsVisibleButton () { - let thisObject = { - container: undefined, - fitFunction: undefined, - parentContainer: undefined, - panels: undefined, - showPanels: true, - draw: draw, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } - - /* Cointainer stuff */ - thisObject.container = newContainer() - thisObject.container.name = 'Panels Visible Button' - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.frame.containerName = 'Panels Visible Button' - - let onMouseClickEventSuscriptionId - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.parentContainer = undefined - thisObject.panels = undefined - } - - function initialize (panels) { - thisObject.panels = panels - setPanelVisibility() - - thisObject.container.frame.width = 25 - thisObject.container.frame.height = 25 - - let position = { - x: thisObject.container.frame.width * 1 / 8, - y: 45 +function newPanelsVisibleButton() { + let thisObject = { + container: undefined, + fitFunction: undefined, + parentContainer: undefined, + panels: undefined, + showPanels: true, + draw: draw, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize } - thisObject.container.frame.position = position + /* Cointainer stuff */ + thisObject.container = newContainer() + thisObject.container.name = 'Panels Visible Button' + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.frame.containerName = 'Panels Visible Button' - /* Lets listen to our own events to react when we have a Mouse Click */ - onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - } + let onMouseClickEventSuscriptionId + return thisObject - function onMouseClick (event) { - if (thisObject.showPanels === false) { - thisObject.showPanels = true - } else { - thisObject.showPanels = false - } - setPanelVisibility() - } - - function setPanelVisibility () { - for (let i = 0; i < thisObject.panels.length; i++) { - panel = canvas.panelsSpace.getPanel(thisObject.panels[i]) - panel.isVisible = thisObject.showPanels - } - } - - function getContainer (point) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } - } - - function draw () { - let icon - if (thisObject.showPanels === true) { - icon = canvas.designSpace.iconCollection.get('plotter-panel') - } else { - icon = canvas.designSpace.iconCollection.get('toggle-panel-off') + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.parentContainer = undefined + thisObject.panels = undefined } - drawIcon(icon, 1 / 2, 1 / 2, 0, 0, 14, thisObject.container) - } + function initialize(panels) { + thisObject.panels = panels + setPanelVisibility() + + thisObject.container.frame.width = 25 + thisObject.container.frame.height = 25 + + let position = { + x: thisObject.container.frame.width * 1 / 8, + y: 45 + } + + thisObject.container.frame.position = position + + /* Lets listen to our own events to react when we have a Mouse Click */ + onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + } + + function onMouseClick(event) { + if (thisObject.showPanels === false) { + thisObject.showPanels = true + } else { + thisObject.showPanels = false + } + setPanelVisibility() + } + + function setPanelVisibility() { + for (let i = 0; i < thisObject.panels.length; i++) { + panel = canvas.panelsSpace.getPanel(thisObject.panels[i]) + panel.isVisible = thisObject.showPanels + } + } + + function getContainer(point) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } + } + + function draw() { + let icon + if (thisObject.showPanels === true) { + icon = canvas.designSpace.iconCollection.get('plotter-panel') + } else { + icon = canvas.designSpace.iconCollection.get('toggle-panel-off') + } + + drawIcon(icon, 1 / 2, 1 / 2, 0, 0, 14, thisObject.container) + } } diff --git a/Panels/PlotterPanel.js b/Panels/PlotterPanel.js index 2db96284a..2b02913b5 100644 --- a/Panels/PlotterPanel.js +++ b/Panels/PlotterPanel.js @@ -1,174 +1,174 @@ -function newPlotterPanel () { - const MODULE_NAME = 'Plotter Panel' - const ERROR_LOG = true - const INTENSIVE_LOG = false - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newPlotterPanel() { + const MODULE_NAME = 'Plotter Panel' + const ERROR_LOG = true + const INTENSIVE_LOG = false + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - fitFunction: undefined, - container: undefined, - isVisible: true, - onRecordChange: onRecordChange, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize('Plotter Panel') - - let heightFactor = 1 - let currentRecord - let upDownButton - let panelNode - - return thisObject - - function finalize () { - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.isVisible = undefined - - heightFactor = undefined - currentRecord = undefined - upDownButton.finalize() - upDownButton = undefined - panelNode = undefined - } - - function initialize (pPanelNode) { - panelNode = pPanelNode - thisObject.container.frame.containerName = panelNode.name - - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL - thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL - - thisObject.container.frame.position.x = canvas.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width - thisObject.container.frame.width * Math.random() * 8 - thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.bottomLeft.y - thisObject.container.frame.height - thisObject.container.frame.height * Math.random() * 1.5 - - upDownButton = newUpDownButton() - upDownButton.parentContainer = thisObject.container - upDownButton.container.frame.parentFrame = thisObject.container.frame - upDownButton.fitFunction = thisObject.fitFunction - upDownButton.initialize() - } - - function getContainer (point) { - if (thisObject.isVisible !== true) { return } - let container - - container = upDownButton.getContainer(point) - if (container !== undefined) { return container } - - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - let checkPoint = { - x: point.x, - y: point.y - } - - checkPoint = thisObject.fitFunction(checkPoint) - - if (point.x === checkPoint.x && point.y === checkPoint.y) { - return thisObject.container - } - } - } - - function onRecordChange (pCurrentRecord) { - currentRecord = pCurrentRecord - } - - function draw () { - if (thisObject.isVisible !== true) { return } - - thisObject.container.frame.draw(false, false, true, thisObject.fitFunction) - plotCurrentRecordData() - upDownButton.draw() - } - - function plotCurrentRecordData () { - const frameBodyHeight = thisObject.container.frame.getBodyHeight() - const frameTitleHeight = thisObject.container.frame.height - frameBodyHeight - - const X_AXIS = thisObject.container.frame.width / 2 - const Y_AXIS = frameTitleHeight + frameBodyHeight / 2 - - const PANEL_HEIGHT = UI_PANEL.HEIGHT.NORMAL - - if (currentRecord === undefined) { return } - let record = currentRecord - - /* First we execute code if provided. */ - if (panelNode.javascriptCode !== undefined) { - try { - eval(panelNode.javascriptCode.code) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> err = ' + err.stack) } - if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> javascriptCode.code = ' + panelNode.javascriptCode.code) } - } + let thisObject = { + fitFunction: undefined, + container: undefined, + isVisible: true, + onRecordChange: onRecordChange, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - /* Second we go through the panel data. */ - if (panelNode.panelData === undefined) { return } - for (let i = 0; i < panelNode.panelData.length; i++) { - let panelData = panelNode.panelData[i] + thisObject.container = newContainer() + thisObject.container.initialize('Plotter Panel') - let labelText = panelData.name - let labelPosition = i * 10 + 12 - let valuePosition = i * 10 + 17 - let value = 'No value defined.' + let heightFactor = 1 + let currentRecord + let upDownButton + let panelNode - if (valuePosition > 100) { - thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 1.25 - } + return thisObject - if (valuePosition > 125) { - thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 1.50 - } + function finalize() { + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.isVisible = undefined - if (valuePosition > 150) { - thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 1.75 - } + heightFactor = undefined + currentRecord = undefined + upDownButton.finalize() + upDownButton = undefined + panelNode = undefined + } - if (valuePosition > 175) { - thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 2.00 - } + function initialize(pPanelNode) { + panelNode = pPanelNode + thisObject.container.frame.containerName = panelNode.name - if (panelData.dataFormula !== undefined) { - try { - value = eval(panelData.dataFormula.code) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> err = ' + err.stack) } - if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> dataFormula.code = ' + panelData.dataFormula.code) } + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL + thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL + + thisObject.container.frame.position.x = canvas.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width - thisObject.container.frame.width * Math.random() * 8 + thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.bottomLeft.y - thisObject.container.frame.height - thisObject.container.frame.height * Math.random() * 1.5 + + upDownButton = newUpDownButton() + upDownButton.parentContainer = thisObject.container + upDownButton.container.frame.parentFrame = thisObject.container.frame + upDownButton.fitFunction = thisObject.fitFunction + upDownButton.initialize() + } + + function getContainer(point) { + if (thisObject.isVisible !== true) { return } + let container + + container = upDownButton.getContainer(point) + if (container !== undefined) { return container } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + let checkPoint = { + x: point.x, + y: point.y + } + + checkPoint = thisObject.fitFunction(checkPoint) + + if (point.x === checkPoint.x && point.y === checkPoint.y) { + return thisObject.container + } + } + } + + function onRecordChange(pCurrentRecord) { + currentRecord = pCurrentRecord + } + + function draw() { + if (thisObject.isVisible !== true) { return } + + thisObject.container.frame.draw(false, false, true, thisObject.fitFunction) + plotCurrentRecordData() + upDownButton.draw() + } + + function plotCurrentRecordData() { + const frameBodyHeight = thisObject.container.frame.getBodyHeight() + const frameTitleHeight = thisObject.container.frame.height - frameBodyHeight + + const X_AXIS = thisObject.container.frame.width / 2 + const Y_AXIS = frameTitleHeight + frameBodyHeight / 2 + + const PANEL_HEIGHT = UI_PANEL.HEIGHT.NORMAL + + if (currentRecord === undefined) { return } + let record = currentRecord + + /* First we execute code if provided. */ + if (panelNode.javascriptCode !== undefined) { + try { + eval(panelNode.javascriptCode.code) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> err = ' + err.stack) } + if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> javascriptCode.code = ' + panelNode.javascriptCode.code) } + } + } + + /* Second we go through the panel data. */ + if (panelNode.panelData === undefined) { return } + for (let i = 0; i < panelNode.panelData.length; i++) { + let panelData = panelNode.panelData[i] + + let labelText = panelData.name + let labelPosition = i * 10 + 12 + let valuePosition = i * 10 + 17 + let value = 'No value defined.' + + if (valuePosition > 100) { + thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 1.25 + } + + if (valuePosition > 125) { + thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 1.50 + } + + if (valuePosition > 150) { + thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 1.75 + } + + if (valuePosition > 175) { + thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 2.00 + } + + if (panelData.dataFormula !== undefined) { + try { + value = eval(panelData.dataFormula.code) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> err = ' + err.stack) } + if (ERROR_LOG === true) { logger.write('[ERROR] plotCurrentRecordData -> dataFormula.code = ' + panelData.dataFormula.code) } + } + } + + if (panelData.config.valueDecimals !== undefined) { + if (value !== undefined) { + if (isNaN(value) === false) { + value = dynamicDecimals(value, panelData.config.valueDecimals) + } + } + } + + if (panelData.config.labelText !== undefined) { + labelText = panelData.config.labelText + } + + if (panelData.config.labelPosition !== undefined) { + labelPosition = panelData.config.labelPosition + } + + if (panelData.config.valuePosition !== undefined) { + valuePosition = panelData.config.valuePosition + } + + printLabel(labelText, X_AXIS, UI_PANEL.HEIGHT.NORMAL * labelPosition / 100 / heightFactor, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction) + printLabel(value, X_AXIS, UI_PANEL.HEIGHT.NORMAL * valuePosition / 100 / heightFactor, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction, false, true) } - } - - if (panelData.config.valueDecimals !== undefined) { - if (value !== undefined) { - if (isNaN(value) === false) { - value = dynamicDecimals(value, panelData.config.valueDecimals) - } - } - } - - if (panelData.config.labelText !== undefined) { - labelText = panelData.config.labelText - } - - if (panelData.config.labelPosition !== undefined) { - labelPosition = panelData.config.labelPosition - } - - if (panelData.config.valuePosition !== undefined) { - valuePosition = panelData.config.valuePosition - } - - printLabel(labelText, X_AXIS, UI_PANEL.HEIGHT.NORMAL * labelPosition / 100 / heightFactor, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction) - printLabel(value, X_AXIS, UI_PANEL.HEIGHT.NORMAL * valuePosition / 100 / heightFactor, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction, false, true) } - } } diff --git a/Panels/UpDownButton.js b/Panels/UpDownButton.js index bb542d183..ffdca4eaa 100644 --- a/Panels/UpDownButton.js +++ b/Panels/UpDownButton.js @@ -1,244 +1,244 @@ -function newUpDownButton () { - let thisObject = { - container: undefined, - fitFunction: undefined, - parentContainer: undefined, - status: undefined, - setStatus: setStatus, - physics: physics, - draw: draw, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } - - let isInitialized = false - /* Cointainer stuff */ - - thisObject.container = newContainer() - thisObject.container.name = 'Up Down Button' - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.frame.containerName = 'Up Down Button' - - thisObject.status = 'up' - let upPosition = {} - let downPosition = {} - let transitionPosition = {} - - let onMouseClickEventSuscriptionId - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.parentContainer = undefined - - thisObject.status = undefined - upPosition = undefined - downPosition = undefined - transitionPosition = undefined - } - - function initialize () { - thisObject.container.frame.width = 12 - thisObject.container.frame.height = 12 - - let position = { - x: thisObject.container.frame.parentFrame.width * 5.75 / 8 - thisObject.container.frame.width / 2, - y: 40 * 4 / 8 - thisObject.container.frame.height / 2 +function newUpDownButton() { + let thisObject = { + container: undefined, + fitFunction: undefined, + parentContainer: undefined, + status: undefined, + setStatus: setStatus, + physics: physics, + draw: draw, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize } - thisObject.container.frame.position = position + let isInitialized = false + /* Cointainer stuff */ - upPosition.x = thisObject.parentContainer.frame.position.x - upPosition.y = thisObject.parentContainer.frame.position.y + thisObject.container = newContainer() + thisObject.container.name = 'Up Down Button' + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.frame.containerName = 'Up Down Button' - downPosition.x = thisObject.parentContainer.frame.position.x - downPosition.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y + thisObject.status = 'up' + let upPosition = {} + let downPosition = {} + let transitionPosition = {} - transitionPosition.x = upPosition.x - transitionPosition.y = upPosition.y + let onMouseClickEventSuscriptionId + return thisObject - /* Lets listen to our own events to react when we have a Mouse Click */ - onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.parentContainer = undefined - isInitialized = true - } - - function setStatus (value) { - if (value === 'up' && thisObject.status === 'down') { - thisObject.status = 'going up' + thisObject.status = undefined + upPosition = undefined + downPosition = undefined + transitionPosition = undefined } - if (value === 'down' && thisObject.status === 'up') { - thisObject.status = 'going down' + + function initialize() { + thisObject.container.frame.width = 12 + thisObject.container.frame.height = 12 + + let position = { + x: thisObject.container.frame.parentFrame.width * 5.75 / 8 - thisObject.container.frame.width / 2, + y: 40 * 4 / 8 - thisObject.container.frame.height / 2 + } + + thisObject.container.frame.position = position + + upPosition.x = thisObject.parentContainer.frame.position.x + upPosition.y = thisObject.parentContainer.frame.position.y + + downPosition.x = thisObject.parentContainer.frame.position.x + downPosition.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y + + transitionPosition.x = upPosition.x + transitionPosition.y = upPosition.y + + /* Lets listen to our own events to react when we have a Mouse Click */ + onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + + isInitialized = true } - } - function onMouseClick (event) { - if (thisObject.status === 'up') { - transitionPosition.x = upPosition.x - transitionPosition.y = upPosition.y - - thisObject.status = 'going down' - } else { - transitionPosition.x = downPosition.x - transitionPosition.y = downPosition.y - - thisObject.status = 'going up' + function setStatus(value) { + if (value === 'up' && thisObject.status === 'down') { + thisObject.status = 'going up' + } + if (value === 'down' && thisObject.status === 'up') { + thisObject.status = 'going down' + } } - } - function physics () { - if (isInitialized === false) { return } + function onMouseClick(event) { + if (thisObject.status === 'up') { + transitionPosition.x = upPosition.x + transitionPosition.y = upPosition.y - upPosition.x = thisObject.parentContainer.frame.position.x - upPosition.y = canvas.chartingSpace.viewport.visibleArea.topRight.y + thisObject.status = 'going down' + } else { + transitionPosition.x = downPosition.x + transitionPosition.y = downPosition.y - downPosition.x = thisObject.parentContainer.frame.position.x - downPosition.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y - - if (thisObject.status === 'going down') { - if (transitionPosition.y < downPosition.y) { - transitionPosition.y = transitionPosition.y + 50 - thisObject.parentContainer.frame.position.y = transitionPosition.y - } else { - thisObject.parentContainer.frame.position.y = downPosition.y - thisObject.status = 'down' - } + thisObject.status = 'going up' + } } - if (thisObject.status === 'going up') { - if (transitionPosition.y > upPosition.y) { - transitionPosition.y = transitionPosition.y - 50 - thisObject.parentContainer.frame.position.y = transitionPosition.y - } else { - thisObject.parentContainer.frame.position.y = upPosition.y - thisObject.status = 'up' - } + + function physics() { + if (isInitialized === false) { return } + + upPosition.x = thisObject.parentContainer.frame.position.x + upPosition.y = canvas.chartingSpace.viewport.visibleArea.topRight.y + + downPosition.x = thisObject.parentContainer.frame.position.x + downPosition.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y + + if (thisObject.status === 'going down') { + if (transitionPosition.y < downPosition.y) { + transitionPosition.y = transitionPosition.y + 50 + thisObject.parentContainer.frame.position.y = transitionPosition.y + } else { + thisObject.parentContainer.frame.position.y = downPosition.y + thisObject.status = 'down' + } + } + if (thisObject.status === 'going up') { + if (transitionPosition.y > upPosition.y) { + transitionPosition.y = transitionPosition.y - 50 + thisObject.parentContainer.frame.position.y = transitionPosition.y + } else { + thisObject.parentContainer.frame.position.y = upPosition.y + thisObject.status = 'up' + } + } } - } - function draw () { - if (isInitialized === false) { return } + function draw() { + if (isInitialized === false) { return } - drawButton() - } - - function getContainer (point, purpose) { - let container - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container + drawButton() } - } - function drawButton () { - let point1 - let point2 - let point3 - - switch (thisObject.status) { - case 'up': { - point1 = { - x: 3, - y: 3 + function getContainer(point, purpose) { + let container + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container } - - point2 = { - x: thisObject.container.frame.width - 3, - y: 3 - } - - point3 = { - x: thisObject.container.frame.width / 2, - y: thisObject.container.frame.height - 3 - } - break - } - - case 'going down': { - point1 = { - x: 4, - y: 4 - } - - point2 = { - x: thisObject.container.frame.width - 4, - y: 4 - } - - point3 = { - x: thisObject.container.frame.width / 2, - y: thisObject.container.frame.height - 4 - } - break - } - - case 'going up': { - point1 = { - x: 4, - y: thisObject.container.frame.height - 4 - } - - point2 = { - x: thisObject.container.frame.width - 4, - y: thisObject.container.frame.height - 4 - } - - point3 = { - x: thisObject.container.frame.width / 2, - y: 4 - } - break - } - - case 'down': { - point1 = { - x: 3, - y: thisObject.container.frame.height - 3 - } - - point2 = { - x: thisObject.container.frame.width - 3, - y: thisObject.container.frame.height - 3 - } - - point3 = { - x: thisObject.container.frame.width / 2, - y: 3 - } - break - } } + function drawButton() { + let point1 + let point2 + let point3 + + switch (thisObject.status) { + case 'up': { + point1 = { + x: 3, + y: 3 + } + + point2 = { + x: thisObject.container.frame.width - 3, + y: 3 + } + + point3 = { + x: thisObject.container.frame.width / 2, + y: thisObject.container.frame.height - 3 + } + break + } + + case 'going down': { + point1 = { + x: 4, + y: 4 + } + + point2 = { + x: thisObject.container.frame.width - 4, + y: 4 + } + + point3 = { + x: thisObject.container.frame.width / 2, + y: thisObject.container.frame.height - 4 + } + break + } + + case 'going up': { + point1 = { + x: 4, + y: thisObject.container.frame.height - 4 + } + + point2 = { + x: thisObject.container.frame.width - 4, + y: thisObject.container.frame.height - 4 + } + + point3 = { + x: thisObject.container.frame.width / 2, + y: 4 + } + break + } + + case 'down': { + point1 = { + x: 3, + y: thisObject.container.frame.height - 3 + } + + point2 = { + x: thisObject.container.frame.width - 3, + y: thisObject.container.frame.height - 3 + } + + point3 = { + x: thisObject.container.frame.width / 2, + y: 3 + } + break + } + } + /* Now the transformations. */ - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) - if (thisObject.fitFunction !== undefined) { - point1 = thisObject.fitFunction(point1) - point2 = thisObject.fitFunction(point2) - point3 = thisObject.fitFunction(point3) - } + if (thisObject.fitFunction !== undefined) { + point1 = thisObject.fitFunction(point1) + point2 = thisObject.fitFunction(point2) + point3 = thisObject.fitFunction(point3) + } /* Lets start the drawing. */ - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.lineTo(point1.x, point1.y) - browserCanvasContext.closePath() + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(250, 250, 250, 1)' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.stroke() + browserCanvasContext.strokeStyle = 'rgba(250, 250, 250, 1)' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() - browserCanvasContext.fillStyle = 'rgba(250, 250, 250, 1)' - browserCanvasContext.fill() - } + browserCanvasContext.fillStyle = 'rgba(250, 250, 250, 1)' + browserCanvasContext.fill() + } } diff --git a/Plotting/NodesAnnouncements.js b/Plotting/NodesAnnouncements.js index 16116df03..2eb21d98e 100644 --- a/Plotting/NodesAnnouncements.js +++ b/Plotting/NodesAnnouncements.js @@ -1,46 +1,46 @@ -function newNodesAnnouncements () { - const MODULE_NAME = 'Nodes Announcements' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesAnnouncements() { + const MODULE_NAME = 'Nodes Announcements' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.announcements - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let arrayItem = array[i] - let nodeId = arrayItem[0] - let value = arrayItem[1] - applyValue(nodeId, value) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } - function applyValue (nodeId, value) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === true) { value = 'true' } - if (value === false) { value = 'false' } - node.payload.uiObject.setValue(value, 20) - } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.announcements + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === true) { value = 'true' } + if (value === false) { value = 'false' } + node.payload.uiObject.setValue(value, 20) + } } diff --git a/Plotting/NodesErrors.js b/Plotting/NodesErrors.js index 1a083597d..5d1ce2d1a 100644 --- a/Plotting/NodesErrors.js +++ b/Plotting/NodesErrors.js @@ -1,47 +1,47 @@ -function newNodesErrors () { - const MODULE_NAME = 'Nodes Errors' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesErrors() { + const MODULE_NAME = 'Nodes Errors' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.errors - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let arrayItem = array[i] - let nodeId = arrayItem[0] - let value = arrayItem[1] - applyValue(nodeId, value) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } + let hiriarchyMap + return thisObject - function applyValue (nodeId, value) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === '') { - node.payload.uiObject.resetErrorMessage() - } else { - node.payload.uiObject.setErrorMessage(value) + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.errors + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === '') { + node.payload.uiObject.resetErrorMessage() + } else { + node.payload.uiObject.setErrorMessage(value) + } } - } } diff --git a/Plotting/NodesHighlights.js b/Plotting/NodesHighlights.js index 443166ad6..d843faf63 100644 --- a/Plotting/NodesHighlights.js +++ b/Plotting/NodesHighlights.js @@ -1,42 +1,42 @@ -function newNodesHighlights () { - const MODULE_NAME = 'Nodes Highlights' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesHighlights() { + const MODULE_NAME = 'Nodes Highlights' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.highlights - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let nodeId = array[i] - highlight(nodeId) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } - function highlight (nodeId) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - node.payload.uiObject.highlight(10) - } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.highlights + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let nodeId = array[i] + highlight(nodeId) + } + } + + function highlight(nodeId) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + node.payload.uiObject.highlight(10) + } } diff --git a/Plotting/NodesProgress.js b/Plotting/NodesProgress.js index cba36be9f..bd31d4802 100644 --- a/Plotting/NodesProgress.js +++ b/Plotting/NodesProgress.js @@ -1,47 +1,47 @@ -function newNodesProgress () { - const MODULE_NAME = 'Nodes Progress' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesProgress() { + const MODULE_NAME = 'Nodes Progress' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.progress - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let arrayItem = array[i] - let nodeId = arrayItem[0] - let value = arrayItem[1] - applyValue(nodeId, value) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } - function applyValue (nodeId, value) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === true) { value = 'true' } - if (value === false) { value = 'false' } - node.payload.uiObject.setPercentage(value, 30) - } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.progress + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === true) { value = 'true' } + if (value === false) { value = 'false' } + node.payload.uiObject.setPercentage(value, 30) + } } diff --git a/Plotting/NodesRunning.js b/Plotting/NodesRunning.js index 130a7a8f8..2ccaa6eeb 100644 --- a/Plotting/NodesRunning.js +++ b/Plotting/NodesRunning.js @@ -1,47 +1,47 @@ -function newNodesRunning () { - const MODULE_NAME = 'Nodes Running' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesRunning() { + const MODULE_NAME = 'Nodes Running' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.running - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let arrayItem = array[i] - let nodeId = arrayItem[0] - let value = arrayItem[1] - applyValue(nodeId, value) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } - function applyValue (nodeId, value) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === true) { value = 'true' } - if (value === false) { value = 'false' } - node.payload.uiObject.runningAtBackend() - } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.running + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === true) { value = 'true' } + if (value === false) { value = 'false' } + node.payload.uiObject.runningAtBackend() + } } diff --git a/Plotting/NodesStatus.js b/Plotting/NodesStatus.js index 699c70741..36e596f47 100644 --- a/Plotting/NodesStatus.js +++ b/Plotting/NodesStatus.js @@ -1,47 +1,47 @@ -function newNodesStatus () { - const MODULE_NAME = 'Nodes Status' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesStatus() { + const MODULE_NAME = 'Nodes Status' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.status - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let arrayItem = array[i] - let nodeId = arrayItem[0] - let value = arrayItem[1] - applyValue(nodeId, value) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } - function applyValue (nodeId, value) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === true) { value = 'true' } - if (value === false) { value = 'false' } - node.payload.uiObject.setStatus(value, 30) - } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.status + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === true) { value = 'true' } + if (value === false) { value = 'false' } + node.payload.uiObject.setStatus(value, 30) + } } diff --git a/Plotting/NodesValues.js b/Plotting/NodesValues.js index 53dfbfa60..c7fabb5e1 100644 --- a/Plotting/NodesValues.js +++ b/Plotting/NodesValues.js @@ -1,47 +1,47 @@ -function newNodesValues () { - const MODULE_NAME = 'Nodes Values' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newNodesValues() { + const MODULE_NAME = 'Nodes Values' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } - - let hiriarchyMap - return thisObject - - function finalize () { - hiriarchyMap = undefined - } - - function initialize (pRootNode) { - let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) - hiriarchyMap = getHiriarchyMap(rootNode) - } - - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - let array = currentRecord.values - if (array === undefined) { return } - for (let i = 0; i < array.length; i++) { - let arrayItem = array[i] - let nodeId = arrayItem[0] - let value = arrayItem[1] - applyValue(nodeId, value) + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize } - } - function applyValue (nodeId, value) { - if (canvas.chartingSpace.visible !== true) { return } - let node = hiriarchyMap.get(nodeId) - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === true) { value = 'true' } - if (value === false) { value = 'false' } - node.payload.uiObject.setValue(value, 1) - } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.values + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === true) { value = 'true' } + if (value === false) { value = 'false' } + node.payload.uiObject.setValue(value, 1) + } } diff --git a/Plotting/RecordValues.js b/Plotting/RecordValues.js index 8f84ba629..486e81e4c 100644 --- a/Plotting/RecordValues.js +++ b/Plotting/RecordValues.js @@ -1,92 +1,92 @@ -function newRecordValues () { - const MODULE_NAME = 'Record Values' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newRecordValues() { + const MODULE_NAME = 'Record Values' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - onRecordChange: onRecordChange, - initialize: initialize, - finalize: finalize - } + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize + } - let tradingSystem - let tradingEngine - let productDefinition - let propertyTargetNodeMap = new Map() - return thisObject + let tradingSystem + let tradingEngine + let productDefinition + let propertyTargetNodeMap = new Map() + return thisObject - function finalize () { - tradingSystem = undefined - tradingEngine = undefined - productDefinition = undefined - propertyTargetNodeMap = undefined - } + function finalize() { + tradingSystem = undefined + tradingEngine = undefined + productDefinition = undefined + propertyTargetNodeMap = undefined + } - function initialize (pTradingSystem, pTradingEngine, pProductDefinition) { - tradingSystem = canvas.designSpace.workspace.getHierarchyHeadsById(pTradingSystem.id) - tradingEngine = canvas.designSpace.workspace.getHierarchyHeadsById(pTradingEngine.id) - productDefinition = pProductDefinition + function initialize(pTradingSystem, pTradingEngine, pProductDefinition) { + tradingSystem = canvas.designSpace.workspace.getHierarchyHeadsById(pTradingSystem.id) + tradingEngine = canvas.designSpace.workspace.getHierarchyHeadsById(pTradingEngine.id) + productDefinition = pProductDefinition - /* - The product root can be a node or a node property of type array. - */ - let productRoot = eval(productDefinition.config.nodePath) - - if (productDefinition.config.nodePathType === 'array') { /* - This means that the configured nodePath is not pointing to a node, but to a node property that is an array. - For that reason we will assume that each element of the array is a record to be outputed + The product root can be a node or a node property of type array. */ - for (let index = 0; index < productRoot.length; index++) { + let productRoot = eval(productDefinition.config.nodePath) + + if (productDefinition.config.nodePathType === 'array') { + /* + This means that the configured nodePath is not pointing to a node, but to a node property that is an array. + For that reason we will assume that each element of the array is a record to be outputed + */ + for (let index = 0; index < productRoot.length; index++) { + /* + The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values. + */ + let productRootNode = productRoot[index] + scanProperties(productRootNode, index) + } + } else { + /* + This means that the configured nodePath points to a single node, which is the one whose children constitutes + the record to be saved at the output file. + */ /* The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values. */ - let productRootNode = productRoot[index] - scanProperties(productRootNode, index) - } - } else { - /* - This means that the configured nodePath points to a single node, which is the one whose children constitutes - the record to be saved at the output file. - */ - /* - The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values. - */ - let productRootNode = productRoot - scanProperties(productRootNode) - } - - function scanProperties (productRootNode, index) { - for (let i = 0; i < productDefinition.record.properties.length; i++) { - let property = productDefinition.record.properties[i] - if (property.config.nodePath !== undefined) { - let propertyRoot = eval(property.config.nodePath) - propertyTargetNodeMap.set(property.id, propertyRoot) - } else { - propertyTargetNodeMap.set(property.id, productRootNode) + let productRootNode = productRoot + scanProperties(productRootNode) } - } - } - } - function onRecordChange (currentRecord) { - if (currentRecord === undefined) { return } - for (let i = 0; i < productDefinition.record.properties.length; i++) { - let property = productDefinition.record.properties[i] - let value = currentRecord[property.config.codeName] - let targetNode = propertyTargetNodeMap.get(property.id) - applyValue(targetNode[property.config.codeName], value) + function scanProperties(productRootNode, index) { + for (let i = 0; i < productDefinition.record.properties.length; i++) { + let property = productDefinition.record.properties[i] + if (property.config.nodePath !== undefined) { + let propertyRoot = eval(property.config.nodePath) + propertyTargetNodeMap.set(property.id, propertyRoot) + } else { + propertyTargetNodeMap.set(property.id, productRootNode) + } + } + } } - } - function applyValue (node, value) { - if (canvas.chartingSpace.visible !== true) { return } - if (node === undefined) { return } - if (node === undefined) { return } - if (node.payload === undefined) { return } - if (node.payload.uiObject === undefined) { return } - if (value === true) { value = 'true' } - if (value === false) { value = 'false' } - node.payload.uiObject.setValue(value, 1) - } + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + for (let i = 0; i < productDefinition.record.properties.length; i++) { + let property = productDefinition.record.properties[i] + let value = currentRecord[property.config.codeName] + let targetNode = propertyTargetNodeMap.get(property.id) + applyValue(targetNode[property.config.codeName], value) + } + } + + function applyValue(node, value) { + if (canvas.chartingSpace.visible !== true) { return } + if (node === undefined) { return } + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === true) { value = 'true' } + if (value === false) { value = 'false' } + node.payload.uiObject.setValue(value, 1) + } } diff --git a/PostLoader.js b/PostLoader.js index 82c268bec..8dd748334 100644 --- a/PostLoader.js +++ b/PostLoader.js @@ -4,86 +4,86 @@ let markets let APP_SCHEMA_MAP = new Map() let APP_SCHEMA_ARRAY = [] -function newDashboard () { - const MODULE_NAME = 'Dashboard' - const ERROR_LOG = true - const INTENSIVE_LOG = false - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newDashboard() { + const MODULE_NAME = 'Dashboard' + const ERROR_LOG = true + const INTENSIVE_LOG = false + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - start: start - } - - const DEBUG_START_UP_DELAY = 0 // 3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time. - - return thisObject - - function start () { - try { - setBrowserEvents() - setUpAppSchema() - - function setUpAppSchema () { - APP_SCHEMA_ARRAY = getAppSchema() - for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { - let nodeDefinition = APP_SCHEMA_ARRAY[i] - let key = nodeDefinition.type - APP_SCHEMA_MAP.set(key, nodeDefinition) - } - startCanvas() - } - - function startCanvas () { - /* If this method is executed for a second time, it should finalize the current execution structure */ - - if (canvas !== undefined) { canvas.finalize() } - - setTimeout(delayedStart, DEBUG_START_UP_DELAY) - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] start -> err = ' + err.stack) } + let thisObject = { + start: start } - } - function delayedStart () { - try { + const DEBUG_START_UP_DELAY = 0 // 3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time. + + return thisObject + + function start() { + try { + setBrowserEvents() + setUpAppSchema() + + function setUpAppSchema() { + APP_SCHEMA_ARRAY = getAppSchema() + for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { + let nodeDefinition = APP_SCHEMA_ARRAY[i] + let key = nodeDefinition.type + APP_SCHEMA_MAP.set(key, nodeDefinition) + } + startCanvas() + } + + function startCanvas() { + /* If this method is executed for a second time, it should finalize the current execution structure */ + + if (canvas !== undefined) { canvas.finalize() } + + setTimeout(delayedStart, DEBUG_START_UP_DELAY) + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] start -> err = ' + err.stack) } + } + } + + function delayedStart() { + try { /* For now, we are supporting only one market. */ - let market = { - id: 2, - baseAsset: 'USDT', - quotedAsset: 'BTC' - } + let market = { + id: 2, + baseAsset: 'USDT', + quotedAsset: 'BTC' + } - markets = new Map() + markets = new Map() - markets.set(market.id, market) + markets.set(market.id, market) - canvas = newCanvas() - canvas.initialize() - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] delayedStart -> err = ' + err.stack) } - } - } - - function setBrowserEvents () { - window.onbeforeunload = saveWorkspace - - /* handles backspace and refresh(F5) from keyboard */ - window.manageBackRefresh = function (event) { - var tag = event.target.tagName.toLowerCase() - if (event.keyCode == 8 && tag != 'input' && tag != 'textarea') { // Backbutton pressed - saveWorkspace() - } else if (event.keyCode == 116) { // F5 pressed - saveWorkspace() - } + canvas = newCanvas() + canvas.initialize() + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] delayedStart -> err = ' + err.stack) } + } } - window.addEventListener('keydown', window.manageBackRefresh) + function setBrowserEvents() { + window.onbeforeunload = saveWorkspace - function saveWorkspace () { - canvas.designSpace.workspace.save() + /* handles backspace and refresh(F5) from keyboard */ + window.manageBackRefresh = function (event) { + var tag = event.target.tagName.toLowerCase() + if (event.keyCode == 8 && tag != 'input' && tag != 'textarea') { // Backbutton pressed + saveWorkspace() + } else if (event.keyCode == 116) { // F5 pressed + saveWorkspace() + } + } + + window.addEventListener('keydown', window.manageBackRefresh) + + function saveWorkspace() { + canvas.designSpace.workspace.save() + } } - } } diff --git a/ProductStorage.js b/ProductStorage.js index 57c8e6b8a..6f83e19b2 100644 --- a/ProductStorage.js +++ b/ProductStorage.js @@ -1,9 +1,9 @@ -  -function newProductStorage (name) { - const MODULE_NAME = 'Product Storage' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME + +function newProductStorage(name) { + const MODULE_NAME = 'Product Storage' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME /* @@ -24,310 +24,310 @@ function newProductStorage (name) { */ - let thisObject = { - eventHandler: undefined, - marketFiles: [], - dailyFiles: [], - singleFile: [], - fileSequences: [], - setDatetime: setDatetime, - setTimeFrame: setTimeFrame, - initialize: initialize, - finalize: finalize - } + let thisObject = { + eventHandler: undefined, + marketFiles: [], + dailyFiles: [], + singleFile: [], + fileSequences: [], + setDatetime: setDatetime, + setTimeFrame: setTimeFrame, + initialize: initialize, + finalize: finalize + } - thisObject.eventHandler = newEventHandler() + thisObject.eventHandler = newEventHandler() /* We name the event Handler to easy debugging. */ - thisObject.eventHandler.name = 'Storage-' + name + thisObject.eventHandler.name = 'Storage-' + name - let datetime - let timeFrame + let datetime + let timeFrame - return thisObject + return thisObject - function finalize () { - try { - for (let i = 0; i < thisObject.marketFiles.length; i++) { - let marketFile = thisObject.marketFiles[i] - marketFile.finalize() - } + function finalize() { + try { + for (let i = 0; i < thisObject.marketFiles.length; i++) { + let marketFile = thisObject.marketFiles[i] + marketFile.finalize() + } - thisObject.marketFiles = undefined + thisObject.marketFiles = undefined - for (let i = 0; i < thisObject.dailyFiles.length; i++) { - let dailyFile = thisObject.dailyFiles[i] - dailyFile.finalize() - } + for (let i = 0; i < thisObject.dailyFiles.length; i++) { + let dailyFile = thisObject.dailyFiles[i] + dailyFile.finalize() + } - thisObject.dailyFiles = undefined + thisObject.dailyFiles = undefined - for (let i = 0; i < thisObject.fileSequences.length; i++) { - let fileSequence = thisObject.fileSequences[i] - fileSequence.finalize() - } + for (let i = 0; i < thisObject.fileSequences.length; i++) { + let fileSequence = thisObject.fileSequences[i] + fileSequence.finalize() + } - thisObject.fileSequences = undefined - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) } + thisObject.fileSequences = undefined + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) } + } } - } - function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, callBackFunction) { - try { - datetime = pDatetime - timeFrame = pTimeFrame + function initialize(dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, callBackFunction) { + try { + datetime = pDatetime + timeFrame = pTimeFrame - let dataSetsToLoad = 0 - let dataSetsLoaded = 0 + let dataSetsToLoad = 0 + let dataSetsLoaded = 0 - for (let i = 0; i < product.datasets.length; i++) { - let dataset = product.datasets[i] + for (let i = 0; i < product.datasets.length; i++) { + let dataset = product.datasets[i] - switch (dataset.config.type) { - case 'Market Files': { - dataSetsToLoad++ + switch (dataset.config.type) { + case 'Market Files': { + dataSetsToLoad++ - let marketFiles = newMarketFiles() - marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onMarketFileReady) - thisObject.marketFiles.push(marketFiles) - } - break + let marketFiles = newMarketFiles() + marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onMarketFileReady) + thisObject.marketFiles.push(marketFiles) + } + break - case 'Daily Files': { - dataSetsToLoad++ + case 'Daily Files': { + dataSetsToLoad++ - let dailyFiles = newDailyFiles() - dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, onDailyFileReady) - thisObject.dailyFiles.push(dailyFiles) - } - break + let dailyFiles = newDailyFiles() + dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, onDailyFileReady) + thisObject.dailyFiles.push(dailyFiles) + } + break - case 'Single File': { - dataSetsToLoad++ + case 'Single File': { + dataSetsToLoad++ - let singleFile = newSingleFile() - singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onSingleFileReady) - thisObject.singleFile.push(singleFile) - } - break + let singleFile = newSingleFile() + singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onSingleFileReady) + thisObject.singleFile.push(singleFile) + } + break - case 'File Sequence': { - dataSetsToLoad++ + case 'File Sequence': { + dataSetsToLoad++ - let fileSequences = newFileSequence() - fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onFileSequenceReady) - thisObject.fileSequences.push(fileSequences) - } - break - default: - if (ERROR_LOG === true) { logger.write('[WARN] initialize -> dataset with no type defined or type not supported -> dataset.config.type = ' + dataset.config.type) } - } - - function onMarketFileReady (err, pCaller) { - try { - switch (err.result) { - case GLOBAL.DEFAULT_OK_RESPONSE.result: { - break - } - case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - } - let event = { - totalValue: pCaller.getExpectedFiles(), - currentValue: pCaller.getFilesLoaded(), - filesNotLoaded: pCaller.getFilesNotLoaded() - } - - thisObject.eventHandler.raiseEvent('Market File Loaded', event) - - if (event.filesNotLoaded === event.totalValue) { - dataSetsToLoad-- - checkInitializeComplete() - return - } - - if (event.currentValue + event.filesNotLoaded === event.totalValue) { - dataSetsLoaded++ - checkInitializeComplete() - } - } catch (err) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } - } - - function onDailyFileReady (err, pCaller) { - try { - switch (err.result) { - case GLOBAL.DEFAULT_OK_RESPONSE.result: { - break - } - - case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - case GLOBAL.CUSTOM_FAIL_RESPONSE.result: { - if (err.message === 'Dataset Unavailable.') { - dataSetsToLoad-- - checkInitializeComplete() - return - } else { - callBackFunction(err) - return + let fileSequences = newFileSequence() + fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onFileSequenceReady) + thisObject.fileSequences.push(fileSequences) + } + break + default: + if (ERROR_LOG === true) { logger.write('[WARN] initialize -> dataset with no type defined or type not supported -> dataset.config.type = ' + dataset.config.type) } } - } - default: { - callBackFunction(err) - return - } - } - let event = { - totalValue: pCaller.getExpectedFiles(), - currentValue: pCaller.getFilesLoaded() - } + function onMarketFileReady(err, pCaller) { + try { + switch (err.result) { + case GLOBAL.DEFAULT_OK_RESPONSE.result: { + break + } + case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + } + let event = { + totalValue: pCaller.getExpectedFiles(), + currentValue: pCaller.getFilesLoaded(), + filesNotLoaded: pCaller.getFilesNotLoaded() + } - thisObject.eventHandler.raiseEvent('Daily File Loaded', event) + thisObject.eventHandler.raiseEvent('Market File Loaded', event) - if (event.currentValue === event.totalValue) { - dataSetsLoaded++ - checkInitializeComplete() + if (event.filesNotLoaded === event.totalValue) { + dataSetsToLoad-- + checkInitializeComplete() + return + } + + if (event.currentValue + event.filesNotLoaded === event.totalValue) { + dataSetsLoaded++ + checkInitializeComplete() + } + } catch (err) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } + + function onDailyFileReady(err, pCaller) { + try { + switch (err.result) { + case GLOBAL.DEFAULT_OK_RESPONSE.result: { + break + } + + case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + case GLOBAL.CUSTOM_FAIL_RESPONSE.result: { + if (err.message === 'Dataset Unavailable.') { + dataSetsToLoad-- + checkInitializeComplete() + return + } else { + callBackFunction(err) + return + } + } + default: { + callBackFunction(err) + return + } + } + + let event = { + totalValue: pCaller.getExpectedFiles(), + currentValue: pCaller.getFilesLoaded() + } + + thisObject.eventHandler.raiseEvent('Daily File Loaded', event) + + if (event.currentValue === event.totalValue) { + dataSetsLoaded++ + checkInitializeComplete() + } + } catch (err) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } + + function onSingleFileReady(err, pCaller) { + try { + switch (err.result) { + case GLOBAL.DEFAULT_OK_RESPONSE.result: { + break + } + + case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + case GLOBAL.CUSTOM_FAIL_RESPONSE.result: { + callBackFunction(err) + return + } + + default: { + callBackFunction(err) + return + } + } + let event = { + totalValue: 1, + currentValue: 1 + } + thisObject.eventHandler.raiseEvent('Single File Loaded', event) + + if (event.currentValue === event.totalValue) { + dataSetsLoaded++ + checkInitializeComplete() + } + } catch (err) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } + + function onFileSequenceReady(err, pCaller) { + try { + switch (err.result) { + case GLOBAL.DEFAULT_OK_RESPONSE.result: { + break + } + case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + case GLOBAL.CUSTOM_FAIL_RESPONSE.result: { + callBackFunction(err) + return + } + default: { + callBackFunction(err) + return + } + } + let event + if (pCaller !== undefined) { + event = { + totalValue: pCaller.getExpectedFiles(), + currentValue: pCaller.getFilesLoaded() + } + } else { // When there are no data the reference to the caller wont arrive here. + event = { + totalValue: 1, + currentValue: 1 + } + } + + thisObject.eventHandler.raiseEvent('File Sequence Loaded', event) + + if (event.currentValue === event.totalValue) { + dataSetsLoaded++ + checkInitializeComplete() + } + } catch (err) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } + + function checkInitializeComplete() { + try { + if (dataSetsLoaded === dataSetsToLoad) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> checkInitializeComplete -> err = ' + err.stack) } + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + } + } } - } catch (err) { + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } } - - function onSingleFileReady (err, pCaller) { - try { - switch (err.result) { - case GLOBAL.DEFAULT_OK_RESPONSE.result: { - break - } - - case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - case GLOBAL.CUSTOM_FAIL_RESPONSE.result: { - callBackFunction(err) - return - } - - default: { - callBackFunction(err) - return - } - } - let event = { - totalValue: 1, - currentValue: 1 - } - thisObject.eventHandler.raiseEvent('Single File Loaded', event) - - if (event.currentValue === event.totalValue) { - dataSetsLoaded++ - checkInitializeComplete() - } - } catch (err) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } - } - - function onFileSequenceReady (err, pCaller) { - try { - switch (err.result) { - case GLOBAL.DEFAULT_OK_RESPONSE.result: { - break - } - case GLOBAL.DEFAULT_FAIL_RESPONSE.result: { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - case GLOBAL.CUSTOM_FAIL_RESPONSE.result: { - callBackFunction(err) - return - } - default: { - callBackFunction(err) - return - } - } - let event - if (pCaller !== undefined) { - event = { - totalValue: pCaller.getExpectedFiles(), - currentValue: pCaller.getFilesLoaded() - } - } else { // When there are no data the reference to the caller wont arrive here. - event = { - totalValue: 1, - currentValue: 1 - } - } - - thisObject.eventHandler.raiseEvent('File Sequence Loaded', event) - - if (event.currentValue === event.totalValue) { - dataSetsLoaded++ - checkInitializeComplete() - } - } catch (err) { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } - } - - function checkInitializeComplete () { - try { - if (dataSetsLoaded === dataSetsToLoad) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> checkInitializeComplete -> err = ' + err.stack) } - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) } - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) } - } - function setDatetime (pDatetime) { + function setDatetime(pDatetime) { /* If there is a change in the day, then we take some actions, otherwise, we dont. */ - let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) - let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS) + let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) + let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS) - datetime = new Date(pDatetime) + datetime = new Date(pDatetime) - if (currentDate !== newDate) { - if (timeFrame <= _1_HOUR_IN_MILISECONDS) { - for (let i = 0; i < thisObject.dailyFiles.length; i++) { - thisObject.dailyFiles[i].setDatetime(pDatetime) + if (currentDate !== newDate) { + if (timeFrame <= _1_HOUR_IN_MILISECONDS) { + for (let i = 0; i < thisObject.dailyFiles.length; i++) { + thisObject.dailyFiles[i].setDatetime(pDatetime) + } + } } - } } - } - function setTimeFrame (pTimeFrame) { + function setTimeFrame(pTimeFrame) { /* We are going to filter out the cases in which the timeFrame received is the same that the one we already know. */ - if (timeFrame !== pTimeFrame) { - timeFrame = pTimeFrame + if (timeFrame !== pTimeFrame) { + timeFrame = pTimeFrame - if (timeFrame <= _1_HOUR_IN_MILISECONDS) { - for (let i = 0; i < thisObject.dailyFiles.length; i++) { - thisObject.dailyFiles[i].setTimeFrame(pTimeFrame, datetime) + if (timeFrame <= _1_HOUR_IN_MILISECONDS) { + for (let i = 0; i < thisObject.dailyFiles.length; i++) { + thisObject.dailyFiles[i].setTimeFrame(pTimeFrame, datetime) + } + } } - } } - } } diff --git a/Scales/AutoScaleButton.js b/Scales/AutoScaleButton.js index 597f1c2b2..5e56c6984 100644 --- a/Scales/AutoScaleButton.js +++ b/Scales/AutoScaleButton.js @@ -1,206 +1,206 @@ -function newAutoScaleButton () { - let thisObject = { - container: undefined, - fitFunction: undefined, - parentContainer: undefined, - autoMinScale: undefined, - autoMaxScale: undefined, - setStatus: setStatus, - draw: draw, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } +function newAutoScaleButton() { + let thisObject = { + container: undefined, + fitFunction: undefined, + parentContainer: undefined, + autoMinScale: undefined, + autoMaxScale: undefined, + setStatus: setStatus, + draw: draw, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize + } - /* Cointainer stuff */ - thisObject.container = newContainer() - thisObject.container.name = 'Auto Scale Button' - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.frame.containerName = 'Auto Scale Button' + /* Cointainer stuff */ + thisObject.container = newContainer() + thisObject.container.name = 'Auto Scale Button' + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.frame.containerName = 'Auto Scale Button' - const ICON_SIZE = 36 - let onMouseWheelEventSubscriptionId - let coordinateSystem - let axis - let currentStatus - return thisObject + const ICON_SIZE = 36 + let onMouseWheelEventSubscriptionId + let coordinateSystem + let axis + let currentStatus + return thisObject - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.parentContainer = undefined - thisObject.panels = undefined + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.parentContainer = undefined + thisObject.panels = undefined - coordinateSystem = undefined - axis = undefined - } + coordinateSystem = undefined + axis = undefined + } - function initialize (pAxis, pCoordinateSystem) { - axis = pAxis - coordinateSystem = pCoordinateSystem - thisObject.autoMinScale = coordinateSystem.autoMinYScale - thisObject.autoMaxScale = coordinateSystem.autoMaxYScale + function initialize(pAxis, pCoordinateSystem) { + axis = pAxis + coordinateSystem = pCoordinateSystem + thisObject.autoMinScale = coordinateSystem.autoMinYScale + thisObject.autoMaxScale = coordinateSystem.autoMaxYScale - switch (axis) { - case 'X': { - thisObject.container.frame.width = ICON_SIZE - thisObject.container.frame.height = ICON_SIZE + switch (axis) { + case 'X': { + thisObject.container.frame.width = ICON_SIZE + thisObject.container.frame.height = ICON_SIZE - let position = { - x: thisObject.container.parentContainer.frame.width * 7 / 8, - y: thisObject.container.parentContainer.frame.height / 2 + let position = { + x: thisObject.container.parentContainer.frame.width * 7 / 8, + y: thisObject.container.parentContainer.frame.height / 2 + } + + thisObject.container.frame.position = position + break + } + case 'Y': { + thisObject.container.frame.width = ICON_SIZE + thisObject.container.frame.height = ICON_SIZE + + let position = { + x: thisObject.container.parentContainer.frame.width * 7 / 8, + y: thisObject.container.parentContainer.frame.height / 2 + } + + thisObject.container.frame.position = position + break + } } - - thisObject.container.frame.position = position - break - } - case 'Y': { - thisObject.container.frame.width = ICON_SIZE - thisObject.container.frame.height = ICON_SIZE - - let position = { - x: thisObject.container.parentContainer.frame.width * 7 / 8, - y: thisObject.container.parentContainer.frame.height / 2 - } - - thisObject.container.frame.position = position - break - } - } - onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - } - - function setStatus (autoMinScale, autoMaxScale) { - thisObject.autoMinScale = autoMinScale - thisObject.autoMaxScale = autoMaxScale - - if (thisObject.autoMinScale === false && thisObject.autoMaxScale === false) { - currentStatus = 1 - } - if (thisObject.autoMinScale === true && thisObject.autoMaxScale === false) { - currentStatus = 2 - } - if (thisObject.autoMinScale === false && thisObject.autoMaxScale === true) { - currentStatus = 4 - } - if (thisObject.autoMinScale === true && thisObject.autoMaxScale === true) { - currentStatus = 6 - } - } - function onMouseWheel (event) { - let factor - let delta = event.wheelDelta - if (delta < 0) { - delta = -1 - } else { - delta = 1 - } - currentStatus = currentStatus + delta - if (currentStatus === 7) { currentStatus = 1 } - if (currentStatus === 0) { currentStatus = 6 } - - switch (currentStatus) { - case 1: { - thisObject.autoMinScale = false - thisObject.autoMaxScale = false - update() - return - } - case 2: { - thisObject.autoMinScale = true - thisObject.autoMaxScale = false - update() - return - } - case 3: { - thisObject.autoMinScale = false - thisObject.autoMaxScale = false - update() - return - } - case 4: { - thisObject.autoMinScale = false - thisObject.autoMaxScale = true - update() - return - } - case 5: { - thisObject.autoMinScale = false - thisObject.autoMaxScale = false - update() - return - } - case 6: { - thisObject.autoMinScale = true - thisObject.autoMaxScale = true - update() - return - } + onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) } - function update () { - switch (axis) { - case 'X': { - coordinateSystem.autoMinXScale = thisObject.autoMinScale - coordinateSystem.autoMaxXScale = thisObject.autoMaxScale - break - } - case 'Y': { - coordinateSystem.autoMinYScale = thisObject.autoMinScale - coordinateSystem.autoMaxYScale = thisObject.autoMaxScale - break - } - } + function setStatus(autoMinScale, autoMaxScale) { + thisObject.autoMinScale = autoMinScale + thisObject.autoMaxScale = autoMaxScale - coordinateSystem.recalculateScale() - } - } - - function getContainer (point, purpose) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } - } - - function draw () { - let icon - switch (axis) { - case 'X': { if (thisObject.autoMinScale === false && thisObject.autoMaxScale === false) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-manual') + currentStatus = 1 } if (thisObject.autoMinScale === true && thisObject.autoMaxScale === false) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-auto-min') + currentStatus = 2 } if (thisObject.autoMinScale === false && thisObject.autoMaxScale === true) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-auto-max') + currentStatus = 4 } if (thisObject.autoMinScale === true && thisObject.autoMaxScale === true) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-auto-min-max') + currentStatus = 6 + } + } + function onMouseWheel(event) { + let factor + let delta = event.wheelDelta + if (delta < 0) { + delta = -1 + } else { + delta = 1 + } + currentStatus = currentStatus + delta + if (currentStatus === 7) { currentStatus = 1 } + if (currentStatus === 0) { currentStatus = 6 } + + switch (currentStatus) { + case 1: { + thisObject.autoMinScale = false + thisObject.autoMaxScale = false + update() + return + } + case 2: { + thisObject.autoMinScale = true + thisObject.autoMaxScale = false + update() + return + } + case 3: { + thisObject.autoMinScale = false + thisObject.autoMaxScale = false + update() + return + } + case 4: { + thisObject.autoMinScale = false + thisObject.autoMaxScale = true + update() + return + } + case 5: { + thisObject.autoMinScale = false + thisObject.autoMaxScale = false + update() + return + } + case 6: { + thisObject.autoMinScale = true + thisObject.autoMaxScale = true + update() + return + } + } + + function update() { + switch (axis) { + case 'X': { + coordinateSystem.autoMinXScale = thisObject.autoMinScale + coordinateSystem.autoMaxXScale = thisObject.autoMaxScale + break + } + case 'Y': { + coordinateSystem.autoMinYScale = thisObject.autoMinScale + coordinateSystem.autoMaxYScale = thisObject.autoMaxScale + break + } + } + + coordinateSystem.recalculateScale() + } + } + + function getContainer(point, purpose) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } + } + + function draw() { + let icon + switch (axis) { + case 'X': { + if (thisObject.autoMinScale === false && thisObject.autoMaxScale === false) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-manual') + } + if (thisObject.autoMinScale === true && thisObject.autoMaxScale === false) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-auto-min') + } + if (thisObject.autoMinScale === false && thisObject.autoMaxScale === true) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-auto-max') + } + if (thisObject.autoMinScale === true && thisObject.autoMaxScale === true) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-time-scale-auto-min-max') + } + drawIcon(icon, 0, 0, 0, 0, ICON_SIZE, thisObject.container) + break + } + case 'Y': { + if (thisObject.autoMinScale === false && thisObject.autoMaxScale === false) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-manual') + } + if (thisObject.autoMinScale === true && thisObject.autoMaxScale === false) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-auto-min') + } + if (thisObject.autoMinScale === false && thisObject.autoMaxScale === true) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-auto-max') + } + if (thisObject.autoMinScale === true && thisObject.autoMaxScale === true) { + icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-auto-min-max') + } + drawIcon(icon, 0, 0, 0, 0, ICON_SIZE, thisObject.container) + break + } } - drawIcon(icon, 0, 0, 0, 0, ICON_SIZE, thisObject.container) - break - } - case 'Y': { - if (thisObject.autoMinScale === false && thisObject.autoMaxScale === false) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-manual') - } - if (thisObject.autoMinScale === true && thisObject.autoMaxScale === false) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-auto-min') - } - if (thisObject.autoMinScale === false && thisObject.autoMaxScale === true) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-auto-max') - } - if (thisObject.autoMinScale === true && thisObject.autoMaxScale === true) { - icon = canvas.designSpace.iconCollection.get('toggle-auto-scale-auto-min-max') - } - drawIcon(icon, 0, 0, 0, 0, ICON_SIZE, thisObject.container) - break - } } - } } diff --git a/Scales/Commons.js b/Scales/Commons.js index 49dda6e71..13f926ca3 100644 --- a/Scales/Commons.js +++ b/Scales/Commons.js @@ -1,45 +1,45 @@ -function drawScaleDisplay (label1, label2, label3, xExtraOffSet1, xExtraOffSet2, xExtraOffSet3, icon1, icon2, container, backgroundColor) { - const RED_LINE_HIGHT = 4 - const OPACITY = 1 +function drawScaleDisplay(label1, label2, label3, xExtraOffSet1, xExtraOffSet2, xExtraOffSet3, icon1, icon2, container, backgroundColor) { + const RED_LINE_HIGHT = 4 + const OPACITY = 1 - let params = { - cornerRadius: 5, - lineWidth: 1, - container: container, - borderColor: UI_COLOR.RUSTED_RED, - castShadow: false, - backgroundColor: backgroundColor, - opacity: OPACITY - } + let params = { + cornerRadius: 5, + lineWidth: 1, + container: container, + borderColor: UI_COLOR.RUSTED_RED, + castShadow: false, + backgroundColor: backgroundColor, + opacity: OPACITY + } - roundedCornersBackground(params) + roundedCornersBackground(params) - /* Place the Text */ + /* Place the Text */ - label1 = label1.substring(0, 18) - label2 = label2.substring(0, 20) - label3 = label3.substring(0, 20) + label1 = label1.substring(0, 18) + label2 = label2.substring(0, 20) + label3 = label3.substring(0, 20) - drawLabel(label1, 1 / 2, 92 / 100, 0, 0, 9, container) - drawLabel(label2, 1 / 2, 42 / 100, 0, 0, 17, container) - drawLabel(label3, 1 / 2, 67 / 100, 0, 0, 9, container) + drawLabel(label1, 1 / 2, 92 / 100, 0, 0, 9, container) + drawLabel(label2, 1 / 2, 42 / 100, 0, 0, 17, container) + drawLabel(label3, 1 / 2, 67 / 100, 0, 0, 9, container) - drawIcon(icon1, 1 / 8, 1 / 2, 0, 0, 28, container) - drawIcon(icon2, 7 / 8, 1 / 2, 0, 0, 28, container) + drawIcon(icon1, 1 / 8, 1 / 2, 0, 0, 28, container) + drawIcon(icon2, 7 / 8, 1 / 2, 0, 0, 28, container) } -function drawScaleDisplayCover (container) { - let params = { - cornerRadius: 5, - lineWidth: 1, - container: container, - borderColor: UI_COLOR.WHITE, - castShadow: false, - backgroundColor: UI_COLOR.WHITE, - opacity: '0.25' - } +function drawScaleDisplayCover(container) { + let params = { + cornerRadius: 5, + lineWidth: 1, + container: container, + borderColor: UI_COLOR.WHITE, + castShadow: false, + backgroundColor: UI_COLOR.WHITE, + opacity: '0.25' + } - roundedCornersBackground(params) + roundedCornersBackground(params) } diff --git a/Scales/RateScale.js b/Scales/RateScale.js index 93ca0cf9d..216de1e8e 100644 --- a/Scales/RateScale.js +++ b/Scales/RateScale.js @@ -1,566 +1,566 @@ -function newRateScale () { - const MODULE_NAME = 'Right Scale' +function newRateScale() { + const MODULE_NAME = 'Right Scale' - let thisObject = { - container: undefined, - rate: undefined, - fitFunction: undefined, - payload: undefined, - minValue: undefined, - maxValue: undefined, - isVisible: true, - layersOn: undefined, - onUpstreamScaleChanged: onUpstreamScaleChanged, - onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer, - physics: physics, - draw: draw, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isClickeable = false - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL - thisObject.container.frame.height = 40 - - let draggeableContainer = newContainer() - draggeableContainer.initialize(MODULE_NAME + ' Draggeable') - draggeableContainer.isDraggeable = true - - let visible = true - let isMouseOver - - let onMouseWheelEventSubscriptionId - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - let onScaleChangedEventSubscriptionId - let onDragStartedEventSubscriptionId - - let coordinateSystem - let coordinateSystemWhenDragStarted - - let limitingContainer - let rateCalculationsContainer - - mouseWhenDragStarted = { - position: { - x: 0, - y: 0 - } - } - - parentFrameWhenDragStarted = { - position: { - x: 0, - y: 0 - }, - width: 0, - height: 0 - } - - let scaleDisplayTimer = 0 - let autoScaleButton - - let wheelDeltaDirection - let wheelDeltaCounter = 0 - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - coordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onDragStartedEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.payload = undefined - - if (coordinateSystemWhenDragStarted !== undefined) { - coordinateSystemWhenDragStarted.finalize() + let thisObject = { + container: undefined, + rate: undefined, + fitFunction: undefined, + payload: undefined, + minValue: undefined, + maxValue: undefined, + isVisible: true, + layersOn: undefined, + onUpstreamScaleChanged: onUpstreamScaleChanged, + onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer, + physics: physics, + draw: draw, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - coordinateSystemWhenDragStarted = undefined + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - coordinateSystem = undefined - limitingContainer = undefined - rateCalculationsContainer = undefined + thisObject.container.isDraggeable = false + thisObject.container.isClickeable = false + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true - mouseWhenDragStarted = undefined - parentFrameWhenDragStarted = undefined + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL + thisObject.container.frame.height = 40 - autoScaleButton.finalize() - autoScaleButton = undefined - } + let draggeableContainer = newContainer() + draggeableContainer.initialize(MODULE_NAME + ' Draggeable') + draggeableContainer.isDraggeable = true - function initialize (pCoordinateSystem, pLimitingContainer, pRateCalculationsContainer) { - coordinateSystem = pCoordinateSystem - limitingContainer = pLimitingContainer - rateCalculationsContainer = pRateCalculationsContainer + let visible = true + let isMouseOver - thisObject.minValue = coordinateSystem.min.y - thisObject.maxValue = coordinateSystem.max.y + let onMouseWheelEventSubscriptionId + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + let onScaleChangedEventSubscriptionId + let onDragStartedEventSubscriptionId - onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - onScaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) - onDragStartedEventSubscriptionId = draggeableContainer.eventHandler.listenToEvent('onDragStarted', onDragStarted) + let coordinateSystem + let coordinateSystemWhenDragStarted - autoScaleButton = newAutoScaleButton() - autoScaleButton.container.connectToParent(thisObject.container) - autoScaleButton.initialize('Y', coordinateSystem) + let limitingContainer + let rateCalculationsContainer - readObjectState() - } - - function onMouseOverSomeTimeMachineContainer (event) { - if (event.containerId === undefined) { - /* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */ - visible = true - } else { - if (event.containerId === thisObject.container.id) { - visible = true - } else { - visible = false - turnOnCounter = 0 - } - } - } - - function onScaleChanged () { - saveObjectState() - } - - function onMouseOver (event) { - isMouseOver = true - event.containerId = thisObject.container.id - thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event) - } - - function onMouseNotOver () { - isMouseOver = false - scaleDisplayTimer = 0 - } - - function onMouseWheel (event) { - if (IS_MAC) { - let sensitivity - if (event.wheelDelta < 0) { - if (event.shiftKey === true) { - sensitivity = 20 - } else { - sensitivity = 5 - } - if (wheelDeltaDirection === -1) { - wheelDeltaCounter++ - if (wheelDeltaCounter < sensitivity) { - return - } else { - wheelDeltaCounter = 0 - } - } else { - wheelDeltaCounter = 0 - wheelDeltaDirection = -1 - return - } - } else { - if (wheelDeltaDirection === 1) { - wheelDeltaCounter++ - if (wheelDeltaCounter < sensitivity) { - return - } else { - wheelDeltaCounter = 0 - } - } else { - wheelDeltaCounter = 0 - wheelDeltaDirection = 1 - return - } - } - } - - if (event.shiftKey === true) { - autoScaleButton.container.eventHandler.raiseEvent('onMouseWheel', event) - return - } - - let factor - let morePower = 10 - if (event.buttons === 4) { morePower = 1 } // Mouse wheel pressed. - - let delta = event.wheelDelta - if (delta < 0) { - factor = -0.01 * morePower - } else { - factor = 0.01 * morePower - } - - coordinateSystem.zoomY(factor, event, limitingContainer) - scaleDisplayTimer = 100 - } - - function onDragStarted (event) { mouseWhenDragStarted = { - position: { - x: event.x, - y: event.y - } + position: { + x: 0, + y: 0 + } } parentFrameWhenDragStarted = { - position: { - x: limitingContainer.frame.position.x, - y: limitingContainer.frame.position.y - }, - width: limitingContainer.frame.width, - height: limitingContainer.frame.height + position: { + x: 0, + y: 0 + }, + width: 0, + height: 0 } - coordinateSystemWhenDragStarted = newCoordinateSystem() + let scaleDisplayTimer = 0 + let autoScaleButton - let minValue = { - x: coordinateSystem.min.x, - y: coordinateSystem.min.y - } + let wheelDeltaDirection + let wheelDeltaCounter = 0 - let maxValue = { - x: coordinateSystem.max.x, - y: coordinateSystem.max.y - } + return thisObject - coordinateSystemWhenDragStarted.initialize(minValue, maxValue, coordinateSystem.maxWidth, coordinateSystem.maxHeight) - } + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) + coordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onDragStartedEventSubscriptionId) - function getContainer (point, purpose) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - if (purpose === GET_CONTAINER_PURPOSE.DRAGGING) { - return draggeableContainer - } + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.payload = undefined - return thisObject.container - } - } - - function saveObjectState () { - try { - let config = JSON.parse(thisObject.payload.node.config) - config.minValue = coordinateSystem.min.y - config.maxValue = coordinateSystem.max.y - config.autoMinScale = coordinateSystem.autoMinYScale - config.autoMaxScale = coordinateSystem.autoMaxYScale - thisObject.payload.node.config = JSON.stringify(config, null, 4) - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } - } - - function readObjectState () { - try { - let config = JSON.parse(thisObject.payload.node.config) - - if ( - (isNaN(config.minValue) || config.minValue === null || config.minValue === undefined) || - (isNaN(config.maxValue) || config.maxValue === null || config.maxValue === undefined) - ) { - // not using this value - } else { - if ( - thisObject.minValue !== config.minValue || - thisObject.maxValue !== config.maxValue || - coordinateSystem.autoMinYScale !== config.autoMinScale || - coordinateSystem.autoMaxYScale !== config.autoMaxScale - ) { - thisObject.minValue = config.minValue - thisObject.maxValue = config.maxValue - coordinateSystem.min.y = thisObject.minValue - coordinateSystem.max.y = thisObject.maxValue - - if (config.autoMinScale !== undefined && (config.autoMinScale === true || config.autoMinScale === false) && config.autoMaxScale !== undefined && (config.autoMaxScale === true || config.autoMaxScale === false)) { - coordinateSystem.autoMinYScale = config.autoMinScale - coordinateSystem.autoMaxYScale = config.autoMaxScale - autoScaleButton.setStatus(config.autoMinScale, config.autoMaxScale) - } - - coordinateSystem.recalculateScale() + if (coordinateSystemWhenDragStarted !== undefined) { + coordinateSystemWhenDragStarted.finalize() } - } - saveObjectState() // this overrides any invalid value at the config. - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } - } - function physics () { - scaleDisplayTimer-- - readObjectState() - positioningPhysics() - draggingPhysics() - } + coordinateSystemWhenDragStarted = undefined - function draggingPhysics () { - if (coordinateSystemWhenDragStarted === undefined) { return } - if (draggeableContainer.frame.position.y === 0) { return } + coordinateSystem = undefined + limitingContainer = undefined + rateCalculationsContainer = undefined - let mouseNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(canvas.mouse.position) - let mouseWhenDragStartedNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mouseWhenDragStarted.position) + mouseWhenDragStarted = undefined + parentFrameWhenDragStarted = undefined - let dragVectorWhenDragStarted = { - x: 0, - y: mouseNoZoom.y - mouseWhenDragStartedNoZoom.y + autoScaleButton.finalize() + autoScaleButton = undefined } - let dragVector = { - x: 0, - y: draggeableContainer.frame.position.y + function initialize(pCoordinateSystem, pLimitingContainer, pRateCalculationsContainer) { + coordinateSystem = pCoordinateSystem + limitingContainer = pLimitingContainer + rateCalculationsContainer = pRateCalculationsContainer + + thisObject.minValue = coordinateSystem.min.y + thisObject.maxValue = coordinateSystem.max.y + + onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + onScaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) + onDragStartedEventSubscriptionId = draggeableContainer.eventHandler.listenToEvent('onDragStarted', onDragStarted) + + autoScaleButton = newAutoScaleButton() + autoScaleButton.container.connectToParent(thisObject.container) + autoScaleButton.initialize('Y', coordinateSystem) + + readObjectState() } - draggeableContainer.frame.position.y = 0 - - let point = { - x: 0, - y: (-dragVectorWhenDragStarted.y) - } - - let newMaxRate = getRateFromPointAtContainer(point, limitingContainer, coordinateSystemWhenDragStarted) - let yDifferenceMaxMin = coordinateSystemWhenDragStarted.max.y - coordinateSystemWhenDragStarted.min.y - - coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin - coordinateSystem.max.y = newMaxRate - let event = { - type: 'center dragged', - dragVector: dragVector - } - coordinateSystem.recalculateScale() - } - - function onUpstreamScaleChanged (event) { - if (event === undefined) { return } - if (event.dragVector.y === 0) { return } - if (event.type === 'center dragged') { - let point = { - x: event.dragVector.x, - y: -event.dragVector.y - } - let newMaxRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem) - let yDifferenceMaxMin = coordinateSystem.max.y - coordinateSystem.min.y - coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin - coordinateSystem.max.y = newMaxRate - - coordinateSystem.recalculateScale() - } - if (event.type === 'top dragged') { - let point = { - x: event.dragVector.x, - y: event.dragVector.y - } - let newMaxRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem) - - coordinateSystem.max.y = newMaxRate - coordinateSystem.maxHeight = rateCalculationsContainer.frame.height - coordinateSystem.recalculateScale() - } - if (event.type === 'bottom dragged') { - let point = { - x: event.dragVector.x, - y: event.dragVector.y + rateCalculationsContainer.frame.height - } - let newMinRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem) - - coordinateSystem.min.y = newMinRate - coordinateSystem.maxHeight = rateCalculationsContainer.frame.height - coordinateSystem.recalculateScale() - } - } - - function positioningPhysics () { - /* Container Limits */ - - let upCorner = { - x: 0, - y: 0 - } - - let bottonCorner = { - x: limitingContainer.frame.width, - y: limitingContainer.frame.height - } - - upCorner = transformThisPoint(upCorner, limitingContainer) - bottonCorner = transformThisPoint(bottonCorner, limitingContainer) - - upCorner = limitingContainer.fitFunction(upCorner, true) - bottonCorner = limitingContainer.fitFunction(bottonCorner, true) - - /* We will check if we need to change the bottom because of being one of many scales of the same type */ - let displaceFactor = 0 - if (thisObject.payload.parentNode === undefined) { return } // This happens when in the process of deleting the scale, timeline chart or time machine. - if (thisObject.payload.parentNode.type === 'Timeline Chart') { - if (thisObject.payload.parentNode.payload.parentNode !== undefined) { - if (thisObject.payload.parentNode.payload.parentNode.rateScale !== undefined) { - if (thisObject.payload.parentNode.payload.parentNode.rateScale.payload.isVisible === true) { - displaceFactor++ - } - } - for (let i = 0; i < thisObject.payload.parentNode.payload.parentNode.timelineCharts.length; i++) { - let timelineChart = thisObject.payload.parentNode.payload.parentNode.timelineCharts[i] - if (timelineChart.rateScale !== undefined) { - if (thisObject.payload.node.id !== timelineChart.rateScale.id) { - if (timelineChart.rateScale.payload.isVisible === true) { - displaceFactor++ - } + function onMouseOverSomeTimeMachineContainer(event) { + if (event.containerId === undefined) { + /* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */ + visible = true + } else { + if (event.containerId === thisObject.container.id) { + visible = true } else { - break + visible = false + turnOnCounter = 0 } - } } - } - } - bottonCorner.x = bottonCorner.x - thisObject.container.frame.width * displaceFactor - - /* Mouse Position Rate Calculation */ - let ratePoint = { - x: 0, - y: canvas.mouse.position.y } - thisObject.rate = getRateFromPointAtBrowserCanvas(ratePoint, rateCalculationsContainer, coordinateSystem) - - /* rateScale Positioning */ - ratePoint = { - x: limitingContainer.frame.width, - y: 0 + function onScaleChanged() { + saveObjectState() } - ratePoint = transformThisPoint(ratePoint, limitingContainer.frame.container) - ratePoint.y = canvas.mouse.position.y - thisObject.container.frame.height / 2 + thisObject.container.frame.height - - /* Checking against the container limits. */ - if (ratePoint.x < upCorner.x) { ratePoint.x = upCorner.x } - if (ratePoint.x + thisObject.container.frame.width > bottonCorner.x) { ratePoint.x = bottonCorner.x } - if (ratePoint.y < upCorner.y + thisObject.container.frame.height) { ratePoint.y = upCorner.y + thisObject.container.frame.height } - if (ratePoint.y > bottonCorner.y) { ratePoint.y = bottonCorner.y } - - thisObject.container.frame.position.y = ratePoint.y - thisObject.container.frame.height - thisObject.container.frame.position.x = ratePoint.x - thisObject.container.frame.width - - thisObject.isVisible = true - thisObject.payload.isVisible = true - if (thisObject.container.frame.position.y + thisObject.container.frame.height * 2 > bottonCorner.y || - thisObject.container.frame.position.y - thisObject.container.frame.height * 1 < upCorner.y || - thisObject.container.frame.position.x < upCorner.x - ) { - thisObject.isVisible = false - thisObject.payload.isVisible = false - } - if (thisObject.layersOn === 0) { - thisObject.isVisible = false - thisObject.payload.isVisible = false + function onMouseOver(event) { + isMouseOver = true + event.containerId = thisObject.container.id + thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event) } - if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES) { - thisObject.isVisible = false - } - } - - function draw () { - drawScaleBox() - autoScaleButton.draw() - if (visible === false) { - drawScaleDisplayCover(thisObject.container) - } - } - - function drawForeground () { - if (isMouseOver === true) { - drawScaleBox() - autoScaleButton.draw() - } - } - - function drawBackground () { - drawScale() - } - - function drawScale () { - const SEPARATION = 50 - const NUMBER_OF_LABELS = Math.trunc(canvas.chartingSpace.viewport.height / SEPARATION) - const FONT_SIZE = 15 - - for (let i = 0; i <= NUMBER_OF_LABELS; i++) { - let ratePoint1 = { - x: 0, - y: TOP_SPACE_HEIGHT + SEPARATION * (i + 1) - } - let ratePoint2 = { - x: 0, - y: TOP_SPACE_HEIGHT + SEPARATION * (i + 0) - } - - let rate = getRateFromPointAtBrowserCanvas(ratePoint1, rateCalculationsContainer, coordinateSystem) - let labels = scaleLabels(rate) - let decimalsDisplace = labels[1].length * FONT_SIZE * FONT_ASPECT_RATIO - - let fitPoint1 = thisObject.fitFunction(ratePoint1) - let fitPoint2 = thisObject.fitFunction(ratePoint2) - - if (fitPoint1.y === ratePoint1.y && fitPoint2.y === ratePoint2.y) { - drawLabel(labels[1], 1 / 2, 0, 0, 0, FONT_SIZE, thisObject.container, UI_COLOR.GREY, undefined, ratePoint1.y) - drawLabel(labels[2], 1 / 2, 0, decimalsDisplace, -5, 9, thisObject.container, UI_COLOR.GREY, undefined, ratePoint1.y) - } - } - } - - function drawScaleBox () { - if (thisObject.rate === undefined) { return } - if (thisObject.payload === undefined) { return } - if (thisObject.payload.node === undefined) { return } - - let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) - let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) - - let backgroundColor = UI_COLOR.BLACK - let labels = scaleLabels(thisObject.rate) - - drawScaleDisplay(labels[0], labels[1], labels[2], 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor) - } - - function scaleLabels (rate) { - if (rate < coordinateSystem.min.y) { - rate = coordinateSystem.min.y - } - if (rate > coordinateSystem.max.y) { - rate = coordinateSystem.max.y + function onMouseNotOver() { + isMouseOver = false + scaleDisplayTimer = 0 } - let label = dynamicDecimals(rate) - let labelArray = label.split('.') - let label1 = thisObject.payload.node.payload.parentNode.name - let label2 = (Math.trunc(rate)).toLocaleString() - let label3 = labelArray[1] - if (label3 === undefined) { label3 = '00' } + function onMouseWheel(event) { + if (IS_MAC) { + let sensitivity + if (event.wheelDelta < 0) { + if (event.shiftKey === true) { + sensitivity = 20 + } else { + sensitivity = 5 + } + if (wheelDeltaDirection === -1) { + wheelDeltaCounter++ + if (wheelDeltaCounter < sensitivity) { + return + } else { + wheelDeltaCounter = 0 + } + } else { + wheelDeltaCounter = 0 + wheelDeltaDirection = -1 + return + } + } else { + if (wheelDeltaDirection === 1) { + wheelDeltaCounter++ + if (wheelDeltaCounter < sensitivity) { + return + } else { + wheelDeltaCounter = 0 + } + } else { + wheelDeltaCounter = 0 + wheelDeltaDirection = 1 + return + } + } + } - if (rate < 1) { - label2 = label - label3 = '' + if (event.shiftKey === true) { + autoScaleButton.container.eventHandler.raiseEvent('onMouseWheel', event) + return + } + + let factor + let morePower = 10 + if (event.buttons === 4) { morePower = 1 } // Mouse wheel pressed. + + let delta = event.wheelDelta + if (delta < 0) { + factor = -0.01 * morePower + } else { + factor = 0.01 * morePower + } + + coordinateSystem.zoomY(factor, event, limitingContainer) + scaleDisplayTimer = 100 } - if (scaleDisplayTimer > 0) { - label2 = (coordinateSystem.scale.y * 10000).toFixed(2) - label3 = 'SCALE' + function onDragStarted(event) { + mouseWhenDragStarted = { + position: { + x: event.x, + y: event.y + } + } + + parentFrameWhenDragStarted = { + position: { + x: limitingContainer.frame.position.x, + y: limitingContainer.frame.position.y + }, + width: limitingContainer.frame.width, + height: limitingContainer.frame.height + } + + coordinateSystemWhenDragStarted = newCoordinateSystem() + + let minValue = { + x: coordinateSystem.min.x, + y: coordinateSystem.min.y + } + + let maxValue = { + x: coordinateSystem.max.x, + y: coordinateSystem.max.y + } + + coordinateSystemWhenDragStarted.initialize(minValue, maxValue, coordinateSystem.maxWidth, coordinateSystem.maxHeight) } - return [label1, label2, label3] - } + function getContainer(point, purpose) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + if (purpose === GET_CONTAINER_PURPOSE.DRAGGING) { + return draggeableContainer + } + + return thisObject.container + } + } + + function saveObjectState() { + try { + let config = JSON.parse(thisObject.payload.node.config) + config.minValue = coordinateSystem.min.y + config.maxValue = coordinateSystem.max.y + config.autoMinScale = coordinateSystem.autoMinYScale + config.autoMaxScale = coordinateSystem.autoMaxYScale + thisObject.payload.node.config = JSON.stringify(config, null, 4) + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } + } + + function readObjectState() { + try { + let config = JSON.parse(thisObject.payload.node.config) + + if ( + (isNaN(config.minValue) || config.minValue === null || config.minValue === undefined) || + (isNaN(config.maxValue) || config.maxValue === null || config.maxValue === undefined) + ) { + // not using this value + } else { + if ( + thisObject.minValue !== config.minValue || + thisObject.maxValue !== config.maxValue || + coordinateSystem.autoMinYScale !== config.autoMinScale || + coordinateSystem.autoMaxYScale !== config.autoMaxScale + ) { + thisObject.minValue = config.minValue + thisObject.maxValue = config.maxValue + coordinateSystem.min.y = thisObject.minValue + coordinateSystem.max.y = thisObject.maxValue + + if (config.autoMinScale !== undefined && (config.autoMinScale === true || config.autoMinScale === false) && config.autoMaxScale !== undefined && (config.autoMaxScale === true || config.autoMaxScale === false)) { + coordinateSystem.autoMinYScale = config.autoMinScale + coordinateSystem.autoMaxYScale = config.autoMaxScale + autoScaleButton.setStatus(config.autoMinScale, config.autoMaxScale) + } + + coordinateSystem.recalculateScale() + } + } + saveObjectState() // this overrides any invalid value at the config. + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } + } + + function physics() { + scaleDisplayTimer-- + readObjectState() + positioningPhysics() + draggingPhysics() + } + + function draggingPhysics() { + if (coordinateSystemWhenDragStarted === undefined) { return } + if (draggeableContainer.frame.position.y === 0) { return } + + let mouseNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(canvas.mouse.position) + let mouseWhenDragStartedNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mouseWhenDragStarted.position) + + let dragVectorWhenDragStarted = { + x: 0, + y: mouseNoZoom.y - mouseWhenDragStartedNoZoom.y + } + + let dragVector = { + x: 0, + y: draggeableContainer.frame.position.y + } + + draggeableContainer.frame.position.y = 0 + + let point = { + x: 0, + y: (-dragVectorWhenDragStarted.y) + } + + let newMaxRate = getRateFromPointAtContainer(point, limitingContainer, coordinateSystemWhenDragStarted) + let yDifferenceMaxMin = coordinateSystemWhenDragStarted.max.y - coordinateSystemWhenDragStarted.min.y + + coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin + coordinateSystem.max.y = newMaxRate + let event = { + type: 'center dragged', + dragVector: dragVector + } + coordinateSystem.recalculateScale() + } + + function onUpstreamScaleChanged(event) { + if (event === undefined) { return } + if (event.dragVector.y === 0) { return } + if (event.type === 'center dragged') { + let point = { + x: event.dragVector.x, + y: -event.dragVector.y + } + let newMaxRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem) + let yDifferenceMaxMin = coordinateSystem.max.y - coordinateSystem.min.y + coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin + coordinateSystem.max.y = newMaxRate + + coordinateSystem.recalculateScale() + } + if (event.type === 'top dragged') { + let point = { + x: event.dragVector.x, + y: event.dragVector.y + } + let newMaxRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem) + + coordinateSystem.max.y = newMaxRate + coordinateSystem.maxHeight = rateCalculationsContainer.frame.height + coordinateSystem.recalculateScale() + } + if (event.type === 'bottom dragged') { + let point = { + x: event.dragVector.x, + y: event.dragVector.y + rateCalculationsContainer.frame.height + } + let newMinRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem) + + coordinateSystem.min.y = newMinRate + coordinateSystem.maxHeight = rateCalculationsContainer.frame.height + coordinateSystem.recalculateScale() + } + } + + function positioningPhysics() { + /* Container Limits */ + + let upCorner = { + x: 0, + y: 0 + } + + let bottonCorner = { + x: limitingContainer.frame.width, + y: limitingContainer.frame.height + } + + upCorner = transformThisPoint(upCorner, limitingContainer) + bottonCorner = transformThisPoint(bottonCorner, limitingContainer) + + upCorner = limitingContainer.fitFunction(upCorner, true) + bottonCorner = limitingContainer.fitFunction(bottonCorner, true) + + /* We will check if we need to change the bottom because of being one of many scales of the same type */ + let displaceFactor = 0 + if (thisObject.payload.parentNode === undefined) { return } // This happens when in the process of deleting the scale, timeline chart or time machine. + if (thisObject.payload.parentNode.type === 'Timeline Chart') { + if (thisObject.payload.parentNode.payload.parentNode !== undefined) { + if (thisObject.payload.parentNode.payload.parentNode.rateScale !== undefined) { + if (thisObject.payload.parentNode.payload.parentNode.rateScale.payload.isVisible === true) { + displaceFactor++ + } + } + for (let i = 0; i < thisObject.payload.parentNode.payload.parentNode.timelineCharts.length; i++) { + let timelineChart = thisObject.payload.parentNode.payload.parentNode.timelineCharts[i] + if (timelineChart.rateScale !== undefined) { + if (thisObject.payload.node.id !== timelineChart.rateScale.id) { + if (timelineChart.rateScale.payload.isVisible === true) { + displaceFactor++ + } + } else { + break + } + } + } + } + } + bottonCorner.x = bottonCorner.x - thisObject.container.frame.width * displaceFactor + + /* Mouse Position Rate Calculation */ + let ratePoint = { + x: 0, + y: canvas.mouse.position.y + } + + thisObject.rate = getRateFromPointAtBrowserCanvas(ratePoint, rateCalculationsContainer, coordinateSystem) + + /* rateScale Positioning */ + ratePoint = { + x: limitingContainer.frame.width, + y: 0 + } + + ratePoint = transformThisPoint(ratePoint, limitingContainer.frame.container) + ratePoint.y = canvas.mouse.position.y - thisObject.container.frame.height / 2 + thisObject.container.frame.height + + /* Checking against the container limits. */ + if (ratePoint.x < upCorner.x) { ratePoint.x = upCorner.x } + if (ratePoint.x + thisObject.container.frame.width > bottonCorner.x) { ratePoint.x = bottonCorner.x } + if (ratePoint.y < upCorner.y + thisObject.container.frame.height) { ratePoint.y = upCorner.y + thisObject.container.frame.height } + if (ratePoint.y > bottonCorner.y) { ratePoint.y = bottonCorner.y } + + thisObject.container.frame.position.y = ratePoint.y - thisObject.container.frame.height + thisObject.container.frame.position.x = ratePoint.x - thisObject.container.frame.width + + thisObject.isVisible = true + thisObject.payload.isVisible = true + if (thisObject.container.frame.position.y + thisObject.container.frame.height * 2 > bottonCorner.y || + thisObject.container.frame.position.y - thisObject.container.frame.height * 1 < upCorner.y || + thisObject.container.frame.position.x < upCorner.x + ) { + thisObject.isVisible = false + thisObject.payload.isVisible = false + } + if (thisObject.layersOn === 0) { + thisObject.isVisible = false + thisObject.payload.isVisible = false + } + + if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES) { + thisObject.isVisible = false + } + } + + function draw() { + drawScaleBox() + autoScaleButton.draw() + if (visible === false) { + drawScaleDisplayCover(thisObject.container) + } + } + + function drawForeground() { + if (isMouseOver === true) { + drawScaleBox() + autoScaleButton.draw() + } + } + + function drawBackground() { + drawScale() + } + + function drawScale() { + const SEPARATION = 50 + const NUMBER_OF_LABELS = Math.trunc(canvas.chartingSpace.viewport.height / SEPARATION) + const FONT_SIZE = 15 + + for (let i = 0; i <= NUMBER_OF_LABELS; i++) { + let ratePoint1 = { + x: 0, + y: TOP_SPACE_HEIGHT + SEPARATION * (i + 1) + } + let ratePoint2 = { + x: 0, + y: TOP_SPACE_HEIGHT + SEPARATION * (i + 0) + } + + let rate = getRateFromPointAtBrowserCanvas(ratePoint1, rateCalculationsContainer, coordinateSystem) + let labels = scaleLabels(rate) + let decimalsDisplace = labels[1].length * FONT_SIZE * FONT_ASPECT_RATIO + + let fitPoint1 = thisObject.fitFunction(ratePoint1) + let fitPoint2 = thisObject.fitFunction(ratePoint2) + + if (fitPoint1.y === ratePoint1.y && fitPoint2.y === ratePoint2.y) { + drawLabel(labels[1], 1 / 2, 0, 0, 0, FONT_SIZE, thisObject.container, UI_COLOR.GREY, undefined, ratePoint1.y) + drawLabel(labels[2], 1 / 2, 0, decimalsDisplace, -5, 9, thisObject.container, UI_COLOR.GREY, undefined, ratePoint1.y) + } + } + } + + function drawScaleBox() { + if (thisObject.rate === undefined) { return } + if (thisObject.payload === undefined) { return } + if (thisObject.payload.node === undefined) { return } + + let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) + let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) + + let backgroundColor = UI_COLOR.BLACK + let labels = scaleLabels(thisObject.rate) + + drawScaleDisplay(labels[0], labels[1], labels[2], 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor) + } + + function scaleLabels(rate) { + if (rate < coordinateSystem.min.y) { + rate = coordinateSystem.min.y + } + if (rate > coordinateSystem.max.y) { + rate = coordinateSystem.max.y + } + + let label = dynamicDecimals(rate) + let labelArray = label.split('.') + let label1 = thisObject.payload.node.payload.parentNode.name + let label2 = (Math.trunc(rate)).toLocaleString() + let label3 = labelArray[1] + if (label3 === undefined) { label3 = '00' } + + if (rate < 1) { + label2 = label + label3 = '' + } + + if (scaleDisplayTimer > 0) { + label2 = (coordinateSystem.scale.y * 10000).toFixed(2) + label3 = 'SCALE' + } + + return [label1, label2, label3] + } } diff --git a/Scales/TimeFrameScale.js b/Scales/TimeFrameScale.js index 3d0d41cd0..26442ef5d 100644 --- a/Scales/TimeFrameScale.js +++ b/Scales/TimeFrameScale.js @@ -1,389 +1,389 @@ -function newTimeFrameScale () { - const MODULE_NAME = 'Time Frame Scale' +function newTimeFrameScale() { + const MODULE_NAME = 'Time Frame Scale' - let thisObject = { - timeFrame: undefined, - container: undefined, - fitFunction: undefined, - payload: undefined, - isVisible: true, - layersOn: undefined, - adjustTimeFrame: adjustTimeFrame, - onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer, - draw: draw, - drawForeground: drawForeground, - physics: physics, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - const FILES_PERIOD_DEFAULT_VALUE = 0 - const TIME_PERIOD_DEFAULT_VALUE = 0 - const MIN_HEIGHT = 50 - - let displayingRealTimeFrame = true - let greyOutCoverLayer = false - let isMouseOver - - let filePeriodIndex = FILES_PERIOD_DEFAULT_VALUE - let timeFrameIndex = TIME_PERIOD_DEFAULT_VALUE - let timeFramesMasterArray = [marketFilesPeriods, dailyFilePeriods] - let timeFrameLabel = '24-hs' - - let onMouseWheelEventSubscriptionId - let onViewportZoomChangedEventSubscriptionId - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - - let limitingContainer - - setupContainer() - - let wheelDeltaDirection - let wheelDeltaCounter = 0 - - return thisObject - - function setupContainer () { - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isClickeable = false - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL - thisObject.container.frame.height = 40 - } - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) - canvas.chartingSpace.viewport.eventHandler.stopListening(onViewportZoomChangedEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.payload = undefined - - limitingContainer = undefined - } - - function initialize (pLimitingContainer) { - limitingContainer = pLimitingContainer - - readObjectState() - newTimeFrame() - - onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - onViewportZoomChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged) - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - } - - function onMouseOverSomeTimeMachineContainer (event) { - if (event.containerId === undefined) { - /* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */ - greyOutCoverLayer = false - } else { - if (event.containerId === thisObject.container.id) { - greyOutCoverLayer = false - } else { - greyOutCoverLayer = true - turnOnCounter = 0 - } - } - } - - function onMouseOver (event) { - isMouseOver = true - event.containerId = thisObject.container.id - thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event) - } - - function onMouseNotOver () { - isMouseOver = false - } - - function physics () { - readObjectState() - positioningPhysics() - } - - function adjustTimeFrame (elementsPlotted) { - const ELEMENTS_PLOTTED_THREASHOLD = 500 - if ( - canvas.chartingSpace.viewport.zoomTargetLevel >= ZOOM_OUT_THRESHOLD_FOR_CHANGING_TIME_FRAME && - displayingRealTimeFrame === false - ) { - let event = {} - event.timeFrame = thisObject.timeFrame - thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event) - displayingRealTimeFrame = true - } - if ( - elementsPlotted > ELEMENTS_PLOTTED_THREASHOLD && - canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_CHANGING_TIME_FRAME && - displayingRealTimeFrame === true - ) { - let event = {} - event.timeFrame = ONE_DAY_IN_MILISECONDS - thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event) - displayingRealTimeFrame = false - } - } - - function positioningPhysics () { - /* Container Limits */ - - let upCorner = { - x: 0, - y: 0 + let thisObject = { + timeFrame: undefined, + container: undefined, + fitFunction: undefined, + payload: undefined, + isVisible: true, + layersOn: undefined, + adjustTimeFrame: adjustTimeFrame, + onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer, + draw: draw, + drawForeground: drawForeground, + physics: physics, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - let bottonCorner = { - x: limitingContainer.frame.width, - y: limitingContainer.frame.height + const FILES_PERIOD_DEFAULT_VALUE = 0 + const TIME_PERIOD_DEFAULT_VALUE = 0 + const MIN_HEIGHT = 50 + + let displayingRealTimeFrame = true + let greyOutCoverLayer = false + let isMouseOver + + let filePeriodIndex = FILES_PERIOD_DEFAULT_VALUE + let timeFrameIndex = TIME_PERIOD_DEFAULT_VALUE + let timeFramesMasterArray = [marketFilesPeriods, dailyFilePeriods] + let timeFrameLabel = '24-hs' + + let onMouseWheelEventSubscriptionId + let onViewportZoomChangedEventSubscriptionId + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + + let limitingContainer + + setupContainer() + + let wheelDeltaDirection + let wheelDeltaCounter = 0 + + return thisObject + + function setupContainer() { + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + + thisObject.container.isDraggeable = false + thisObject.container.isClickeable = false + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true + + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL + thisObject.container.frame.height = 40 } - upCorner = transformThisPoint(upCorner, limitingContainer) - bottonCorner = transformThisPoint(bottonCorner, limitingContainer) + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) + canvas.chartingSpace.viewport.eventHandler.stopListening(onViewportZoomChangedEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - upCorner = limitingContainer.fitFunction(upCorner, true) - bottonCorner = limitingContainer.fitFunction(bottonCorner, true) + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.payload = undefined - /* We will check if we need to change the bottom because of being one of many scales of the same type */ - let displaceFactor = 0 - if (thisObject.payload.parentNode === undefined) { return } // This happens when in the process of deleting the scale, timeline chart or time machine. - if (thisObject.payload.parentNode.type === 'Timeline Chart') { - if (thisObject.payload.parentNode.payload.parentNode !== undefined) { - if (thisObject.payload.parentNode.payload.parentNode.timeFrameScale !== undefined) { - if (thisObject.payload.parentNode.payload.parentNode.timeFrameScale.payload.isVisible === true) { - displaceFactor++ - } - } - for (let i = 0; i < thisObject.payload.parentNode.payload.parentNode.timelineCharts.length; i++) { - let timelineChart = thisObject.payload.parentNode.payload.parentNode.timelineCharts[i] - if (timelineChart.timeFrameScale !== undefined) { - if (thisObject.payload.node.id !== timelineChart.timeFrameScale.id) { - if (timelineChart.timeFrameScale.payload.isVisible === true) { - displaceFactor++ - } + limitingContainer = undefined + } + + function initialize(pLimitingContainer) { + limitingContainer = pLimitingContainer + + readObjectState() + newTimeFrame() + + onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + onViewportZoomChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged) + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + } + + function onMouseOverSomeTimeMachineContainer(event) { + if (event.containerId === undefined) { + /* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */ + greyOutCoverLayer = false + } else { + if (event.containerId === thisObject.container.id) { + greyOutCoverLayer = false } else { - break + greyOutCoverLayer = true + turnOnCounter = 0 } - } } - } - } - bottonCorner.y = bottonCorner.y - thisObject.container.frame.height * displaceFactor - - /* Positioning */ - timePoint = { - x: 0, - y: limitingContainer.frame.height } - timePoint = transformThisPoint(timePoint, limitingContainer.frame.container) - timePoint.x = canvas.mouse.position.x - thisObject.container.frame.width / 2 - - /* Checking against the container limits. */ - if (timePoint.x < upCorner.x) { timePoint.x = upCorner.x } - if (timePoint.x + thisObject.container.frame.width > bottonCorner.x) { timePoint.x = bottonCorner.x - thisObject.container.frame.width } - if (timePoint.y < upCorner.y + thisObject.container.frame.height) { timePoint.y = upCorner.y + thisObject.container.frame.height } - if (timePoint.y > bottonCorner.y) { timePoint.y = bottonCorner.y } - - thisObject.container.frame.position.x = timePoint.x - thisObject.container.frame.position.y = timePoint.y - thisObject.container.frame.height - - thisObject.isVisible = true - thisObject.payload.isVisible = true - if (thisObject.container.frame.position.y + thisObject.container.frame.height > bottonCorner.y || - thisObject.container.frame.position.y - thisObject.container.frame.height * 3 < upCorner.y || - thisObject.container.frame.position.x < upCorner.x) { - thisObject.isVisible = false - thisObject.payload.isVisible = false - } - if (thisObject.layersOn === 0) { - thisObject.isVisible = false - thisObject.payload.isVisible = false + function onMouseOver(event) { + isMouseOver = true + event.containerId = thisObject.container.id + thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event) } - if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES) { - thisObject.isVisible = false + function onMouseNotOver() { + isMouseOver = false } - } - function onViewportZoomChanged (event) { - if (event !== undefined) { // it is undefined when the level is just being animated. - if (event.shiftKey === false) { return } // with no shft key pressed, no automatic change in scale - let currentTimeFrame = thisObject.timeFrame - let timeFrame = recalculatePeriod(event.newLevel) - if (timeFrame !== currentTimeFrame) { - for (let i = 0; i < timeFramesMasterArray.length; i++) { - let timeFrameArray = timeFramesMasterArray[i] - for (let j = 0; j < timeFrameArray.length; j++) { - let record = timeFrameArray[j] - if (timeFrame === record[0]) { - filePeriodIndex = i - timeFrameIndex = j + function physics() { + readObjectState() + positioningPhysics() + } + + function adjustTimeFrame(elementsPlotted) { + const ELEMENTS_PLOTTED_THREASHOLD = 500 + if ( + canvas.chartingSpace.viewport.zoomTargetLevel >= ZOOM_OUT_THRESHOLD_FOR_CHANGING_TIME_FRAME && + displayingRealTimeFrame === false + ) { + let event = {} + event.timeFrame = thisObject.timeFrame + thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event) + displayingRealTimeFrame = true + } + if ( + elementsPlotted > ELEMENTS_PLOTTED_THREASHOLD && + canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_CHANGING_TIME_FRAME && + displayingRealTimeFrame === true + ) { + let event = {} + event.timeFrame = ONE_DAY_IN_MILISECONDS + thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event) + displayingRealTimeFrame = false + } + } + + function positioningPhysics() { + /* Container Limits */ + + let upCorner = { + x: 0, + y: 0 + } + + let bottonCorner = { + x: limitingContainer.frame.width, + y: limitingContainer.frame.height + } + + upCorner = transformThisPoint(upCorner, limitingContainer) + bottonCorner = transformThisPoint(bottonCorner, limitingContainer) + + upCorner = limitingContainer.fitFunction(upCorner, true) + bottonCorner = limitingContainer.fitFunction(bottonCorner, true) + + /* We will check if we need to change the bottom because of being one of many scales of the same type */ + let displaceFactor = 0 + if (thisObject.payload.parentNode === undefined) { return } // This happens when in the process of deleting the scale, timeline chart or time machine. + if (thisObject.payload.parentNode.type === 'Timeline Chart') { + if (thisObject.payload.parentNode.payload.parentNode !== undefined) { + if (thisObject.payload.parentNode.payload.parentNode.timeFrameScale !== undefined) { + if (thisObject.payload.parentNode.payload.parentNode.timeFrameScale.payload.isVisible === true) { + displaceFactor++ + } + } + for (let i = 0; i < thisObject.payload.parentNode.payload.parentNode.timelineCharts.length; i++) { + let timelineChart = thisObject.payload.parentNode.payload.parentNode.timelineCharts[i] + if (timelineChart.timeFrameScale !== undefined) { + if (thisObject.payload.node.id !== timelineChart.timeFrameScale.id) { + if (timelineChart.timeFrameScale.payload.isVisible === true) { + displaceFactor++ + } + } else { + break + } + } + } } - } } + bottonCorner.y = bottonCorner.y - thisObject.container.frame.height * displaceFactor + + /* Positioning */ + timePoint = { + x: 0, + y: limitingContainer.frame.height + } + + timePoint = transformThisPoint(timePoint, limitingContainer.frame.container) + timePoint.x = canvas.mouse.position.x - thisObject.container.frame.width / 2 + + /* Checking against the container limits. */ + if (timePoint.x < upCorner.x) { timePoint.x = upCorner.x } + if (timePoint.x + thisObject.container.frame.width > bottonCorner.x) { timePoint.x = bottonCorner.x - thisObject.container.frame.width } + if (timePoint.y < upCorner.y + thisObject.container.frame.height) { timePoint.y = upCorner.y + thisObject.container.frame.height } + if (timePoint.y > bottonCorner.y) { timePoint.y = bottonCorner.y } + + thisObject.container.frame.position.x = timePoint.x + thisObject.container.frame.position.y = timePoint.y - thisObject.container.frame.height + + thisObject.isVisible = true + thisObject.payload.isVisible = true + if (thisObject.container.frame.position.y + thisObject.container.frame.height > bottonCorner.y || + thisObject.container.frame.position.y - thisObject.container.frame.height * 3 < upCorner.y || + thisObject.container.frame.position.x < upCorner.x) { + thisObject.isVisible = false + thisObject.payload.isVisible = false + } + if (thisObject.layersOn === 0) { + thisObject.isVisible = false + thisObject.payload.isVisible = false + } + + if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES) { + thisObject.isVisible = false + } + } + + function onViewportZoomChanged(event) { + if (event !== undefined) { // it is undefined when the level is just being animated. + if (event.shiftKey === false) { return } // with no shft key pressed, no automatic change in scale + let currentTimeFrame = thisObject.timeFrame + let timeFrame = recalculatePeriod(event.newLevel) + if (timeFrame !== currentTimeFrame) { + for (let i = 0; i < timeFramesMasterArray.length; i++) { + let timeFrameArray = timeFramesMasterArray[i] + for (let j = 0; j < timeFrameArray.length; j++) { + let record = timeFrameArray[j] + if (timeFrame === record[0]) { + filePeriodIndex = i + timeFrameIndex = j + } + } + } + newTimeFrame() + saveObjectState() + } + } + } + + function onMouseWheel(event) { + if (IS_MAC) { + let sensitivity + if (event.wheelDelta < 0) { + if (event.shiftKey === true) { + sensitivity = 20 + } else { + sensitivity = 5 + } + if (wheelDeltaDirection === -1) { + wheelDeltaCounter++ + if (wheelDeltaCounter < sensitivity) { + return + } else { + wheelDeltaCounter = 0 + } + } else { + wheelDeltaCounter = 0 + wheelDeltaDirection = -1 + return + } + } else { + if (wheelDeltaDirection === 1) { + wheelDeltaCounter++ + if (wheelDeltaCounter < sensitivity) { + return + } else { + wheelDeltaCounter = 0 + } + } else { + wheelDeltaCounter = 0 + wheelDeltaDirection = 1 + return + } + } + } + + let delta = event.wheelDelta + if (delta < 0) { + timeFrameIndex-- + if (timeFrameIndex < 0) { + filePeriodIndex-- + if (filePeriodIndex < 0) { + filePeriodIndex = 0 + timeFrameIndex = 0 + } else { + timeFrameIndex = timeFramesMasterArray[filePeriodIndex].length - 1 + } + } + } else { + timeFrameIndex++ + if (timeFrameIndex > timeFramesMasterArray[filePeriodIndex].length - 1) { + filePeriodIndex++ + if (filePeriodIndex > timeFramesMasterArray.length - 1) { + filePeriodIndex = timeFramesMasterArray.length - 1 + timeFrameIndex = timeFramesMasterArray[filePeriodIndex].length - 1 + } else { + timeFrameIndex = 0 + } + } + } + newTimeFrame() saveObjectState() - } - } - } - - function onMouseWheel (event) { - if (IS_MAC) { - let sensitivity - if (event.wheelDelta < 0) { - if (event.shiftKey === true) { - sensitivity = 20 - } else { - sensitivity = 5 - } - if (wheelDeltaDirection === -1) { - wheelDeltaCounter++ - if (wheelDeltaCounter < sensitivity) { - return - } else { - wheelDeltaCounter = 0 - } - } else { - wheelDeltaCounter = 0 - wheelDeltaDirection = -1 - return - } - } else { - if (wheelDeltaDirection === 1) { - wheelDeltaCounter++ - if (wheelDeltaCounter < sensitivity) { - return - } else { - wheelDeltaCounter = 0 - } - } else { - wheelDeltaCounter = 0 - wheelDeltaDirection = 1 - return - } - } } - let delta = event.wheelDelta - if (delta < 0) { - timeFrameIndex-- - if (timeFrameIndex < 0) { - filePeriodIndex-- - if (filePeriodIndex < 0) { - filePeriodIndex = 0 - timeFrameIndex = 0 - } else { - timeFrameIndex = timeFramesMasterArray[filePeriodIndex].length - 1 + function getContainer(point) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container } - } - } else { - timeFrameIndex++ - if (timeFrameIndex > timeFramesMasterArray[filePeriodIndex].length - 1) { - filePeriodIndex++ - if (filePeriodIndex > timeFramesMasterArray.length - 1) { - filePeriodIndex = timeFramesMasterArray.length - 1 - timeFrameIndex = timeFramesMasterArray[filePeriodIndex].length - 1 - } else { - timeFrameIndex = 0 + } + + function saveObjectState() { + try { + let config = JSON.parse(thisObject.payload.node.config) + config.value = timeFrameLabel + thisObject.payload.node.config = JSON.stringify(config) + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. } - } } - newTimeFrame() - saveObjectState() - } - - function getContainer (point) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } - } - - function saveObjectState () { - try { - let config = JSON.parse(thisObject.payload.node.config) - config.value = timeFrameLabel - thisObject.payload.node.config = JSON.stringify(config) - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } - } - - function readObjectState () { - try { - let config = JSON.parse(thisObject.payload.node.config) - if (config.value !== timeFrameLabel) { - let found = false - for (let i = 0; i < timeFramesMasterArray.length; i++) { - let timeFrameArray = timeFramesMasterArray[i] - for (let j = 0; j < timeFrameArray.length; j++) { - let record = timeFrameArray[j] - if (config.value === record[1]) { - filePeriodIndex = i - timeFrameIndex = j - found = true + function readObjectState() { + try { + let config = JSON.parse(thisObject.payload.node.config) + if (config.value !== timeFrameLabel) { + let found = false + for (let i = 0; i < timeFramesMasterArray.length; i++) { + let timeFrameArray = timeFramesMasterArray[i] + for (let j = 0; j < timeFrameArray.length; j++) { + let record = timeFrameArray[j] + if (config.value === record[1]) { + filePeriodIndex = i + timeFrameIndex = j + found = true + } + } + } + if (found === true) { + newTimeFrame() + } else { + saveObjectState() + } } - } + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. } - if (found === true) { - newTimeFrame() - } else { - saveObjectState() + } + + function newTimeFrame() { + let timeFrameArray = timeFramesMasterArray[filePeriodIndex] + thisObject.timeFrame = timeFrameArray[timeFrameIndex][0] + timeFrameLabel = timeFrameArray[timeFrameIndex][1] + // console.log('NEW TIME FRAME LABEL', timeFrameLabel) + let event = {} + event.timeFrame = thisObject.timeFrame + thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event) + } + + function draw() { + drawScaleBox() + if (greyOutCoverLayer === true) { + drawScaleDisplayCover(thisObject.container) } - } - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. } - } - function newTimeFrame () { - let timeFrameArray = timeFramesMasterArray[filePeriodIndex] - thisObject.timeFrame = timeFrameArray[timeFrameIndex][0] - timeFrameLabel = timeFrameArray[timeFrameIndex][1] - // console.log('NEW TIME FRAME LABEL', timeFrameLabel) - let event = {} - event.timeFrame = thisObject.timeFrame - thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event) - } - - function draw () { - drawScaleBox() - if (greyOutCoverLayer === true) { - drawScaleDisplayCover(thisObject.container) + function drawForeground() { + if (isMouseOver === true) { + drawScaleBox() + } } - } - function drawForeground () { - if (isMouseOver === true) { - drawScaleBox() + function drawScaleBox() { + if (timeFrameLabel === undefined) { return } + + let label = timeFrameLabel.split('-') + let label1 = thisObject.payload.node.payload.parentNode.name + let label2 = label[0] + let label3 = label[1].toUpperCase() + + let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) + let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) + + let backgroundColor = UI_COLOR.BLACK + + drawScaleDisplay(label1, label2, label3, 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor) } - } - - function drawScaleBox () { - if (timeFrameLabel === undefined) { return } - - let label = timeFrameLabel.split('-') - let label1 = thisObject.payload.node.payload.parentNode.name - let label2 = label[0] - let label3 = label[1].toUpperCase() - - let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) - let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) - - let backgroundColor = UI_COLOR.BLACK - - drawScaleDisplay(label1, label2, label3, 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor) - } } diff --git a/Scales/TimeScale.js b/Scales/TimeScale.js index 90ee96fb0..af0a3dbc8 100644 --- a/Scales/TimeScale.js +++ b/Scales/TimeScale.js @@ -1,359 +1,359 @@ -function newTimeScale () { - const MODULE_NAME = 'Time Scale' +function newTimeScale() { + const MODULE_NAME = 'Time Scale' - let thisObject = { - container: undefined, - date: undefined, - fitFunction: undefined, - payload: undefined, - isVisible: true, - fromDate: undefined, - toDate: undefined, - onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer, - physics: physics, - draw: draw, - drawBackground: drawBackground, - drawForeground: drawForeground, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isClickeable = false - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL - thisObject.container.frame.height = 40 - - let visible = true - let autoScaleButton - let isMouseOver - - let onMouseWheelEventSubscriptionId - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - let onScaleChangedEventSubscriptionId - - let coordinateSystem - let limitingContainer - - let wheelDeltaDirection - let wheelDeltaCounter = 0 - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - coordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - thisObject.payload = undefined - - coordinateSystem = undefined - limitingContainer = undefined - - autoScaleButton.finalize() - autoScaleButton = undefined - } - - function initialize (pCoordinateSystem, pLimitingContainer) { - coordinateSystem = pCoordinateSystem - limitingContainer = pLimitingContainer - - onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - onScaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) - - autoScaleButton = newAutoScaleButton() - autoScaleButton.container.connectToParent(thisObject.container) - autoScaleButton.initialize('X', coordinateSystem) - - readObjectState() - } - - function onMouseOverSomeTimeMachineContainer (event) { - if (event.containerId === undefined) { - /* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */ - visible = true - } else { - if (event.containerId === thisObject.container.id) { - visible = true - } else { - visible = false - turnOnCounter = 0 - } + let thisObject = { + container: undefined, + date: undefined, + fitFunction: undefined, + payload: undefined, + isVisible: true, + fromDate: undefined, + toDate: undefined, + onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer, + physics: physics, + draw: draw, + drawBackground: drawBackground, + drawForeground: drawForeground, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - } - function onMouseOver (event) { - isMouseOver = true - event.containerId = thisObject.container.id - thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event) - } + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - function onMouseNotOver () { - isMouseOver = false - } + thisObject.container.isDraggeable = false + thisObject.container.isClickeable = false + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true + + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL + thisObject.container.frame.height = 40 + + let visible = true + let autoScaleButton + let isMouseOver + + let onMouseWheelEventSubscriptionId + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + let onScaleChangedEventSubscriptionId + + let coordinateSystem + let limitingContainer + + let wheelDeltaDirection + let wheelDeltaCounter = 0 + + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) + coordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined + thisObject.payload = undefined + + coordinateSystem = undefined + limitingContainer = undefined + + autoScaleButton.finalize() + autoScaleButton = undefined + } + + function initialize(pCoordinateSystem, pLimitingContainer) { + coordinateSystem = pCoordinateSystem + limitingContainer = pLimitingContainer + + onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + onScaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged) + + autoScaleButton = newAutoScaleButton() + autoScaleButton.container.connectToParent(thisObject.container) + autoScaleButton.initialize('X', coordinateSystem) + + readObjectState() + } + + function onMouseOverSomeTimeMachineContainer(event) { + if (event.containerId === undefined) { + /* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */ + visible = true + } else { + if (event.containerId === thisObject.container.id) { + visible = true + } else { + visible = false + turnOnCounter = 0 + } + } + } + + function onMouseOver(event) { + isMouseOver = true + event.containerId = thisObject.container.id + thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event) + } + + function onMouseNotOver() { + isMouseOver = false + } + + function onMouseWheel(event) { + if (IS_MAC) { + let sensitivity + if (event.wheelDelta < 0) { + if (event.shiftKey === true) { + sensitivity = 20 + } else { + sensitivity = 5 + } + if (wheelDeltaDirection === -1) { + wheelDeltaCounter++ + if (wheelDeltaCounter < sensitivity) { + return + } else { + wheelDeltaCounter = 0 + } + } else { + wheelDeltaCounter = 0 + wheelDeltaDirection = -1 + return + } + } else { + if (wheelDeltaDirection === 1) { + wheelDeltaCounter++ + if (wheelDeltaCounter < sensitivity) { + return + } else { + wheelDeltaCounter = 0 + } + } else { + wheelDeltaCounter = 0 + wheelDeltaDirection = 1 + return + } + } + } - function onMouseWheel (event) { - if (IS_MAC) { - let sensitivity - if (event.wheelDelta < 0) { if (event.shiftKey === true) { - sensitivity = 20 - } else { - sensitivity = 5 - } - if (wheelDeltaDirection === -1) { - wheelDeltaCounter++ - if (wheelDeltaCounter < sensitivity) { + autoScaleButton.container.eventHandler.raiseEvent('onMouseWheel', event) return - } else { - wheelDeltaCounter = 0 - } + } + let factor + let morePower = 10 + if (event.buttons === 4) { morePower = 1 } // Mouse wheel pressed. + + let delta = event.wheelDelta + if (delta < 0) { + factor = -0.01 * morePower } else { - wheelDeltaCounter = 0 - wheelDeltaDirection = -1 - return + factor = 0.01 * morePower } - } else { - if (wheelDeltaDirection === 1) { - wheelDeltaCounter++ - if (wheelDeltaCounter < sensitivity) { - return - } else { - wheelDeltaCounter = 0 - } - } else { - wheelDeltaCounter = 0 - wheelDeltaDirection = 1 - return + + coordinateSystem.zoomX(factor, event, limitingContainer, MODULE_NAME) + } + + function onScaleChanged() { + saveObjectState() + } + + function getContainer(point, purpose) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container } - } } - if (event.shiftKey === true) { - autoScaleButton.container.eventHandler.raiseEvent('onMouseWheel', event) - return - } - let factor - let morePower = 10 - if (event.buttons === 4) { morePower = 1 } // Mouse wheel pressed. - - let delta = event.wheelDelta - if (delta < 0) { - factor = -0.01 * morePower - } else { - factor = 0.01 * morePower - } - - coordinateSystem.zoomX(factor, event, limitingContainer, MODULE_NAME) - } - - function onScaleChanged () { - saveObjectState() - } - - function getContainer (point, purpose) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } - } - - function saveObjectState () { - try { - let config = JSON.parse(thisObject.payload.node.config) - config.fromDate = (new Date(coordinateSystem.min.x)).toISOString() - config.toDate = (new Date(coordinateSystem.max.x)).toISOString() - config.autoMinScale = coordinateSystem.autoMinXScale - config.autoMaxScale = coordinateSystem.autoMaxXScale - thisObject.payload.node.config = JSON.stringify(config, null, 4) - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } - } - - function readObjectState () { - try { - let config = JSON.parse(thisObject.payload.node.config) - - if ( - (isNaN(Date.parse(config.fromDate)) || config.fromDate === null || config.fromDate === undefined) || - (isNaN(Date.parse(config.toDate)) || config.toDate === null || config.toDate === undefined) - ) { - // not using this value - } else { - if (thisObject.fromDate !== Date.parse(config.fromDate) || thisObject.toDate !== Date.parse(config.toDate)) { - thisObject.fromDate = Date.parse(config.fromDate) - thisObject.toDate = Date.parse(config.toDate) - coordinateSystem.min.x = thisObject.fromDate - coordinateSystem.max.x = thisObject.toDate - - if (config.autoMinScale !== undefined && (config.autoMinScale === true || config.autoMinScale === false) && config.autoMaxScale !== undefined && (config.autoMaxScale === true || config.autoMaxScale === false)) { - coordinateSystem.autoMinXScale = config.autoMinScale - coordinateSystem.autoMaxXScale = config.autoMaxScale - autoScaleButton.setStatus(config.autoMinScale, config.autoMaxScale) - } - coordinateSystem.recalculateScale() + function saveObjectState() { + try { + let config = JSON.parse(thisObject.payload.node.config) + config.fromDate = (new Date(coordinateSystem.min.x)).toISOString() + config.toDate = (new Date(coordinateSystem.max.x)).toISOString() + config.autoMinScale = coordinateSystem.autoMinXScale + config.autoMaxScale = coordinateSystem.autoMaxXScale + thisObject.payload.node.config = JSON.stringify(config, null, 4) + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. } - } - saveObjectState() // this overrides any invalid value at the config. - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } - } - - function physics () { - readObjectState() - positioningPhysics() - } - - function positioningPhysics () { - /* Container Limits */ - - let upCorner = { - x: 0, - y: 0 } - let bottonCorner = { - x: limitingContainer.frame.width, - y: limitingContainer.frame.height + function readObjectState() { + try { + let config = JSON.parse(thisObject.payload.node.config) + + if ( + (isNaN(Date.parse(config.fromDate)) || config.fromDate === null || config.fromDate === undefined) || + (isNaN(Date.parse(config.toDate)) || config.toDate === null || config.toDate === undefined) + ) { + // not using this value + } else { + if (thisObject.fromDate !== Date.parse(config.fromDate) || thisObject.toDate !== Date.parse(config.toDate)) { + thisObject.fromDate = Date.parse(config.fromDate) + thisObject.toDate = Date.parse(config.toDate) + coordinateSystem.min.x = thisObject.fromDate + coordinateSystem.max.x = thisObject.toDate + + if (config.autoMinScale !== undefined && (config.autoMinScale === true || config.autoMinScale === false) && config.autoMaxScale !== undefined && (config.autoMaxScale === true || config.autoMaxScale === false)) { + coordinateSystem.autoMinXScale = config.autoMinScale + coordinateSystem.autoMaxXScale = config.autoMaxScale + autoScaleButton.setStatus(config.autoMinScale, config.autoMaxScale) + } + coordinateSystem.recalculateScale() + } + } + saveObjectState() // this overrides any invalid value at the config. + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } } - upCorner = transformThisPoint(upCorner, limitingContainer) - bottonCorner = transformThisPoint(bottonCorner, limitingContainer) - - upCorner = limitingContainer.fitFunction(upCorner, true) - bottonCorner = limitingContainer.fitFunction(bottonCorner, true) - - /* Mouse Position Date Calculation */ - let timePoint = { - x: canvas.mouse.position.x, - y: 0 + function physics() { + readObjectState() + positioningPhysics() } - let mouseDate = getDateFromPointAtBrowserCanvas(timePoint, limitingContainer, coordinateSystem) + function positioningPhysics() { + /* Container Limits */ - thisObject.date = new Date(mouseDate) + let upCorner = { + x: 0, + y: 0 + } - /* timeScale Positioning */ - timePoint = { - x: 0, - y: 0 + let bottonCorner = { + x: limitingContainer.frame.width, + y: limitingContainer.frame.height + } + + upCorner = transformThisPoint(upCorner, limitingContainer) + bottonCorner = transformThisPoint(bottonCorner, limitingContainer) + + upCorner = limitingContainer.fitFunction(upCorner, true) + bottonCorner = limitingContainer.fitFunction(bottonCorner, true) + + /* Mouse Position Date Calculation */ + let timePoint = { + x: canvas.mouse.position.x, + y: 0 + } + + let mouseDate = getDateFromPointAtBrowserCanvas(timePoint, limitingContainer, coordinateSystem) + + thisObject.date = new Date(mouseDate) + + /* timeScale Positioning */ + timePoint = { + x: 0, + y: 0 + } + + timePoint = transformThisPoint(timePoint, limitingContainer.frame.container) + timePoint.x = canvas.mouse.position.x - thisObject.container.frame.width / 2 + + /* Checking against the container limits. */ + if (timePoint.x < upCorner.x) { timePoint.x = upCorner.x } + if (timePoint.x + thisObject.container.frame.width > bottonCorner.x) { timePoint.x = bottonCorner.x - thisObject.container.frame.width } + if (timePoint.y < upCorner.y) { timePoint.y = upCorner.y } + if (timePoint.y + thisObject.container.frame.height > bottonCorner.y) { timePoint.y = bottonCorner.y - thisObject.container.frame.height } + + thisObject.container.frame.position.x = timePoint.x + thisObject.container.frame.position.y = timePoint.y + + thisObject.isVisible = true + if (thisObject.container.frame.position.y + thisObject.container.frame.height * 4 > bottonCorner.y || + thisObject.container.frame.position.y < upCorner.y || + thisObject.container.frame.position.x < upCorner.x) { + thisObject.isVisible = false + } + + if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES) { + thisObject.isVisible = false + } } - timePoint = transformThisPoint(timePoint, limitingContainer.frame.container) - timePoint.x = canvas.mouse.position.x - thisObject.container.frame.width / 2 - - /* Checking against the container limits. */ - if (timePoint.x < upCorner.x) { timePoint.x = upCorner.x } - if (timePoint.x + thisObject.container.frame.width > bottonCorner.x) { timePoint.x = bottonCorner.x - thisObject.container.frame.width } - if (timePoint.y < upCorner.y) { timePoint.y = upCorner.y } - if (timePoint.y + thisObject.container.frame.height > bottonCorner.y) { timePoint.y = bottonCorner.y - thisObject.container.frame.height } - - thisObject.container.frame.position.x = timePoint.x - thisObject.container.frame.position.y = timePoint.y - - thisObject.isVisible = true - if (thisObject.container.frame.position.y + thisObject.container.frame.height * 4 > bottonCorner.y || - thisObject.container.frame.position.y < upCorner.y || - thisObject.container.frame.position.x < upCorner.x) { - thisObject.isVisible = false + function drawBackground() { + drawScale() } - if (canvas.chartingSpace.viewport.zoomTargetLevel < ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES) { - thisObject.isVisible = false - } - } + function drawScale() { + const SEPARATION = 150 + const NUMBER_OF_LABELS = Math.trunc(canvas.chartingSpace.viewport.width / SEPARATION) + const FONT_SIZE = 15 - function drawBackground () { - drawScale() - } + for (let i = 0; i <= NUMBER_OF_LABELS; i++) { + let timePoint = { + x: SEPARATION * (i + 1), + y: 0 + } - function drawScale () { - const SEPARATION = 150 - const NUMBER_OF_LABELS = Math.trunc(canvas.chartingSpace.viewport.width / SEPARATION) - const FONT_SIZE = 15 + let time = getDateFromPointAtBrowserCanvas(timePoint, limitingContainer, coordinateSystem) + let labels = scaleLabels(time, true) + let labelDisplace = labels[1].length * FONT_SIZE * FONT_ASPECT_RATIO - for (let i = 0; i <= NUMBER_OF_LABELS; i++) { - let timePoint = { - x: SEPARATION * (i + 1), - y: 0 - } + let timePoint1 = { + x: SEPARATION * (i + 1) - labelDisplace, + y: 0 + } + let timePoint2 = { + x: SEPARATION * (i + 1) + labelDisplace, + y: 0 + } - let time = getDateFromPointAtBrowserCanvas(timePoint, limitingContainer, coordinateSystem) - let labels = scaleLabels(time, true) - let labelDisplace = labels[1].length * FONT_SIZE * FONT_ASPECT_RATIO + let fitPoint1 = thisObject.fitFunction(timePoint1) + let fitPoint2 = thisObject.fitFunction(timePoint2) - let timePoint1 = { - x: SEPARATION * (i + 1) - labelDisplace, - y: 0 - } - let timePoint2 = { - x: SEPARATION * (i + 1) + labelDisplace, - y: 0 - } - - let fitPoint1 = thisObject.fitFunction(timePoint1) - let fitPoint2 = thisObject.fitFunction(timePoint2) - - if (fitPoint1.x === timePoint1.x && fitPoint2.x === timePoint2.x) { - drawLabel(labels[1], 1 / 2, 0, 18, 17, FONT_SIZE, thisObject.container, UI_COLOR.GREY, timePoint1.x, undefined) - drawLabel(labels[2], 1 / 2, 0, 18, 30, 12, thisObject.container, UI_COLOR.GREY, timePoint1.x, undefined) - } - } - } - - function draw () { - drawScaleBox() - autoScaleButton.draw() - if (visible === false) { - drawScaleDisplayCover(thisObject.container) - } - } - - function drawForeground () { - if (isMouseOver === true) { - drawScaleBox() - autoScaleButton.draw() - } - } - - function drawScaleBox () { - if (thisObject.date === undefined) { return } - - let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) - let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) - - let backgroundColor = UI_COLOR.BLACK - let labels = scaleLabels(thisObject.date) - - drawScaleDisplay(labels[0], labels[1], labels[2], 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor) - } - - function scaleLabels (date, excludeYear) { - let label = date.toUTCString() - let labelArray = label.split(' ') - let label1 = thisObject.payload.node.payload.parentNode.name - let label2 = labelArray[1] + ' ' + labelArray[2] + ' ' + labelArray[3] - let label3 = labelArray[4] - - if (excludeYear === true) { - label2 = labelArray[1] + ' ' + labelArray[2] + if (fitPoint1.x === timePoint1.x && fitPoint2.x === timePoint2.x) { + drawLabel(labels[1], 1 / 2, 0, 18, 17, FONT_SIZE, thisObject.container, UI_COLOR.GREY, timePoint1.x, undefined) + drawLabel(labels[2], 1 / 2, 0, 18, 30, 12, thisObject.container, UI_COLOR.GREY, timePoint1.x, undefined) + } + } } - return [label1, label2, label3] - } + function draw() { + drawScaleBox() + autoScaleButton.draw() + if (visible === false) { + drawScaleDisplayCover(thisObject.container) + } + } + + function drawForeground() { + if (isMouseOver === true) { + drawScaleBox() + autoScaleButton.draw() + } + } + + function drawScaleBox() { + if (thisObject.date === undefined) { return } + + let icon1 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type) + let icon2 = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type) + + let backgroundColor = UI_COLOR.BLACK + let labels = scaleLabels(thisObject.date) + + drawScaleDisplay(labels[0], labels[1], labels[2], 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor) + } + + function scaleLabels(date, excludeYear) { + let label = date.toUTCString() + let labelArray = label.split(' ') + let label1 = thisObject.payload.node.payload.parentNode.name + let label2 = labelArray[1] + ' ' + labelArray[2] + ' ' + labelArray[3] + let label3 = labelArray[4] + + if (excludeYear === true) { + label2 = labelArray[1] + ' ' + labelArray[2] + } + + return [label1, label2, label3] + } } diff --git a/SideSpace/ListItem.js b/SideSpace/ListItem.js index 59e982979..fdb2f3478 100644 --- a/SideSpace/ListItem.js +++ b/SideSpace/ListItem.js @@ -1,107 +1,107 @@ -function newListItem () { - const MODULE_NAME = 'List Item' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newListItem() { + const MODULE_NAME = 'List Item' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - container: undefined, - fitFunction: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize() - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - thisObject.container.detectMouseOver = true - thisObject.container.isClickeable = true - thisObject.container.frame.width = SIDE_PANEL_WIDTH * 0.75 - thisObject.container.frame.height = SIDE_PANEL_WIDTH * 0.75 - - let name - let type - - let onMouseOverEventSubscriptionId - let onMouseNotOverEventSubscriptionId - let onMouseClickEventSubscriptionId - - let isMouseOver = false - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(onMouseClickEventSubscriptionId) - - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fitFunction = undefined - } - - function initialize (pName, pType) { - name = pName - type = pType - - onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - onMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - } - - function getContainer (point) { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } - } - - function onMouseOver (event) { - isMouseOver = true - } - - function onMouseNotOver () { - isMouseOver = false - } - - function onMouseClick (event) { - canvas.designSpace.workspace.replaceWorkspaceByLoadingOne(name) - } - - function physics () { - - } - - function draw () { - let icon = canvas.designSpace.iconByUiObjectType.get(type) - let backgroundColor = UI_COLOR.BLACK - let labelColor - - const RED_LINE_HIGHT = 4 - const OPACITY = 1 - - let params = { - cornerRadius: 0, - lineWidth: 1, - container: thisObject.container, - borderColor: UI_COLOR.RUSTED_RED, - castShadow: false, - backgroundColor: backgroundColor, - opacity: OPACITY + let thisObject = { + container: undefined, + fitFunction: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - if (isMouseOver === false) { - labelColor = UI_COLOR.WHITE - } else { - labelColor = UI_COLOR.TITANIUM_YELLOW + thisObject.container = newContainer() + thisObject.container.initialize() + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = false + thisObject.container.detectMouseOver = true + thisObject.container.isClickeable = true + thisObject.container.frame.width = SIDE_PANEL_WIDTH * 0.75 + thisObject.container.frame.height = SIDE_PANEL_WIDTH * 0.75 + + let name + let type + + let onMouseOverEventSubscriptionId + let onMouseNotOverEventSubscriptionId + let onMouseClickEventSubscriptionId + + let isMouseOver = false + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(onMouseClickEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fitFunction = undefined } - roundedCornersBackground(params) + function initialize(pName, pType) { + name = pName + type = pType - drawLabel(name, 1 / 2, 3.0 / 10, -5, 0, 15, thisObject.container, labelColor) - drawLabel(type, 1 / 2, 7.2 / 10, -5, 0, 15, thisObject.container, labelColor) - drawIcon(icon, 1 / 2, 1 / 2, 0, 0, 80, thisObject.container) - } + onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + onMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + } + + function getContainer(point) { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } + } + + function onMouseOver(event) { + isMouseOver = true + } + + function onMouseNotOver() { + isMouseOver = false + } + + function onMouseClick(event) { + canvas.designSpace.workspace.replaceWorkspaceByLoadingOne(name) + } + + function physics() { + + } + + function draw() { + let icon = canvas.designSpace.iconByUiObjectType.get(type) + let backgroundColor = UI_COLOR.BLACK + let labelColor + + const RED_LINE_HIGHT = 4 + const OPACITY = 1 + + let params = { + cornerRadius: 0, + lineWidth: 1, + container: thisObject.container, + borderColor: UI_COLOR.RUSTED_RED, + castShadow: false, + backgroundColor: backgroundColor, + opacity: OPACITY + } + + if (isMouseOver === false) { + labelColor = UI_COLOR.WHITE + } else { + labelColor = UI_COLOR.TITANIUM_YELLOW + } + + roundedCornersBackground(params) + + drawLabel(name, 1 / 2, 3.0 / 10, -5, 0, 15, thisObject.container, labelColor) + drawLabel(type, 1 / 2, 7.2 / 10, -5, 0, 15, thisObject.container, labelColor) + drawIcon(icon, 1 / 2, 1 / 2, 0, 0, 80, thisObject.container) + } } diff --git a/SideSpace/ListView.js b/SideSpace/ListView.js index e066f7b73..5aac6fb7e 100644 --- a/SideSpace/ListView.js +++ b/SideSpace/ListView.js @@ -1,271 +1,271 @@ -function newListView () { - const MODULE_NAME = 'List View' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newListView() { + const MODULE_NAME = 'List View' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - fitFunction: undefined, - container: undefined, - listItems: [], - payload: undefined, - isVisible: false, - resize: resize, - turnOn: turnOn, - turnOff: turnOff, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize() - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - - let isInitialized = false - - let listItemsMap = new Map() - let visibleListItems = [] - let firstVisibleListItem - - let headerHeight = 40 - let footerHeight = 30 - let listItemHeight = SIDE_PANEL_WIDTH * 0.75 - - let posibleVisibleListItems - - let itemSeparation - - let onMouseWheelEventSuscriptionId - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onMouseWheelEventSuscriptionId) - - listItemsMap = undefined - visibleListItems = undefined - - thisObject.container.finalize() - thisObject.container = undefined - - thisObject.payload = undefined - thisObject = undefined - } - - function initialize () { - thisObject.container.name = MODULE_NAME - thisObject.container.frame.containerName = thisObject.container.name - thisObject.container.frame.width = SIDE_PANEL_WIDTH * 0.75 - - let position = { // Default position - x: SIDE_PANEL_WIDTH * 0.25 / 2, - y: 20 + let thisObject = { + fitFunction: undefined, + container: undefined, + listItems: [], + payload: undefined, + isVisible: false, + resize: resize, + turnOn: turnOn, + turnOff: turnOff, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - thisObject.container.frame.position = position + thisObject.container = newContainer() + thisObject.container.initialize() + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true - onMouseWheelEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) + let isInitialized = false - resize() - turnOn() - } + let listItemsMap = new Map() + let visibleListItems = [] + let firstVisibleListItem - function resize () { - thisObject.container.frame.height = browserCanvas.height - thisObject.container.frame.position.y * 2 + let headerHeight = 40 + let footerHeight = 30 + let listItemHeight = SIDE_PANEL_WIDTH * 0.75 - let spaceForListItems = (thisObject.container.frame.height - headerHeight - footerHeight) - posibleVisibleListItems = Math.trunc(spaceForListItems / (listItemHeight)) - if ((posibleVisibleListItems - 1) !== 0) { - itemSeparation = (spaceForListItems - listItemHeight * posibleVisibleListItems) / (posibleVisibleListItems - 1) - } else { - itemSeparation = 0 - } - } + let posibleVisibleListItems - function turnOn () { - firstVisibleListItem = 1 + let itemSeparation - callServer(undefined, 'ListWorkspaces', onResponse) + let onMouseWheelEventSuscriptionId - function onResponse (err, text) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> Could not load the list of your workspaces from the backend. ') } - return - } + return thisObject - let workspacelist = JSON.parse(text) - thisObject.listItems = [] - for (let i = 0; i < workspacelist.length; i++) { - let workspace = workspacelist[i].replace('.json', '') - let listItem = newListItem() - listItem.initialize(workspace, 'Workspace') - listItem.container.connectToParent(thisObject.container, false, false) + function finalize() { + thisObject.container.eventHandler.stopListening(onMouseWheelEventSuscriptionId) - thisObject.listItems.push(listItem) - } - calculateVisbleListItems() - isInitialized = true - thisObject.isVisible = true - } - } + listItemsMap = undefined + visibleListItems = undefined - function turnOff () { - thisObject.isVisible = false - } + thisObject.container.finalize() + thisObject.container = undefined - function onMouseWheel (event) { - delta = event.wheelDelta - if (delta > 0) { - delta = -1 - } else { - delta = 1 + thisObject.payload = undefined + thisObject = undefined } - firstVisibleListItem = firstVisibleListItem + delta + function initialize() { + thisObject.container.name = MODULE_NAME + thisObject.container.frame.containerName = thisObject.container.name + thisObject.container.frame.width = SIDE_PANEL_WIDTH * 0.75 - calculateVisbleListItems() - } - - function calculateVisbleListItems () { - let availableSlots = Math.trunc(posibleVisibleListItems) - - if (firstVisibleListItem < 1) { firstVisibleListItem = 1 } - if (firstVisibleListItem > (thisObject.listItems.length - availableSlots + 1)) { firstVisibleListItem = thisObject.listItems.length - availableSlots + 1 } - - visibleListItems = [] - - for (let i = 0; i < thisObject.listItems.length; i++) { - if (i + 1 >= firstVisibleListItem && i + 1 < firstVisibleListItem + availableSlots) { - let listItem = thisObject.listItems[i] - - listItem.container.frame.position.x = 0 - listItem.container.frame.position.y = (listItemHeight + itemSeparation) * visibleListItems.length + headerHeight - - /* Add to Visible Product Array */ - visibleListItems.push(listItem) - } - } - } - - function getContainer (point, purpose) { - if (isInitialized === false || thisObject.isVisible === false) { return } - let container - - /* First we check if thisObject point is inside thisObject space. */ - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - /* Now we see which is the inner most container that has it */ - for (let i = 0; i < visibleListItems.length; i++) { - container = visibleListItems[i].getContainer(point) - - if (container !== undefined) { - if (container.isForThisPurpose(purpose) === true) { - return container - } + let position = { // Default position + x: SIDE_PANEL_WIDTH * 0.25 / 2, + y: 20 } - } - return thisObject.container - } - } + thisObject.container.frame.position = position - function childrenPhysics () { - for (let i = 0; i < thisObject.listItems.length; i++) { - let listItem = thisObject.listItems[i] - listItem.physics() - } - } + onMouseWheelEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel) - function physics () { - if (isInitialized === false || thisObject.isVisible === false) { return } - if (isInitialized === false) { return } - if (thisObject.isVisible === false) { return } - childrenPhysics() - } - - function draw () { - if (isInitialized === false || thisObject.isVisible === false) { return } - - drawBackground() - drawChildren() - drawScrollBar() - } - - function drawChildren () { - for (let i = 0; i < visibleListItems.length; i++) { - let listItem = visibleListItems[i] - if (listItem !== undefined) { - listItem.draw() - } - } - } - - function drawBackground () { - let label = 'Your Workspaces' - - let backgroundColor = UI_COLOR.WHITE - let params = { - cornerRadius: 5, - lineWidth: 1, - container: thisObject.container, - borderColor: UI_COLOR.RUSTED_RED, - castShadow: false, - backgroundColor: backgroundColor, - opacity: 1 + resize() + turnOn() } - roundedCornersBackground(params) + function resize() { + thisObject.container.frame.height = browserCanvas.height - thisObject.container.frame.position.y * 2 - drawLabel(label, 1 / 2, 0, 0, 25, 15, thisObject.container, UI_COLOR.BLACK) - } - - function drawScrollBar () { - if (thisObject.listItems.length > posibleVisibleListItems && posibleVisibleListItems > 0) { - let xOffset = 4 - let barTopPoint = { - x: thisObject.container.frame.width - xOffset, - y: headerHeight - } - let barBottomPoint = { - x: thisObject.container.frame.width - xOffset, - y: thisObject.container.frame.height - footerHeight - } - let ratio = (posibleVisibleListItems * listItemHeight + (posibleVisibleListItems - 1) * itemSeparation) / (thisObject.listItems.length * listItemHeight + (thisObject.listItems.length - 1) * itemSeparation) - let handleHeight = posibleVisibleListItems * (listItemHeight * ratio) + (posibleVisibleListItems - 1) * itemSeparation * ratio - let handleTopPoint = { - x: thisObject.container.frame.width - xOffset, - y: headerHeight + (listItemHeight * ratio * (firstVisibleListItem - 1) + itemSeparation * ratio * (firstVisibleListItem - 1)) - } - let handleBottomPoint = { - x: thisObject.container.frame.width - xOffset, - y: handleTopPoint.y + handleHeight - } - barTopPoint = thisObject.container.frame.frameThisPoint(barTopPoint) - barBottomPoint = thisObject.container.frame.frameThisPoint(barBottomPoint) - handleTopPoint = thisObject.container.frame.frameThisPoint(handleTopPoint) - handleBottomPoint = thisObject.container.frame.frameThisPoint(handleBottomPoint) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(barTopPoint.x, barTopPoint.y) - browserCanvasContext.lineTo(barBottomPoint.x, barBottomPoint.y) - browserCanvasContext.closePath() - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.lineWidth = 1 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')' - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(handleTopPoint.x, handleTopPoint.y) - browserCanvasContext.lineTo(handleBottomPoint.x, handleBottomPoint.y) - browserCanvasContext.closePath() - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.lineWidth = 4 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + 1 + ')' - browserCanvasContext.stroke() + let spaceForListItems = (thisObject.container.frame.height - headerHeight - footerHeight) + posibleVisibleListItems = Math.trunc(spaceForListItems / (listItemHeight)) + if ((posibleVisibleListItems - 1) !== 0) { + itemSeparation = (spaceForListItems - listItemHeight * posibleVisibleListItems) / (posibleVisibleListItems - 1) + } else { + itemSeparation = 0 + } + } + + function turnOn() { + firstVisibleListItem = 1 + + callServer(undefined, 'ListWorkspaces', onResponse) + + function onResponse(err, text) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> Could not load the list of your workspaces from the backend. ') } + return + } + + let workspacelist = JSON.parse(text) + thisObject.listItems = [] + for (let i = 0; i < workspacelist.length; i++) { + let workspace = workspacelist[i].replace('.json', '') + let listItem = newListItem() + listItem.initialize(workspace, 'Workspace') + listItem.container.connectToParent(thisObject.container, false, false) + + thisObject.listItems.push(listItem) + } + calculateVisbleListItems() + isInitialized = true + thisObject.isVisible = true + } + } + + function turnOff() { + thisObject.isVisible = false + } + + function onMouseWheel(event) { + delta = event.wheelDelta + if (delta > 0) { + delta = -1 + } else { + delta = 1 + } + + firstVisibleListItem = firstVisibleListItem + delta + + calculateVisbleListItems() + } + + function calculateVisbleListItems() { + let availableSlots = Math.trunc(posibleVisibleListItems) + + if (firstVisibleListItem < 1) { firstVisibleListItem = 1 } + if (firstVisibleListItem > (thisObject.listItems.length - availableSlots + 1)) { firstVisibleListItem = thisObject.listItems.length - availableSlots + 1 } + + visibleListItems = [] + + for (let i = 0; i < thisObject.listItems.length; i++) { + if (i + 1 >= firstVisibleListItem && i + 1 < firstVisibleListItem + availableSlots) { + let listItem = thisObject.listItems[i] + + listItem.container.frame.position.x = 0 + listItem.container.frame.position.y = (listItemHeight + itemSeparation) * visibleListItems.length + headerHeight + + /* Add to Visible Product Array */ + visibleListItems.push(listItem) + } + } + } + + function getContainer(point, purpose) { + if (isInitialized === false || thisObject.isVisible === false) { return } + let container + + /* First we check if thisObject point is inside thisObject space. */ + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + /* Now we see which is the inner most container that has it */ + for (let i = 0; i < visibleListItems.length; i++) { + container = visibleListItems[i].getContainer(point) + + if (container !== undefined) { + if (container.isForThisPurpose(purpose) === true) { + return container + } + } + } + + return thisObject.container + } + } + + function childrenPhysics() { + for (let i = 0; i < thisObject.listItems.length; i++) { + let listItem = thisObject.listItems[i] + listItem.physics() + } + } + + function physics() { + if (isInitialized === false || thisObject.isVisible === false) { return } + if (isInitialized === false) { return } + if (thisObject.isVisible === false) { return } + childrenPhysics() + } + + function draw() { + if (isInitialized === false || thisObject.isVisible === false) { return } + + drawBackground() + drawChildren() + drawScrollBar() + } + + function drawChildren() { + for (let i = 0; i < visibleListItems.length; i++) { + let listItem = visibleListItems[i] + if (listItem !== undefined) { + listItem.draw() + } + } + } + + function drawBackground() { + let label = 'Your Workspaces' + + let backgroundColor = UI_COLOR.WHITE + let params = { + cornerRadius: 5, + lineWidth: 1, + container: thisObject.container, + borderColor: UI_COLOR.RUSTED_RED, + castShadow: false, + backgroundColor: backgroundColor, + opacity: 1 + } + + roundedCornersBackground(params) + + drawLabel(label, 1 / 2, 0, 0, 25, 15, thisObject.container, UI_COLOR.BLACK) + } + + function drawScrollBar() { + if (thisObject.listItems.length > posibleVisibleListItems && posibleVisibleListItems > 0) { + let xOffset = 4 + let barTopPoint = { + x: thisObject.container.frame.width - xOffset, + y: headerHeight + } + let barBottomPoint = { + x: thisObject.container.frame.width - xOffset, + y: thisObject.container.frame.height - footerHeight + } + let ratio = (posibleVisibleListItems * listItemHeight + (posibleVisibleListItems - 1) * itemSeparation) / (thisObject.listItems.length * listItemHeight + (thisObject.listItems.length - 1) * itemSeparation) + let handleHeight = posibleVisibleListItems * (listItemHeight * ratio) + (posibleVisibleListItems - 1) * itemSeparation * ratio + let handleTopPoint = { + x: thisObject.container.frame.width - xOffset, + y: headerHeight + (listItemHeight * ratio * (firstVisibleListItem - 1) + itemSeparation * ratio * (firstVisibleListItem - 1)) + } + let handleBottomPoint = { + x: thisObject.container.frame.width - xOffset, + y: handleTopPoint.y + handleHeight + } + barTopPoint = thisObject.container.frame.frameThisPoint(barTopPoint) + barBottomPoint = thisObject.container.frame.frameThisPoint(barBottomPoint) + handleTopPoint = thisObject.container.frame.frameThisPoint(handleTopPoint) + handleBottomPoint = thisObject.container.frame.frameThisPoint(handleBottomPoint) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(barTopPoint.x, barTopPoint.y) + browserCanvasContext.lineTo(barBottomPoint.x, barBottomPoint.y) + browserCanvasContext.closePath() + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.lineWidth = 1 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')' + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(handleTopPoint.x, handleTopPoint.y) + browserCanvasContext.lineTo(handleBottomPoint.x, handleBottomPoint.y) + browserCanvasContext.closePath() + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.lineWidth = 4 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + 1 + ')' + browserCanvasContext.stroke() + } } - } } diff --git a/SideSpace/SidePanelTab.js b/SideSpace/SidePanelTab.js index 1934b2337..2d1a2c161 100644 --- a/SideSpace/SidePanelTab.js +++ b/SideSpace/SidePanelTab.js @@ -1,237 +1,237 @@ -function newSidePanelTab () { - const MODULE_NAME = 'Side Panel Tab' - let thisObject = { - pointerDirection: 'left', - container: undefined, - resize: resize, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize - } - - const TAB_WIDTH = 25 - const TAB_HEIGHT = 60 - - let isInitialized = false - let animation = 'none' - let ORIGINAL_PARENT_POSITON - let xOffset = 0 - - thisObject.container = newContainer() - thisObject.container.name = MODULE_NAME - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - - return thisObject - - function initialize () { - thisObject.container.frame.width = TAB_WIDTH - thisObject.container.frame.height = TAB_HEIGHT - - ORIGINAL_PARENT_POSITON = thisObject.container.parentContainer.frame.position.x - - thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - resize() - isInitialized = true - } - - function resize () { - thisObject.container.frame.position.x = 0 + thisObject.container.parentContainer.frame.width - thisObject.container.frame.position.y = 69 - setClosed() - } - - function onMouseClick (event) { - if (thisObject.pointerDirection === 'left') { - animation = 'opening' - thisObject.container.eventHandler.raiseEvent('opening') - } else { - animation = 'closing' - thisObject.container.eventHandler.raiseEvent('closing') - } - } - - function getContainer (point) { - let container - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - - function physics () { - if (isInitialized === false) { return } - animate() - } - - function draw () { - if (isInitialized === false) { return } - borders() - arrow() - } - - function animate () { - const STEP = 50 - - if (animation === 'opening') { - xOffset = xOffset + STEP - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset - if (xOffset >= thisObject.container.parentContainer.frame.width) { - setOpened() - thisObject.container.eventHandler.raiseEvent('opened') - } +function newSidePanelTab() { + const MODULE_NAME = 'Side Panel Tab' + let thisObject = { + pointerDirection: 'left', + container: undefined, + resize: resize, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize } - if (animation === 'closing') { - xOffset = xOffset - STEP - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset - if (xOffset <= 0) { + const TAB_WIDTH = 25 + const TAB_HEIGHT = 60 + + let isInitialized = false + let animation = 'none' + let ORIGINAL_PARENT_POSITON + let xOffset = 0 + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + + return thisObject + + function initialize() { + thisObject.container.frame.width = TAB_WIDTH + thisObject.container.frame.height = TAB_HEIGHT + + ORIGINAL_PARENT_POSITON = thisObject.container.parentContainer.frame.position.x + + thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + resize() + isInitialized = true + } + + function resize() { + thisObject.container.frame.position.x = 0 + thisObject.container.parentContainer.frame.width + thisObject.container.frame.position.y = 69 setClosed() - thisObject.container.eventHandler.raiseEvent('closed') - } - } - } - - function setOpened () { - animation = 'none' - xOffset = thisObject.container.parentContainer.frame.width - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset - thisObject.container.parentContainer.status = 'visible' - thisObject.pointerDirection = 'right' - } - function setClosed () { - animation = 'none' - xOffset = 0 - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON - thisObject.container.parentContainer.status = 'hidden' - thisObject.pointerDirection = 'left' - } - - function arrow () { - let point1 - let point2 - let point3 - - if (thisObject.pointerDirection === 'left') { - point1 = { - x: TAB_WIDTH * 3.5 / 10, - y: TAB_HEIGHT * 12.5 / 30 - } - - point2 = { - x: TAB_WIDTH * 6.5 / 10, - y: TAB_HEIGHT * 15 / 30 - } - - point3 = { - x: TAB_WIDTH * 3.5 / 10, - y: TAB_HEIGHT * 17.5 / 30 - } - } else { - point1 = { - x: TAB_WIDTH * 6.5 / 10, - y: TAB_HEIGHT * 12.5 / 30 - } - - point2 = { - x: TAB_WIDTH * 3.5 / 10, - y: TAB_HEIGHT * 15 / 30 - } - - point3 = { - x: TAB_WIDTH * 6.5 / 10, - y: TAB_HEIGHT * 17.5 / 30 - } } - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.closePath() - - let opacity = 1 - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' - browserCanvasContext.fill() - } - - function borders () { - let point1 - let point2 - let point3 - let point4 - - point1 = { - x: 0, - y: 0 + function onMouseClick(event) { + if (thisObject.pointerDirection === 'left') { + animation = 'opening' + thisObject.container.eventHandler.raiseEvent('opening') + } else { + animation = 'closing' + thisObject.container.eventHandler.raiseEvent('closing') + } } - point2 = { - x: TAB_WIDTH, - y: 0 + function getContainer(point) { + let container + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } } - point3 = { - x: TAB_WIDTH, - y: TAB_HEIGHT + function physics() { + if (isInitialized === false) { return } + animate() } - point4 = { - x: 0, - y: TAB_HEIGHT + function draw() { + if (isInitialized === false) { return } + borders() + arrow() } - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) - point4 = thisObject.container.frame.frameThisPoint(point4) + function animate() { + const STEP = 50 - let opacity + if (animation === 'opening') { + xOffset = xOffset + STEP + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + if (xOffset >= thisObject.container.parentContainer.frame.width) { + setOpened() + thisObject.container.eventHandler.raiseEvent('opened') + } + } - /* Shadow */ - - for (let i = 0; i <= 5; i++) { - opacity = 1 - (i / 100) - 0.93 - - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x + i, point1.y + i) - browserCanvasContext.lineTo(point2.x + i, point2.y + i) - browserCanvasContext.lineTo(point3.x + i, point3.y + i) - browserCanvasContext.lineTo(point4.x + i, point4.y + i) - browserCanvasContext.lineTo(point1.x + i, point1.y + i) - browserCanvasContext.closePath() - - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' - browserCanvasContext.lineWidth = 1 - browserCanvasContext.stroke() + if (animation === 'closing') { + xOffset = xOffset - STEP + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + if (xOffset <= 0) { + setClosed() + thisObject.container.eventHandler.raiseEvent('closed') + } + } } - /* Background and Border */ + function setOpened() { + animation = 'none' + xOffset = thisObject.container.parentContainer.frame.width + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + thisObject.container.parentContainer.status = 'visible' + thisObject.pointerDirection = 'right' + } + function setClosed() { + animation = 'none' + xOffset = 0 + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + thisObject.container.parentContainer.status = 'hidden' + thisObject.pointerDirection = 'left' + } - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.lineTo(point4.x, point4.y) - browserCanvasContext.lineTo(point1.x, point1.y) - browserCanvasContext.closePath() + function arrow() { + let point1 + let point2 + let point3 - opacity = 1 + if (thisObject.pointerDirection === 'left') { + point1 = { + x: TAB_WIDTH * 3.5 / 10, + y: TAB_HEIGHT * 12.5 / 30 + } - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + '' - browserCanvasContext.fill() + point2 = { + x: TAB_WIDTH * 6.5 / 10, + y: TAB_HEIGHT * 15 / 30 + } - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' - browserCanvasContext.lineWidth = 0.3 - browserCanvasContext.stroke() - } + point3 = { + x: TAB_WIDTH * 3.5 / 10, + y: TAB_HEIGHT * 17.5 / 30 + } + } else { + point1 = { + x: TAB_WIDTH * 6.5 / 10, + y: TAB_HEIGHT * 12.5 / 30 + } + + point2 = { + x: TAB_WIDTH * 3.5 / 10, + y: TAB_HEIGHT * 15 / 30 + } + + point3 = { + x: TAB_WIDTH * 6.5 / 10, + y: TAB_HEIGHT * 17.5 / 30 + } + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.closePath() + + let opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.fill() + } + + function borders() { + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: TAB_WIDTH, + y: 0 + } + + point3 = { + x: TAB_WIDTH, + y: TAB_HEIGHT + } + + point4 = { + x: 0, + y: TAB_HEIGHT + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + point4 = thisObject.container.frame.frameThisPoint(point4) + + let opacity + + /* Shadow */ + + for (let i = 0; i <= 5; i++) { + opacity = 1 - (i / 100) - 0.93 + + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x + i, point1.y + i) + browserCanvasContext.lineTo(point2.x + i, point2.y + i) + browserCanvasContext.lineTo(point3.x + i, point3.y + i) + browserCanvasContext.lineTo(point4.x + i, point4.y + i) + browserCanvasContext.lineTo(point1.x + i, point1.y + i) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() + } + + /* Background and Border */ + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() + + opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + '' + browserCanvasContext.fill() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.lineWidth = 0.3 + browserCanvasContext.stroke() + } } diff --git a/Spaces/ChartingSpace.js b/Spaces/ChartingSpace.js index afbca8ce9..f42e0c77c 100644 --- a/Spaces/ChartingSpace.js +++ b/Spaces/ChartingSpace.js @@ -6,441 +6,441 @@ changes, then all charts in it are replotted with the corresponging data. */ -function newChartingSpace () { - const MODULE_NAME = 'Charting Space' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newChartingSpace() { + const MODULE_NAME = 'Charting Space' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - visible: false, - container: undefined, - inViewport: undefined, - timeMachines: undefined, - viewport: undefined, - payload: undefined, - onKeyPressed: onKeyPressed, - reset: reset, - oneScreenUp: oneScreenUp, - oneScreenDown: oneScreenDown, - oneScreenLeft: oneScreenLeft, - oneScreenRight: oneScreenRight, - fitFunction: fitFunction, - isThisPointVisible: isThisPointVisible, - physics: physics, - draw: draw, - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize, - finalize: finalize - } + let thisObject = { + visible: false, + container: undefined, + inViewport: undefined, + timeMachines: undefined, + viewport: undefined, + payload: undefined, + onKeyPressed: onKeyPressed, + reset: reset, + oneScreenUp: oneScreenUp, + oneScreenDown: oneScreenDown, + oneScreenLeft: oneScreenLeft, + oneScreenRight: oneScreenRight, + fitFunction: fitFunction, + isThisPointVisible: isThisPointVisible, + physics: physics, + draw: draw, + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize, + finalize: finalize + } - let canvasBrowserResizedEventSubscriptionId - let timeMachinesMap - let syncWithDesignerLoop + let canvasBrowserResizedEventSubscriptionId + let timeMachinesMap + let syncWithDesignerLoop - const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25 + const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25 - initialSetup() - - let isInitialized = false - - return thisObject - - function reset () { - finalize() initialSetup() - isInitialized = false - initialize() - } - function initialSetup () { - thisObject.timeMachines = [] - thisObject.visible = true - timeMachinesMap = new Map() - syncWithDesignerLoop = 0 - thisObject.inViewport = new Map() + let isInitialized = false - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) + return thisObject - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - } - - function finalize () { - for (let i = 0; i < thisObject.timeMachines.length; i++) { - let timeMachine = thisObject.timeMachines[i] - timeMachine.finalize() + function reset() { + finalize() + initialSetup() + isInitialized = false + initialize() } - thisObject.inViewport = undefined - thisObject.timeMachines = undefined - timeMachinesMap = undefined + function initialSetup() { + thisObject.timeMachines = [] + thisObject.visible = true + timeMachinesMap = new Map() + syncWithDesignerLoop = 0 + thisObject.inViewport = new Map() - thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId) + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - thisObject.container.finalize() - thisObject.container = undefined - - if (thisObject.viewport !== undefined) { - thisObject.viewport.finalize() - thisObject.viewport = undefined + thisObject.container.isDraggeable = false + thisObject.container.isWheelable = false } - thisObject.payload = undefined - } - - function initialize () { - if (isInitialized === true) { return } - if (canvas.designSpace === undefined) { return } - if (canvas.designSpace.workspace === undefined) { return } - - let rootNodes = canvas.designSpace.workspace.workspaceNode.rootNodes - for (let i = 0; i < rootNodes.length; i++) { - let rootNode = rootNodes[i] - if (rootNode !== null) { - if (rootNode.type === 'Charting Space') { - thisObject.payload = rootNode.payload + function finalize() { + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[i] + timeMachine.finalize() } - } + + thisObject.inViewport = undefined + thisObject.timeMachines = undefined + timeMachinesMap = undefined + + thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + + if (thisObject.viewport !== undefined) { + thisObject.viewport.finalize() + thisObject.viewport = undefined + } + + thisObject.payload = undefined } - if (thisObject.payload === undefined) { - // if (ERROR_LOG === true) { logger.write('[WARN] initialize -> There must exist a Charting Space at the Design Space in order to enable Charts. PLease create one and refreash your browser. ') } - return - } + function initialize() { + if (isInitialized === true) { return } + if (canvas.designSpace === undefined) { return } + if (canvas.designSpace.workspace === undefined) { return } - thisObject.viewport = newViewport() - if (thisObject.payload.node.viewport === undefined) { - if (ERROR_LOG === true) { logger.write('[WARN] initialize -> There must exist a Viewport node attached to the Charting Space node in order for the Viewport save its properties. ') } - return - } else { - thisObject.viewport.payload = thisObject.payload.node.viewport.payload - } + let rootNodes = canvas.designSpace.workspace.workspaceNode.rootNodes + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode !== null) { + if (rootNode.type === 'Charting Space') { + thisObject.payload = rootNode.payload + } + } + } - thisObject.viewport.initialize() + if (thisObject.payload === undefined) { + // if (ERROR_LOG === true) { logger.write('[WARN] initialize -> There must exist a Charting Space at the Design Space in order to enable Charts. PLease create one and refreash your browser. ') } + return + } - canvasBrowserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) - - isInitialized = true - } - - function getContainer (point, purpose) { - if (thisObject.visible !== true) { return } - if (thisObject.viewport === undefined) { return } - if (thisObject.viewport.isThisPointInViewport(point) === false) { return } - - let container - - /* This first step is not actually to get the container but to allow things to be turned off in case there is a switch of focus from one time machine to another */ - for (let i = 0; i < thisObject.timeMachines.length; i++) { - container = thisObject.timeMachines[i].container - if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) { - container.eventHandler.raiseEvent('onMouseNotOver') - } - } - - /* - Now we see which is the inner most container that has it. - In this case we will ask all the time machines even if one of them already returned a matching container. - This will help the others know they are not on ofcus - */ - let containerFound - for (let i = 0; i < thisObject.timeMachines.length; i++) { - container = thisObject.timeMachines[i].getContainer(point, purpose) - if (container !== undefined) { - if (purpose !== undefined) { - if (containerFound === undefined) { - containerFound = container - } + thisObject.viewport = newViewport() + if (thisObject.payload.node.viewport === undefined) { + if (ERROR_LOG === true) { logger.write('[WARN] initialize -> There must exist a Viewport node attached to the Charting Space node in order for the Viewport save its properties. ') } + return } else { - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - if (containerFound === undefined) { - containerFound = container - } - } + thisObject.viewport.payload = thisObject.payload.node.viewport.payload } - } - } - if (containerFound !== undefined) { - containerFound.space = 'Charting Space' - return containerFound + + thisObject.viewport.initialize() + + canvasBrowserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + + isInitialized = true } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - thisObject.container.space = 'Charting Space' - return thisObject.container - } else { - return undefined - } - } + function getContainer(point, purpose) { + if (thisObject.visible !== true) { return } + if (thisObject.viewport === undefined) { return } + if (thisObject.viewport.isThisPointInViewport(point) === false) { return } - function resize () { - thisObject.viewport.resize() - thisObject.container.frame.width = browserCanvas.width - thisObject.container.frame.height = COCKPIT_SPACE_POSITION - } + let container - function oneScreenUp () { - if (thisObject.visible === false) { return } - let displaceVector = { - x: 0, - y: browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 - } - - canvas.chartingSpace.viewport.displace(displaceVector) - } - - function oneScreenDown () { - if (thisObject.visible === false) { return } - let displaceVector = { - x: 0, - y: -browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 - } - - canvas.chartingSpace.viewport.displace(displaceVector) - } - - function oneScreenLeft () { - if (thisObject.visible === false) { return } - let displaceVector = { - x: browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, - y: 0 - } - - canvas.chartingSpace.viewport.displace(displaceVector, true) - } - - function oneScreenRight () { - if (thisObject.visible === false) { return } - let displaceVector = { - x: -browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, - y: 0 - } - - canvas.chartingSpace.viewport.displace(displaceVector, true) - } - - function fitFunction (point, fullVisible) { - /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ - - let returnPoint = { - x: point.x, - y: point.y - } - - if (point.x > browserCanvas.width) { - returnPoint.x = browserCanvas.width - } - - if (point.x < 0) { - returnPoint.x = 0 - } - - if (fullVisible === true) { - if (point.y > COCKPIT_SPACE_POSITION) { - returnPoint.y = COCKPIT_SPACE_POSITION - } - } else { - if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) { - returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2 - } - } - - if (point.y < TOP_SPACE_HEIGHT) { - returnPoint.y = TOP_SPACE_HEIGHT - } - - return returnPoint - } - - function isThisPointVisible (point) { - if (point.x > browserCanvas.width) { - return false - } - - if (point.x < 0) { - return false - } - - if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) { - return false - } - - if (point.y < 0) { - return false - } - - return true - } - - function physics () { - initialize() - thisObjectPhysics() - if (thisObject.visible !== true) { return } - if (thisObject.viewport !== undefined) { - thisObject.viewport.physics() - } - childrenPhysics() - syncWithDesigner() - } - - function onKeyPressed (event) { - if (thisObject.visible !== true) { return } - for (let j = 0; j < thisObject.timeMachines.length; j++) { - let timeMachine = thisObject.timeMachines[j] - if (timeMachine.onFocus === true) { - timeMachine.onKeyPressed(event) - } - } - } - - function syncWithDesigner () { - if (thisObject.payload === undefined) { return } - if (thisObject.payload.node === undefined) { return } - syncWithDesignerLoop = syncWithDesignerLoop + 0.00000000001 - - if (thisObject.payload.node.dashboards !== undefined) { - for (let i = 0; i < thisObject.payload.node.dashboards.length; i++) { - let dashboard = thisObject.payload.node.dashboards[i] - if (dashboard.timeMachines !== undefined) { - for (let j = 0; j < dashboard.timeMachines.length; j++) { - let node = dashboard.timeMachines[j] - let timeMachine = timeMachinesMap.get(node.id) - if (timeMachine === undefined) { - /* The time machine node is new, thus we need to initialize a new timeMachine */ - initializeTimeMachine(node, syncWithDesignerLoop) - } else { - /* The time machine already exists, we tag it as existing at the current loop. */ - timeMachine.syncWithDesignerLoop = syncWithDesignerLoop + /* This first step is not actually to get the container but to allow things to be turned off in case there is a switch of focus from one time machine to another */ + for (let i = 0; i < thisObject.timeMachines.length; i++) { + container = thisObject.timeMachines[i].container + if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) { + container.eventHandler.raiseEvent('onMouseNotOver') } - } } - } + + /* + Now we see which is the inner most container that has it. + In this case we will ask all the time machines even if one of them already returned a matching container. + This will help the others know they are not on ofcus + */ + let containerFound + for (let i = 0; i < thisObject.timeMachines.length; i++) { + container = thisObject.timeMachines[i].getContainer(point, purpose) + if (container !== undefined) { + if (purpose !== undefined) { + if (containerFound === undefined) { + containerFound = container + } + } else { + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + if (containerFound === undefined) { + containerFound = container + } + } + } + } + } + if (containerFound !== undefined) { + containerFound.space = 'Charting Space' + return containerFound + } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + thisObject.container.space = 'Charting Space' + return thisObject.container + } else { + return undefined + } } - /* We check all the timeMachines we have to see if we need to remove any of them */ - for (let i = 0; i < thisObject.timeMachines.length; i++) { - let timeMachine = thisObject.timeMachines[i] - if (timeMachine.syncWithDesignerLoop < syncWithDesignerLoop) { - /* Must be removed */ - timeMachine.finalize() - timeMachinesMap.delete(timeMachine.nodeId) - thisObject.timeMachines.splice(i, 1) - /* We remove one at the time */ - return - } + function resize() { + thisObject.viewport.resize() + thisObject.container.frame.width = browserCanvas.width + thisObject.container.frame.height = COCKPIT_SPACE_POSITION } - function initializeTimeMachine (node, syncWithDesignerLoop) { - if (node.payload === undefined) { return } // not ready to consider this Time Machine - if (node.payload.uiObject === undefined) { return } + function oneScreenUp() { + if (thisObject.visible === false) { return } + let displaceVector = { + x: 0, + y: browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 + } - let timeMachine = newTimeMachine() - timeMachine.syncWithDesignerLoop = syncWithDesignerLoop - timeMachine.payload = node.payload - timeMachine.nodeId = node.id + canvas.chartingSpace.viewport.displace(displaceVector) + } - timeMachinesMap.set(node.id, timeMachine) - timeMachine.payload.uiObject.setValue('Loading...') + function oneScreenDown() { + if (thisObject.visible === false) { return } + let displaceVector = { + x: 0, + y: -browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 + } - /* Setting up the new time machine. */ - timeMachine.container.frame.position.x = browserCanvas.width / 2 - browserCanvas.width / TIME_MACHINE_WIDTH / 2 - timeMachine.container.frame.position.y = browserCanvas.height / 2 - (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT / 2 - timeMachine.initialize(onTimeMachineInitialized) + canvas.chartingSpace.viewport.displace(displaceVector) + } + + function oneScreenLeft() { + if (thisObject.visible === false) { return } + let displaceVector = { + x: browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, + y: 0 + } + + canvas.chartingSpace.viewport.displace(displaceVector, true) + } + + function oneScreenRight() { + if (thisObject.visible === false) { return } + let displaceVector = { + x: -browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, + y: 0 + } + + canvas.chartingSpace.viewport.displace(displaceVector, true) + } + + function fitFunction(point, fullVisible) { + /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ + + let returnPoint = { + x: point.x, + y: point.y + } + + if (point.x > browserCanvas.width) { + returnPoint.x = browserCanvas.width + } + + if (point.x < 0) { + returnPoint.x = 0 + } + + if (fullVisible === true) { + if (point.y > COCKPIT_SPACE_POSITION) { + returnPoint.y = COCKPIT_SPACE_POSITION + } + } else { + if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) { + returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2 + } + } + + if (point.y < TOP_SPACE_HEIGHT) { + returnPoint.y = TOP_SPACE_HEIGHT + } + + return returnPoint + } + + function isThisPointVisible(point) { + if (point.x > browserCanvas.width) { + return false + } + + if (point.x < 0) { + return false + } + + if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) { + return false + } + + if (point.y < 0) { + return false + } + + return true + } + + function physics() { + initialize() + thisObjectPhysics() + if (thisObject.visible !== true) { return } + if (thisObject.viewport !== undefined) { + thisObject.viewport.physics() + } + childrenPhysics() + syncWithDesigner() + } + + function onKeyPressed(event) { + if (thisObject.visible !== true) { return } + for (let j = 0; j < thisObject.timeMachines.length; j++) { + let timeMachine = thisObject.timeMachines[j] + if (timeMachine.onFocus === true) { + timeMachine.onKeyPressed(event) + } + } + } + + function syncWithDesigner() { + if (thisObject.payload === undefined) { return } + if (thisObject.payload.node === undefined) { return } + syncWithDesignerLoop = syncWithDesignerLoop + 0.00000000001 + + if (thisObject.payload.node.dashboards !== undefined) { + for (let i = 0; i < thisObject.payload.node.dashboards.length; i++) { + let dashboard = thisObject.payload.node.dashboards[i] + if (dashboard.timeMachines !== undefined) { + for (let j = 0; j < dashboard.timeMachines.length; j++) { + let node = dashboard.timeMachines[j] + let timeMachine = timeMachinesMap.get(node.id) + if (timeMachine === undefined) { + /* The time machine node is new, thus we need to initialize a new timeMachine */ + initializeTimeMachine(node, syncWithDesignerLoop) + } else { + /* The time machine already exists, we tag it as existing at the current loop. */ + timeMachine.syncWithDesignerLoop = syncWithDesignerLoop + } + } + } + } + } + + /* We check all the timeMachines we have to see if we need to remove any of them */ + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[i] + if (timeMachine.syncWithDesignerLoop < syncWithDesignerLoop) { + /* Must be removed */ + timeMachine.finalize() + timeMachinesMap.delete(timeMachine.nodeId) + thisObject.timeMachines.splice(i, 1) + /* We remove one at the time */ + return + } + } + + function initializeTimeMachine(node, syncWithDesignerLoop) { + if (node.payload === undefined) { return } // not ready to consider this Time Machine + if (node.payload.uiObject === undefined) { return } + + let timeMachine = newTimeMachine() + timeMachine.syncWithDesignerLoop = syncWithDesignerLoop + timeMachine.payload = node.payload + timeMachine.nodeId = node.id + + timeMachinesMap.set(node.id, timeMachine) + timeMachine.payload.uiObject.setValue('Loading...') + + /* Setting up the new time machine. */ + timeMachine.container.frame.position.x = browserCanvas.width / 2 - browserCanvas.width / TIME_MACHINE_WIDTH / 2 + timeMachine.container.frame.position.y = browserCanvas.height / 2 - (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT / 2 + timeMachine.initialize(onTimeMachineInitialized) + + function onTimeMachineInitialized() { + thisObject.timeMachines.push(timeMachine) + timeMachine.payload.uiObject.setValue('') + if (canvas.chartingSpace.viewport !== undefined) { + canvas.chartingSpace.viewport.raiseEvents() // These events will impacts on objects just initialized. + } + } + } + } + + function thisObjectPhysics() { + thisObject.container.frame.height = COCKPIT_SPACE_POSITION + + if (thisObject.container.frame.height <= TOP_SPACE_HEIGHT) { + thisObject.visible = false + if (thisObject.viewport !== undefined) { + thisObject.viewport.visible = false + } + } else { + thisObject.visible = true + if (thisObject.viewport !== undefined) { + thisObject.viewport.visible = true + } + } - function onTimeMachineInitialized () { - thisObject.timeMachines.push(timeMachine) - timeMachine.payload.uiObject.setValue('') if (canvas.chartingSpace.viewport !== undefined) { - canvas.chartingSpace.viewport.raiseEvents() // These events will impacts on objects just initialized. + canvas.chartingSpace.viewport.resize() } - } - } - } - - function thisObjectPhysics () { - thisObject.container.frame.height = COCKPIT_SPACE_POSITION - - if (thisObject.container.frame.height <= TOP_SPACE_HEIGHT) { - thisObject.visible = false - if (thisObject.viewport !== undefined) { - thisObject.viewport.visible = false - } - } else { - thisObject.visible = true - if (thisObject.viewport !== undefined) { - thisObject.viewport.visible = true - } } - if (canvas.chartingSpace.viewport !== undefined) { - canvas.chartingSpace.viewport.resize() - } - } + function childrenPhysics() { + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[i] + if (timeMachine.payload.node === undefined) { + continue + } - function childrenPhysics () { - for (let i = 0; i < thisObject.timeMachines.length; i++) { - let timeMachine = thisObject.timeMachines[i] - if (timeMachine.payload.node === undefined) { - continue - } - - if (timeMachine.container.frame.isInViewPort()) { - thisObject.inViewport.set(timeMachine.payload.node.id, timeMachine) - } else { - thisObject.inViewport.delete(timeMachine.payload.node.id) - } - timeMachine.physics() - } - } - - function drawBackground () { - if (thisObject.visible === false) { return } - drawSpaceBackground() - - for (let i = 0; i < thisObject.timeMachines.length; i++) { - let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1] - timeMachine.drawBackground() - } - } - - function draw () { - if (canWeDraw === false) { return } - if (thisObject.visible === false) { return } - drawBackground() - - for (let i = 0; i < thisObject.timeMachines.length; i++) { - let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1] - timeMachine.draw() + if (timeMachine.container.frame.isInViewPort()) { + thisObject.inViewport.set(timeMachine.payload.node.id, timeMachine) + } else { + thisObject.inViewport.delete(timeMachine.payload.node.id) + } + timeMachine.physics() + } } - drawForeground() - } + function drawBackground() { + if (thisObject.visible === false) { return } + drawSpaceBackground() - function drawForeground () { - for (let i = 0; i < thisObject.timeMachines.length; i++) { - let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1] - timeMachine.drawForeground() - } - } - - function drawSpaceBackground () { - let opacity = '1' - let fromPoint = { - x: 0, - y: 0 + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1] + timeMachine.drawBackground() + } } - let toPoint = { - x: browserCanvas.width, - y: COCKPIT_SPACE_POSITION + function draw() { + if (canWeDraw === false) { return } + if (thisObject.visible === false) { return } + drawBackground() + + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1] + timeMachine.draw() + } + + drawForeground() } - browserCanvasContext.beginPath() - browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')' - browserCanvasContext.closePath() - browserCanvasContext.fill() - } + function drawForeground() { + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1] + timeMachine.drawForeground() + } + } + + function drawSpaceBackground() { + let opacity = '1' + let fromPoint = { + x: 0, + y: 0 + } + + let toPoint = { + x: browserCanvas.width, + y: COCKPIT_SPACE_POSITION + } + + browserCanvasContext.beginPath() + browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')' + browserCanvasContext.closePath() + browserCanvasContext.fill() + } } diff --git a/Spaces/CockpitSpace.js b/Spaces/CockpitSpace.js index af67991f7..efb6c4213 100644 --- a/Spaces/CockpitSpace.js +++ b/Spaces/CockpitSpace.js @@ -1,370 +1,370 @@ - function newCockpitSpace () { - const MODULE_NAME = 'CockpitSpace' - const STATUS_TYPES = { - ALL_GOOD: 1, - WARNING: 2 - } - let thisObject = { - container: undefined, - status: 'BOTTOM', - fullscreen: undefined, - statusTypes: STATUS_TYPES, - setStatus: setStatus, - toTop: toTop, - toBottom: toBottom, - toMiddle: toMiddle, - moveUp: moveUp, - moveDown: moveDown, - draw: draw, - physics: physics, - getContainer: getContainer, - finalize: finalize, - initialize: initialize, - initializePosition: initializePosition - } +function newCockpitSpace() { + const MODULE_NAME = 'CockpitSpace' + const STATUS_TYPES = { + ALL_GOOD: 1, + WARNING: 2 + } + let thisObject = { + container: undefined, + status: 'BOTTOM', + fullscreen: undefined, + statusTypes: STATUS_TYPES, + setStatus: setStatus, + toTop: toTop, + toBottom: toBottom, + toMiddle: toMiddle, + moveUp: moveUp, + moveDown: moveDown, + draw: draw, + physics: physics, + getContainer: getContainer, + finalize: finalize, + initialize: initialize, + initializePosition: initializePosition + } - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.detectMouseOver = true - thisObject.container.isDraggeable = true - thisObject.container.notDraggingOnX = true + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.detectMouseOver = true + thisObject.container.isDraggeable = true + thisObject.container.notDraggingOnX = true - controlsMap = new Map() - resize() + controlsMap = new Map() + resize() - let selfMouseClickEventSubscriptionId - let canvasBrowserResizedEventSubscriptionId + let selfMouseClickEventSubscriptionId + let canvasBrowserResizedEventSubscriptionId - let statusCounter = 0 - let statusText - let statusType - let isInitilized = false + let statusCounter = 0 + let statusText + let statusType + let isInitilized = false - return thisObject + return thisObject - function finalize () { - thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) - thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId) + function finalize() { + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId) - thisObject.container.finalize() - thisObject.container = undefined - thisObject.fullscreen = undefined - } + thisObject.container.finalize() + thisObject.container = undefined + thisObject.fullscreen = undefined + } - function initialize () { - canvasBrowserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) - selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + function initialize() { + canvasBrowserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - thisObject.fullscreen = newFullScreen() - thisObject.fullscreen.container.connectToParent(thisObject.container) - thisObject.fullscreen.initialize() - } + thisObject.fullscreen = newFullScreen() + thisObject.fullscreen.container.connectToParent(thisObject.container) + thisObject.fullscreen.initialize() + } - function initializePosition () { - thisObject.container.frame.position.x = 0 + function initializePosition() { + thisObject.container.frame.position.x = 0 - let INITIAL_POSITION - if (canvas.designSpace.workspace.enabled === true) { - let localStorage = window.localStorage.getItem(MODULE_NAME) - if (localStorage !== null) { - storage = JSON.parse(localStorage) - thisObject.container.frame.position.y = storage.spacePosition - } else { - INITIAL_POSITION = 55 - thisObject.container.frame.position.y = browserCanvas.height * INITIAL_POSITION / 100 - COCKPIT_SPACE_HEIGHT - } - } else { - INITIAL_POSITION = 100 - thisObject.container.frame.position.y = browserCanvas.height * INITIAL_POSITION / 100 - COCKPIT_SPACE_HEIGHT - } - isInitilized = true - } + let INITIAL_POSITION + if (canvas.designSpace.workspace.enabled === true) { + let localStorage = window.localStorage.getItem(MODULE_NAME) + if (localStorage !== null) { + storage = JSON.parse(localStorage) + thisObject.container.frame.position.y = storage.spacePosition + } else { + INITIAL_POSITION = 55 + thisObject.container.frame.position.y = browserCanvas.height * INITIAL_POSITION / 100 - COCKPIT_SPACE_HEIGHT + } + } else { + INITIAL_POSITION = 100 + thisObject.container.frame.position.y = browserCanvas.height * INITIAL_POSITION / 100 - COCKPIT_SPACE_HEIGHT + } + isInitilized = true + } - function onMouseClick (event) { + function onMouseClick(event) { - } + } - function setStatus (text, counter, type) { - statusCounter = counter - statusText = text - statusType = type - } + function setStatus(text, counter, type) { + statusCounter = counter + statusText = text + statusType = type + } - function resize () { - thisObject.container.frame.width = browserCanvas.width - thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT + function resize() { + thisObject.container.frame.width = browserCanvas.width + thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - switch (thisObject.status) { - case 'BOTTOM': { - thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT - break - } - case 'TOP': { - thisObject.container.frame.position.y = TOP_SPACE_HEIGHT - break - } - } - } + switch (thisObject.status) { + case 'BOTTOM': { + thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT + break + } + case 'TOP': { + thisObject.container.frame.position.y = TOP_SPACE_HEIGHT + break + } + } + } - function toTop () { - thisObject.container.frame.position.y = COCKPIT_SPACE_HEIGHT - } + function toTop() { + thisObject.container.frame.position.y = COCKPIT_SPACE_HEIGHT + } - function toBottom () { - thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT - } + function toBottom() { + thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT + } - function toMiddle () { - thisObject.container.frame.position.y = browserCanvas.height / 2 - COCKPIT_SPACE_HEIGHT - } + function toMiddle() { + thisObject.container.frame.position.y = browserCanvas.height / 2 - COCKPIT_SPACE_HEIGHT + } - function moveUp () { - thisObject.container.frame.position.y = thisObject.container.frame.position.y - COCKPIT_SPACE_HEIGHT * 2 - if (thisObject.container.frame.position.y < 0) { - thisObject.container.frame.position.y = 0 - } - } + function moveUp() { + thisObject.container.frame.position.y = thisObject.container.frame.position.y - COCKPIT_SPACE_HEIGHT * 2 + if (thisObject.container.frame.position.y < 0) { + thisObject.container.frame.position.y = 0 + } + } - function moveDown () { - thisObject.container.frame.position.y = thisObject.container.frame.position.y + COCKPIT_SPACE_HEIGHT * 2 - if (thisObject.container.frame.position.y > browserCanvas.height - COCKPIT_SPACE_HEIGHT) { - thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT - } - } + function moveDown() { + thisObject.container.frame.position.y = thisObject.container.frame.position.y + COCKPIT_SPACE_HEIGHT * 2 + if (thisObject.container.frame.position.y > browserCanvas.height - COCKPIT_SPACE_HEIGHT) { + thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT + } + } - function statusPhysics () { - statusCounter-- - if (statusCounter < 0) { - statusCounter = 0 - statusText = undefined, - statusType = undefined - } - } + function statusPhysics() { + statusCounter-- + if (statusCounter < 0) { + statusCounter = 0 + statusText = undefined, + statusType = undefined + } + } - function physics () { - thisObjectPhysics() - childrenPhysics() - statusPhysics() - } + function physics() { + thisObjectPhysics() + childrenPhysics() + statusPhysics() + } - function childrenPhysics () { - thisObject.fullscreen.physics() - } - function thisObjectPhysics () { - if (isInitilized === false) { return } - /* Check the limits */ + function childrenPhysics() { + thisObject.fullscreen.physics() + } + function thisObjectPhysics() { + if (isInitilized === false) { return } + /* Check the limits */ - thisObject.status = 'MIDDLE' + thisObject.status = 'MIDDLE' - if (canvas.designSpace.workspace.enabled === true) { - thisObject.container.isDraggeable = true - } else { - thisObject.container.isDraggeable = false - } + if (canvas.designSpace.workspace.enabled === true) { + thisObject.container.isDraggeable = true + } else { + thisObject.container.isDraggeable = false + } - if (thisObject.container.frame.position.y > browserCanvas.height * 99.5 / 100 - COCKPIT_SPACE_HEIGHT) { - thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT - thisObject.status = 'BOTTOM' - canvas.designSpace.makeInvisible() - canvas.floatingSpace.makeInvisible() - } else { - canvas.designSpace.makeVisible() - canvas.floatingSpace.makeVisible() - } + if (thisObject.container.frame.position.y > browserCanvas.height * 99.5 / 100 - COCKPIT_SPACE_HEIGHT) { + thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT + thisObject.status = 'BOTTOM' + canvas.designSpace.makeInvisible() + canvas.floatingSpace.makeInvisible() + } else { + canvas.designSpace.makeVisible() + canvas.floatingSpace.makeVisible() + } - if (thisObject.container.frame.position.y < browserCanvas.height * 0.5 / 100 + TOP_SPACE_HEIGHT) { - thisObject.container.frame.position.y = TOP_SPACE_HEIGHT - thisObject.status = 'TOP' - canvas.panelsSpace.visible = false - } else { - canvas.panelsSpace.visible = true - } + if (thisObject.container.frame.position.y < browserCanvas.height * 0.5 / 100 + TOP_SPACE_HEIGHT) { + thisObject.container.frame.position.y = TOP_SPACE_HEIGHT + thisObject.status = 'TOP' + canvas.panelsSpace.visible = false + } else { + canvas.panelsSpace.visible = true + } - COCKPIT_SPACE_POSITION = thisObject.container.frame.position.y - let storage = { - spacePosition: COCKPIT_SPACE_POSITION - } - window.localStorage.setItem(MODULE_NAME, JSON.stringify(storage)) - if (canvas.chartingSpace.viewport !== undefined) { - canvas.chartingSpace.viewport.resize() - } - } + COCKPIT_SPACE_POSITION = thisObject.container.frame.position.y + let storage = { + spacePosition: COCKPIT_SPACE_POSITION + } + window.localStorage.setItem(MODULE_NAME, JSON.stringify(storage)) + if (canvas.chartingSpace.viewport !== undefined) { + canvas.chartingSpace.viewport.resize() + } + } - function getContainer (point) { - let container + function getContainer(point) { + let container - // container = thisObject.fullscreen.getContainer(point) - // if (container !== undefined) { return container } + // container = thisObject.fullscreen.getContainer(point) + // if (container !== undefined) { return container } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - thisObject.container.space = 'Cockpit Space' - return thisObject.container - } else { - return undefined - } - } + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + thisObject.container.space = 'Cockpit Space' + return thisObject.container + } else { + return undefined + } + } - function draw () { - if (canWeDraw === false) { return } - thisObject.container.frame.draw(false, false) + function draw() { + if (canWeDraw === false) { return } + thisObject.container.frame.draw(false, false) - drawBackground() + drawBackground() - // thisObject.fullscreen.draw() - } + // thisObject.fullscreen.draw() + } - function drawBackground () { - let opacity = 1 + function drawBackground() { + let opacity = 1 - let zeroPoint = { - x: 0, - y: 0 - } + let zeroPoint = { + x: 0, + y: 0 + } - const RED_LINE_HIGHT = 2 + const RED_LINE_HIGHT = 2 - zeroPoint = thisObject.container.frame.frameThisPoint(zeroPoint) + zeroPoint = thisObject.container.frame.frameThisPoint(zeroPoint) - let barColor = UI_COLOR.DARK_TURQUOISE // default - let textColor + let barColor = UI_COLOR.DARK_TURQUOISE // default + let textColor - if (statusType !== undefined) { - switch (statusType) { - case STATUS_TYPES.ALL_GOOD: - { - barColor = UI_COLOR.PATINATED_TURQUOISE - textColor = UI_COLOR.WHITE - break - } - case STATUS_TYPES.WARNING: - { - barColor = UI_COLOR.RED - textColor = UI_COLOR.TITANIUM_YELLOW - break - } - } - } + if (statusType !== undefined) { + switch (statusType) { + case STATUS_TYPES.ALL_GOOD: + { + barColor = UI_COLOR.PATINATED_TURQUOISE + textColor = UI_COLOR.WHITE + break + } + case STATUS_TYPES.WARNING: + { + barColor = UI_COLOR.RED + textColor = UI_COLOR.TITANIUM_YELLOW + break + } + } + } - browserCanvasContext.beginPath() - browserCanvasContext.rect(zeroPoint.x, zeroPoint.y, thisObject.container.frame.width, thisObject.container.frame.height) - browserCanvasContext.fillStyle = 'rgba(' + barColor + ', ' + opacity + ')' - browserCanvasContext.closePath() - browserCanvasContext.fill() + browserCanvasContext.beginPath() + browserCanvasContext.rect(zeroPoint.x, zeroPoint.y, thisObject.container.frame.width, thisObject.container.frame.height) + browserCanvasContext.fillStyle = 'rgba(' + barColor + ', ' + opacity + ')' + browserCanvasContext.closePath() + browserCanvasContext.fill() - browserCanvasContext.beginPath() - browserCanvasContext.rect(zeroPoint.x, zeroPoint.y, thisObject.container.frame.width, RED_LINE_HIGHT) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')' - browserCanvasContext.closePath() - browserCanvasContext.fill() + browserCanvasContext.beginPath() + browserCanvasContext.rect(zeroPoint.x, zeroPoint.y, thisObject.container.frame.width, RED_LINE_HIGHT) + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')' + browserCanvasContext.closePath() + browserCanvasContext.fill() - browserCanvasContext.beginPath() - browserCanvasContext.rect(zeroPoint.x, zeroPoint.y - RED_LINE_HIGHT + thisObject.container.frame.height, thisObject.container.frame.width, RED_LINE_HIGHT) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')' - browserCanvasContext.closePath() - browserCanvasContext.fill() + browserCanvasContext.beginPath() + browserCanvasContext.rect(zeroPoint.x, zeroPoint.y - RED_LINE_HIGHT + thisObject.container.frame.height, thisObject.container.frame.width, RED_LINE_HIGHT) + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')' + browserCanvasContext.closePath() + browserCanvasContext.fill() - if (statusText !== undefined) { - let position = { - x: thisObject.container.frame.width / 2, - y: thisObject.container.frame.height / 2 + 5 - } - printLabel(statusText, position.x, position.y, 1, 15, textColor, true, thisObject.container) - } + if (statusText !== undefined) { + let position = { + x: thisObject.container.frame.width / 2, + y: thisObject.container.frame.height / 2 + 5 + } + printLabel(statusText, position.x, position.y, 1, 15, textColor, true, thisObject.container) + } - if (canvas.designSpace !== undefined) { - if (canvas.designSpace.workspace.enabled === true && statusText === undefined) { - arrow() - } - } - } + if (canvas.designSpace !== undefined) { + if (canvas.designSpace.workspace.enabled === true && statusText === undefined) { + arrow() + } + } + } - function arrow () { - const X_OFFSET = thisObject.container.frame.width / 2 - const Y_OFFSET = thisObject.container.frame.height / 2 - const HEIGHT = 6 - const WIDTH = 18 - const LINE_WIDTH = 3 - const OPACITY = 1 - let DISTANCE_BETWEEN_ARROWS = 0 - let ARROW_1_DIRECTION = 0 - let ARROW_2_DIRECTION = 0 + function arrow() { + const X_OFFSET = thisObject.container.frame.width / 2 + const Y_OFFSET = thisObject.container.frame.height / 2 + const HEIGHT = 6 + const WIDTH = 18 + const LINE_WIDTH = 3 + const OPACITY = 1 + let DISTANCE_BETWEEN_ARROWS = 0 + let ARROW_1_DIRECTION = 0 + let ARROW_2_DIRECTION = 0 - switch (thisObject.status) { + switch (thisObject.status) { - case ('TOP'): { - ARROW_1_DIRECTION = -1 - ARROW_2_DIRECTION = -1 - DISTANCE_BETWEEN_ARROWS = 6 - break - } - case ('MIDDLE'): { - ARROW_1_DIRECTION = 1 - ARROW_2_DIRECTION = -1 - DISTANCE_BETWEEN_ARROWS = 9 - break - } - case ('BOTTOM'): { - ARROW_1_DIRECTION = 1 - ARROW_2_DIRECTION = 1 - DISTANCE_BETWEEN_ARROWS = 6 - break - } - } + case ('TOP'): { + ARROW_1_DIRECTION = -1 + ARROW_2_DIRECTION = -1 + DISTANCE_BETWEEN_ARROWS = 6 + break + } + case ('MIDDLE'): { + ARROW_1_DIRECTION = 1 + ARROW_2_DIRECTION = -1 + DISTANCE_BETWEEN_ARROWS = 9 + break + } + case ('BOTTOM'): { + ARROW_1_DIRECTION = 1 + ARROW_2_DIRECTION = 1 + DISTANCE_BETWEEN_ARROWS = 6 + break + } + } - point1 = { - x: X_OFFSET - WIDTH / 2, - y: Y_OFFSET + HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 - } + point1 = { + x: X_OFFSET - WIDTH / 2, + y: Y_OFFSET + HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 + } - point2 = { - x: X_OFFSET, - y: Y_OFFSET - HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 - } + point2 = { + x: X_OFFSET, + y: Y_OFFSET - HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 + } - point3 = { - x: X_OFFSET + WIDTH / 2, - y: Y_OFFSET + HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 - } + point3 = { + x: X_OFFSET + WIDTH / 2, + y: Y_OFFSET + HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 + } - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) - point4 = { - x: X_OFFSET - WIDTH / 2, - y: Y_OFFSET + HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 - } + point4 = { + x: X_OFFSET - WIDTH / 2, + y: Y_OFFSET + HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 + } - point5 = { - x: X_OFFSET, - y: Y_OFFSET - HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 - } + point5 = { + x: X_OFFSET, + y: Y_OFFSET - HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 + } - point6 = { - x: X_OFFSET + WIDTH / 2, - y: Y_OFFSET + HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 - } + point6 = { + x: X_OFFSET + WIDTH / 2, + y: Y_OFFSET + HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 + } - point4 = thisObject.container.frame.frameThisPoint(point4) - point5 = thisObject.container.frame.frameThisPoint(point5) - point6 = thisObject.container.frame.frameThisPoint(point6) + point4 = thisObject.container.frame.frameThisPoint(point4) + point5 = thisObject.container.frame.frameThisPoint(point5) + point6 = thisObject.container.frame.frameThisPoint(point6) - browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.beginPath() + browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.moveTo(point4.x, point4.y) - browserCanvasContext.lineTo(point5.x, point5.y) - browserCanvasContext.lineTo(point6.x, point6.y) + browserCanvasContext.moveTo(point4.x, point4.y) + browserCanvasContext.lineTo(point5.x, point5.y) + browserCanvasContext.lineTo(point6.x, point6.y) - browserCanvasContext.lineWidth = LINE_WIDTH - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.stroke() - } - } + browserCanvasContext.lineWidth = LINE_WIDTH + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.stroke() + } +} diff --git a/Spaces/DesignSpace.js b/Spaces/DesignSpace.js index 4940727b6..b67ffa44b 100644 --- a/Spaces/DesignSpace.js +++ b/Spaces/DesignSpace.js @@ -1,351 +1,351 @@ -function newDesignSpace () { - const MODULE_NAME = 'Designe Space' - let thisObject = { - sidePanel: undefined, - container: undefined, - iconCollection: undefined, - iconByUiObjectType: undefined, - workspace: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - makeVisible: makeVisible, - makeInvisible: makeInvisible, - initialize: initialize - } - - let container = newContainer() - container.initialize() - thisObject.container = container - - container.isDraggeable = false - - thisObject.iconCollection = new Map() - thisObject.iconByUiObjectType = new Map() - - return thisObject - - function initialize () { - loadIconCollection() - buildIconByUiObjectTypeMap() - - thisObject.workspace = newWorkspace() - thisObject.workspace.initialize() - } - - function buildIconByUiObjectTypeMap () { - /* Take types-icons relationships defined at the schema */ - for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { - let nodeDefinition = APP_SCHEMA_ARRAY[i] - let iconName = nodeDefinition.icon - if (iconName !== undefined) { - let icon = thisObject.iconCollection.get(iconName) - thisObject.iconByUiObjectType.set(nodeDefinition.type, icon) - } - } - } - - function loadIconCollection () { - const iconsNames = [ - 'analysis', - 'analysis-1', - 'approve', - 'attach', - 'attractive', - 'pyramid', - 'brainstorming', - 'broken-link', - 'chat', - 'chronometer', - 'compass', - 'competition', - 'content', - 'design-tool', - 'grid', - 'headphones', - 'html', - 'image', - 'layout', - 'loading', - 'login', - 'pantone', - 'paper-plane', - 'photo-camera', - 'piggy-bank', - 'pipette', - 'pixel', - 'placeholder', - 'planning', - 'promotion', - 'pyramid', - 'quality', - 'responsive', - 'schedule', - 'search', - 'security', - 'settings', - 'sitemap', - 'startup', - 'support', - 'tap', - 'menu-fix-pinned', - 'menu-fix-unpinned', - 'targeting', - 'task', - 'testing', - 'text', - 'timeline', - 'tools', - 'delete', - 'upload', - 'vector', - 'video-player', - 'menu-mobility-freeze', - 'menu-mobility-unfreeze', - 'menu-tree-minus', - 'menu-tree-plus', - 'menu-backup', - 'menu-share', - 'stop', - 'stage-open', - 'stage-close', - 'stage-trigger', - 'stage-trigger-trigger-on', - 'stage-trigger-trigger-off', - 'stage-trigger-take-position', - 'menu-tensor-fixed-angles', - 'menu-tensor-free-angles', - 'stage-open-position-size', - 'stage-open-take-profit', - 'stage-open-postion-rate', - 'session-live-trading', - 'session-paper-trading', - 'session-backtesting', - 'session-forward-testing', - 'network', - 'network-node', - 'bot-trading', - 'layer-manager', - 'process', - 'bot-indicator', - 'bot-sensor', - 'time-period', - 'data-mine', - 'procedure-loop', - 'calculations-procedure', - 'data-building-procedure', - 'procedure-initialization', - 'process-definition', - 'output-dataset', - 'data-dependency', - 'product-definition', - 'plotter-module', - 'status-dependency', - 'record-property', - 'record-definition', - 'plotter', - 'plotter-panel', - 'dataset-definition', - 'status-report', - 'execution-finished-event', - 'process-dependencies', - 'process-output', - 'social-bot', - 'execution-started-event', - 'shapes', - 'chart-point', - 'style', - 'chart-points', - 'shapes-polygon-vertex', - 'shapes-polygon-border', - 'shapes-polygon-body', - 'chart-point-formula', - 'style-condition', - 'shapes-polygon', - 'data-entry', - 'data-formula', - 'clone', - 'exchange-account-asset', - 'exchange-account-key', - 'user-keys', - 'user-assets', - 'asset', - 'exchange-accounts', - 'user-account', - 'market', - 'exchange-assets', - 'crypto-exchanges', - 'crypto-exchange', - 'exchange-markets', - 'charting-space', - 'time-line-chart', - 'time-frame-scale', - 'time-scale', - 'rate-scale', - 'time-machine', - 'data-product', - 'single-market-data', - 'data-storage', - 'dataset', - 'viewport', - 'bitfinex', - 'binance', - 'kucoin', - 'bittrex', - 'kraken', - 'poloniex', - 'upbit', - 'monero', - 'tether', - 'tron', - 'stellar', - 'qtum', - 'neo', - 'litecoin', - 'ethereum-classic', - 'ethereum', - 'eos', - 'dash', - 'cardano', - 'bitcoin-cash', - 'bitcoin', - 'binance-coin', - 'trend', - 'oscillator', - 'moving-average', - 'histogram', - 'band', - 'volume', - 'candles', - 'bitmex', - 'liquid', - 'hitbtc', - 'us-dollar', - 'distance-to-parent-200', - 'distance-to-parent-150', - 'distance-to-parent-100', - 'distance-to-parent-050', - 'distance-to-parent-025', - 'distance-to-parent-000', - 'angle-to-parent-360', - 'angle-to-parent-180', - 'angle-to-parent-090', - 'angle-to-parent-045', - 'angle-to-parent-000', - 'data-mining', - 'initial-definition', - 'next-phase-event', - 'testing-environment', - 'production-environment', - 'task-manager', - 'session-based-data', - 'session-independent-data', - 'session-reference', - 'dashboard', - 'toggle-auto-scale-manual', - 'toggle-auto-scale-auto-min-max', - 'toggle-auto-scale-auto-max', - 'toggle-auto-scale-auto-min', - 'toggle-panel-off', - 'toggle-auto-time-scale-auto-min', - 'toggle-auto-time-scale-auto-max', - 'toggle-auto-time-scale-auto-min-max', - 'toggle-auto-time-scale-manual', - 'mouse-pointer', - 'mouse-left-click', - 'mouse-right-click', - 'mouse-wheel-up', - 'mouse-wheel-down', - 'mouse-wheel-click', - 'key-alt', - 'key-shift', - 'key-ctrl', - 'hand-drag', - 'key-down', - 'key-left', - 'key-right', - 'key-up', - 'master-script', - 'scripts-library', - 'super-action', - 'super-scripts', - 'template-script', - 'template-structure', - 'template-target', - 'delink', - 'detach', - 'help', - 'key-a', - 'key-m', - 'key-r', - 'arrangement-horizontal-top', - 'arrangement-convex', - 'arrangement-horizontal-bottom', - 'arrangement-vertical-right', - 'arrangement-vertical-left', - 'arrangement-concave', - 'move-to-phase-event', - 'open-execution', - 'move-order', - 'market-order', - 'limit-order', - 'execution-algorithm', - 'cancel-order' - ] - - for (let i = 0; i < iconsNames.length; i++) { - let name = iconsNames[i] - loadImage(name) +function newDesignSpace() { + const MODULE_NAME = 'Designe Space' + let thisObject = { + sidePanel: undefined, + container: undefined, + iconCollection: undefined, + iconByUiObjectType: undefined, + workspace: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + makeVisible: makeVisible, + makeInvisible: makeInvisible, + initialize: initialize } - function loadImage (name) { - const PATH = 'Images/Icons/style-01/' - let image = new Image() - image.onload = onImageLoad - image.fileName = name + let container = newContainer() + container.initialize() + thisObject.container = container - function onImageLoad () { - image.canDrawIcon = true - } - image.src = window.canvasApp.urlPrefix + PATH + name + '.png' - thisObject.iconCollection.set(name, image) - } - } + container.isDraggeable = false - function physics () { - thisObject.workspace.physics() - } + thisObject.iconCollection = new Map() + thisObject.iconByUiObjectType = new Map() - function makeVisible () { - visible = true - } + return thisObject - function makeInvisible () { - visible = false - } + function initialize() { + loadIconCollection() + buildIconByUiObjectTypeMap() - function getContainer (point) { - let container - - if (thisObject.sidePanel !== undefined) { - container = thisObject.sidePanel.getContainer(point) - if (container !== undefined) { - container.space = 'Design Space' - return container - } + thisObject.workspace = newWorkspace() + thisObject.workspace.initialize() } - return - } + function buildIconByUiObjectTypeMap() { + /* Take types-icons relationships defined at the schema */ + for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { + let nodeDefinition = APP_SCHEMA_ARRAY[i] + let iconName = nodeDefinition.icon + if (iconName !== undefined) { + let icon = thisObject.iconCollection.get(iconName) + thisObject.iconByUiObjectType.set(nodeDefinition.type, icon) + } + } + } - function draw () { - if (canWeDraw === false) { return } - if (thisObject.sidePanel !== undefined) { - thisObject.sidePanel.draw() + function loadIconCollection() { + const iconsNames = [ + 'analysis', + 'analysis-1', + 'approve', + 'attach', + 'attractive', + 'pyramid', + 'brainstorming', + 'broken-link', + 'chat', + 'chronometer', + 'compass', + 'competition', + 'content', + 'design-tool', + 'grid', + 'headphones', + 'html', + 'image', + 'layout', + 'loading', + 'login', + 'pantone', + 'paper-plane', + 'photo-camera', + 'piggy-bank', + 'pipette', + 'pixel', + 'placeholder', + 'planning', + 'promotion', + 'pyramid', + 'quality', + 'responsive', + 'schedule', + 'search', + 'security', + 'settings', + 'sitemap', + 'startup', + 'support', + 'tap', + 'menu-fix-pinned', + 'menu-fix-unpinned', + 'targeting', + 'task', + 'testing', + 'text', + 'timeline', + 'tools', + 'delete', + 'upload', + 'vector', + 'video-player', + 'menu-mobility-freeze', + 'menu-mobility-unfreeze', + 'menu-tree-minus', + 'menu-tree-plus', + 'menu-backup', + 'menu-share', + 'stop', + 'stage-open', + 'stage-close', + 'stage-trigger', + 'stage-trigger-trigger-on', + 'stage-trigger-trigger-off', + 'stage-trigger-take-position', + 'menu-tensor-fixed-angles', + 'menu-tensor-free-angles', + 'stage-open-position-size', + 'stage-open-take-profit', + 'stage-open-postion-rate', + 'session-live-trading', + 'session-paper-trading', + 'session-backtesting', + 'session-forward-testing', + 'network', + 'network-node', + 'bot-trading', + 'layer-manager', + 'process', + 'bot-indicator', + 'bot-sensor', + 'time-period', + 'data-mine', + 'procedure-loop', + 'calculations-procedure', + 'data-building-procedure', + 'procedure-initialization', + 'process-definition', + 'output-dataset', + 'data-dependency', + 'product-definition', + 'plotter-module', + 'status-dependency', + 'record-property', + 'record-definition', + 'plotter', + 'plotter-panel', + 'dataset-definition', + 'status-report', + 'execution-finished-event', + 'process-dependencies', + 'process-output', + 'social-bot', + 'execution-started-event', + 'shapes', + 'chart-point', + 'style', + 'chart-points', + 'shapes-polygon-vertex', + 'shapes-polygon-border', + 'shapes-polygon-body', + 'chart-point-formula', + 'style-condition', + 'shapes-polygon', + 'data-entry', + 'data-formula', + 'clone', + 'exchange-account-asset', + 'exchange-account-key', + 'user-keys', + 'user-assets', + 'asset', + 'exchange-accounts', + 'user-account', + 'market', + 'exchange-assets', + 'crypto-exchanges', + 'crypto-exchange', + 'exchange-markets', + 'charting-space', + 'time-line-chart', + 'time-frame-scale', + 'time-scale', + 'rate-scale', + 'time-machine', + 'data-product', + 'single-market-data', + 'data-storage', + 'dataset', + 'viewport', + 'bitfinex', + 'binance', + 'kucoin', + 'bittrex', + 'kraken', + 'poloniex', + 'upbit', + 'monero', + 'tether', + 'tron', + 'stellar', + 'qtum', + 'neo', + 'litecoin', + 'ethereum-classic', + 'ethereum', + 'eos', + 'dash', + 'cardano', + 'bitcoin-cash', + 'bitcoin', + 'binance-coin', + 'trend', + 'oscillator', + 'moving-average', + 'histogram', + 'band', + 'volume', + 'candles', + 'bitmex', + 'liquid', + 'hitbtc', + 'us-dollar', + 'distance-to-parent-200', + 'distance-to-parent-150', + 'distance-to-parent-100', + 'distance-to-parent-050', + 'distance-to-parent-025', + 'distance-to-parent-000', + 'angle-to-parent-360', + 'angle-to-parent-180', + 'angle-to-parent-090', + 'angle-to-parent-045', + 'angle-to-parent-000', + 'data-mining', + 'initial-definition', + 'next-phase-event', + 'testing-environment', + 'production-environment', + 'task-manager', + 'session-based-data', + 'session-independent-data', + 'session-reference', + 'dashboard', + 'toggle-auto-scale-manual', + 'toggle-auto-scale-auto-min-max', + 'toggle-auto-scale-auto-max', + 'toggle-auto-scale-auto-min', + 'toggle-panel-off', + 'toggle-auto-time-scale-auto-min', + 'toggle-auto-time-scale-auto-max', + 'toggle-auto-time-scale-auto-min-max', + 'toggle-auto-time-scale-manual', + 'mouse-pointer', + 'mouse-left-click', + 'mouse-right-click', + 'mouse-wheel-up', + 'mouse-wheel-down', + 'mouse-wheel-click', + 'key-alt', + 'key-shift', + 'key-ctrl', + 'hand-drag', + 'key-down', + 'key-left', + 'key-right', + 'key-up', + 'master-script', + 'scripts-library', + 'super-action', + 'super-scripts', + 'template-script', + 'template-structure', + 'template-target', + 'delink', + 'detach', + 'help', + 'key-a', + 'key-m', + 'key-r', + 'arrangement-horizontal-top', + 'arrangement-convex', + 'arrangement-horizontal-bottom', + 'arrangement-vertical-right', + 'arrangement-vertical-left', + 'arrangement-concave', + 'move-to-phase-event', + 'open-execution', + 'move-order', + 'market-order', + 'limit-order', + 'execution-algorithm', + 'cancel-order' + ] + + for (let i = 0; i < iconsNames.length; i++) { + let name = iconsNames[i] + loadImage(name) + } + + function loadImage(name) { + const PATH = 'Images/Icons/style-01/' + let image = new Image() + image.onload = onImageLoad + image.fileName = name + + function onImageLoad() { + image.canDrawIcon = true + } + image.src = window.canvasApp.urlPrefix + PATH + name + '.png' + thisObject.iconCollection.set(name, image) + } } - if (thisObject.workspace !== undefined) { - thisObject.workspace.draw() + + function physics() { + thisObject.workspace.physics() + } + + function makeVisible() { + visible = true + } + + function makeInvisible() { + visible = false + } + + function getContainer(point) { + let container + + if (thisObject.sidePanel !== undefined) { + container = thisObject.sidePanel.getContainer(point) + if (container !== undefined) { + container.space = 'Design Space' + return container + } + } + + return + } + + function draw() { + if (canWeDraw === false) { return } + if (thisObject.sidePanel !== undefined) { + thisObject.sidePanel.draw() + } + if (thisObject.workspace !== undefined) { + thisObject.workspace.draw() + } } - } } diff --git a/Spaces/FloatingSpace.js b/Spaces/FloatingSpace.js index cb94ebc2d..90234b1a4 100644 --- a/Spaces/FloatingSpace.js +++ b/Spaces/FloatingSpace.js @@ -1,433 +1,433 @@ -function newFloatingSpace () { - const MODULE_NAME = 'Floating Space' - const ERROR_LOG = true - /* - The Floating Space is the place where floating elements like floatingObjects, live and are rendered. - This space has its own physics which helps with the animation of these objects and also preventing them to overlap. - */ +function newFloatingSpace() { + const MODULE_NAME = 'Floating Space' + const ERROR_LOG = true + /* + The Floating Space is the place where floating elements like floatingObjects, live and are rendered. + This space has its own physics which helps with the animation of these objects and also preventing them to overlap. + */ - let thisObject = { - floatingLayer: undefined, // This is the array of floatingObjects being displayed - uiObjectConstructor: undefined, - container: undefined, - inMapMode: false, - drawReferenceLines: false, - drawChainLines: true, - toggleDrawChainLines: toggleDrawChainLines, - toggleDrawReferenceLines: toggleDrawReferenceLines, - toggleMapMode: toggleMapMode, - enterMapMode: enterMapMode, - exitMapMode: exitMapMode, - transformPointToMap: transformPointToMap, - transformRadiusToMap: transformRadiusToMap, - transformImagesizeToMap: transformImagesizeToMap, - oneScreenUp: oneScreenUp, - oneScreenDown: oneScreenDown, - oneScreenLeft: oneScreenLeft, - oneScreenRight: oneScreenRight, - positionAtNode: positionAtNode, - fitIntoVisibleArea: fitIntoVisibleArea, - isThisPointVisible: isThisPointVisible, - isItFar: isItFar, - makeVisible: makeVisible, - makeInvisible: makeInvisible, - draw: draw, - physics: physics, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - thisObject.container.isClickeable = false - thisObject.container.isDraggeable = true - thisObject.container.isWheelable = true - thisObject.container.detectMouseOver = true - thisObject.container.isClickeable = false - thisObject.container.frame.radius = 0 - - let devicePixelRatio = window.devicePixelRatio - const SPACE_SIZE = 50000 - - thisObject.container.frame.width = SPACE_SIZE - thisObject.container.frame.height = SPACE_SIZE - thisObject.container.frame.position.x = browserCanvas.width / 2 - thisObject.container.frame.width / 2 - thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2 - - let visible = false - let floatingObjetOnFocus - - const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25 - let onDragStartedEventSubscriptionId - let spaceFocusAquiredEventSubscriptionId - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(onDragStartedEventSubscriptionId) - canvas.floatingSpace.container.eventHandler.stopListening(spaceFocusAquiredEventSubscriptionId) - - thisObject.floatingLayer.finalize() - thisObject.uiObjectConstructor.finalize() - thisObject.container.finalize() - - thisObject.floatingLayer = undefined - thisObject.uiObjectConstructor = undefined - thisObject.container = undefined - - floatingObjetOnFocus = undefined - } - - function initialize (callBackFunction) { - thisObject.floatingLayer = newFloatingLayer() - thisObject.floatingLayer.initialize() - - thisObject.uiObjectConstructor = newUiObjectConstructor() - thisObject.uiObjectConstructor.initialize(thisObject.floatingLayer) - - onDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted) - spaceFocusAquiredEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus) - } - - function someoneAquiredFocus (floatingObject) { - if (floatingObject === undefined || floatingObject.container === undefined) { - return + let thisObject = { + floatingLayer: undefined, // This is the array of floatingObjects being displayed + uiObjectConstructor: undefined, + container: undefined, + inMapMode: false, + drawReferenceLines: false, + drawChainLines: true, + toggleDrawChainLines: toggleDrawChainLines, + toggleDrawReferenceLines: toggleDrawReferenceLines, + toggleMapMode: toggleMapMode, + enterMapMode: enterMapMode, + exitMapMode: exitMapMode, + transformPointToMap: transformPointToMap, + transformRadiusToMap: transformRadiusToMap, + transformImagesizeToMap: transformImagesizeToMap, + oneScreenUp: oneScreenUp, + oneScreenDown: oneScreenDown, + oneScreenLeft: oneScreenLeft, + oneScreenRight: oneScreenRight, + positionAtNode: positionAtNode, + fitIntoVisibleArea: fitIntoVisibleArea, + isThisPointVisible: isThisPointVisible, + isItFar: isItFar, + makeVisible: makeVisible, + makeInvisible: makeInvisible, + draw: draw, + physics: physics, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - floatingObjetOnFocus = floatingObject - } - function toggleDrawReferenceLines () { - if (thisObject.drawReferenceLines === true) { - thisObject.drawReferenceLines = false - } else { - thisObject.drawReferenceLines = true + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) + thisObject.container.isClickeable = false + thisObject.container.isDraggeable = true + thisObject.container.isWheelable = true + thisObject.container.detectMouseOver = true + thisObject.container.isClickeable = false + thisObject.container.frame.radius = 0 + + let devicePixelRatio = window.devicePixelRatio + const SPACE_SIZE = 50000 + + thisObject.container.frame.width = SPACE_SIZE + thisObject.container.frame.height = SPACE_SIZE + thisObject.container.frame.position.x = browserCanvas.width / 2 - thisObject.container.frame.width / 2 + thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2 + + let visible = false + let floatingObjetOnFocus + + const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25 + let onDragStartedEventSubscriptionId + let spaceFocusAquiredEventSubscriptionId + + return thisObject + + function finalize() { + thisObject.container.eventHandler.stopListening(onDragStartedEventSubscriptionId) + canvas.floatingSpace.container.eventHandler.stopListening(spaceFocusAquiredEventSubscriptionId) + + thisObject.floatingLayer.finalize() + thisObject.uiObjectConstructor.finalize() + thisObject.container.finalize() + + thisObject.floatingLayer = undefined + thisObject.uiObjectConstructor = undefined + thisObject.container = undefined + + floatingObjetOnFocus = undefined } - } - function toggleDrawChainLines () { - if (thisObject.drawChainLines === true) { - thisObject.drawChainLines = false - } else { - thisObject.drawChainLines = true + function initialize(callBackFunction) { + thisObject.floatingLayer = newFloatingLayer() + thisObject.floatingLayer.initialize() + + thisObject.uiObjectConstructor = newUiObjectConstructor() + thisObject.uiObjectConstructor.initialize(thisObject.floatingLayer) + + onDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted) + spaceFocusAquiredEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus) } - } - function transformPointToMap (point) { - let returnPoint = { - x: point.x - thisObject.container.frame.position.x, - y: point.y - thisObject.container.frame.position.y - } - returnPoint.x = returnPoint.x / SPACE_SIZE * browserCanvas.width - returnPoint.y = returnPoint.y / SPACE_SIZE * browserCanvas.height - return returnPoint - } - - function transformRadiusToMap (radius) { - const RADIUS_REDUCTION_FACTOR = 2 - return radius / RADIUS_REDUCTION_FACTOR - } - - function transformImagesizeToMap (imageSize) { - const IMAGE_REDUCTION_FACTOR = 3 - return imageSize / IMAGE_REDUCTION_FACTOR - } - - function enterMapMode () { - thisObject.inMapMode = true - } - - function exitMapMode () { - thisObject.inMapMode = false - } - - function toggleMapMode () { - if (thisObject.inMapMode === false) { - enterMapMode() - } else { - exitMapMode() - } - } - - function onDragStarted (event) { - if (thisObject.inMapMode === false) { - if (event.buttons !== 2) { return } - event.candelDragging = true - enterMapMode() - } else { - if (event.buttons !== 1) { - event.candelDragging = true - return - } - - let mousePosition = { - x: event.x, - y: event.y - } - - let mouseAtSpace = { - x: mousePosition.x / browserCanvas.width * SPACE_SIZE, - y: mousePosition.y / browserCanvas.height * SPACE_SIZE - } - /* Let's see if we can snap to some of the root nodes that are isHierarchyHead */ - let snapCandidateNodes = canvas.designSpace.workspace.getHierarchyHeads() - for (let i = 0; i < snapCandidateNodes.length; i++) { - let node = snapCandidateNodes[i] - let nodePosition = { - x: node.payload.floatingObject.container.frame.position.x, - y: node.payload.floatingObject.container.frame.position.y + function someoneAquiredFocus(floatingObject) { + if (floatingObject === undefined || floatingObject.container === undefined) { + return } - // nodePosition = node.payload.floatingObject.container.frame.frameThisPoint(nodePosition) + floatingObjetOnFocus = floatingObject + } - let distance = Math.sqrt(Math.pow(mouseAtSpace.x - nodePosition.x, 2) + Math.pow(mouseAtSpace.y - nodePosition.y, 2)) - const SNAP_THREASHOLD = 1000 - if (distance < SNAP_THREASHOLD) { - mousePosition.x = nodePosition.x / SPACE_SIZE * browserCanvas.width - mousePosition.y = nodePosition.y / SPACE_SIZE * browserCanvas.height + function toggleDrawReferenceLines() { + if (thisObject.drawReferenceLines === true) { + thisObject.drawReferenceLines = false + } else { + thisObject.drawReferenceLines = true } - } - - /* Movign the Floating Space to where the mouse is. */ - thisObject.container.frame.position.x = -mousePosition.x / browserCanvas.width * SPACE_SIZE + browserCanvas.width / 2 - thisObject.container.frame.position.y = -mousePosition.y / browserCanvas.height * SPACE_SIZE + browserCanvas.height / 2 - - exitMapMode() - } - } - - function isItFar (payload, dontCheckParent) { - /* If for any reason the paylaod is undefined we return false */ - if (payload === undefined) { return false } - if (thisObject.inMapMode === true) { return false } - - let radarFactor = 2 // How big is the margin - - /* If the chain parent is not far, they we dont consither this far. */ - if (dontCheckParent !== true) { - if (payload.chainParent !== undefined) { - if (isItFar(payload.chainParent.payload, true) === false) { return false } - } } - /* Exceptions that are never considered far. */ - if ( - payload.node.type === 'Trading System' || - payload.node.type === 'Network' || - payload.node.type === 'Crypto Ecosystem' || - payload.node.type === 'Charting Space' || - payload.node.type === 'Data Mine' || - payload.node.type === 'Super Scripts' - ) { - return false + function toggleDrawChainLines() { + if (thisObject.drawChainLines === true) { + thisObject.drawChainLines = false + } else { + thisObject.drawChainLines = true + } } - /* Another exception are the ones who have reference parents */ - if (payload.referenceParent !== undefined) { return false } - - /* Here we will check the position of a floatingobject to see if it is outside the screen, with a margin of one screen around. */ - let point = thisObject.container.frame.frameThisPoint(payload.position) - - if (point.x > browserCanvas.width + browserCanvas.width * radarFactor) { - return true + function transformPointToMap(point) { + let returnPoint = { + x: point.x - thisObject.container.frame.position.x, + y: point.y - thisObject.container.frame.position.y + } + returnPoint.x = returnPoint.x / SPACE_SIZE * browserCanvas.width + returnPoint.y = returnPoint.y / SPACE_SIZE * browserCanvas.height + return returnPoint } - if (point.x < 0 - browserCanvas.width * radarFactor) { - return true + function transformRadiusToMap(radius) { + const RADIUS_REDUCTION_FACTOR = 2 + return radius / RADIUS_REDUCTION_FACTOR } - let bottom = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT - let heightDiff = browserCanvas.height - bottom - if (point.y < bottom - heightDiff * radarFactor) { - return true + function transformImagesizeToMap(imageSize) { + const IMAGE_REDUCTION_FACTOR = 3 + return imageSize / IMAGE_REDUCTION_FACTOR } - if (point.y > browserCanvas.height + heightDiff * radarFactor) { - return true - } - return false - } - - function fitIntoVisibleArea (point) { - /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ - - let returnPoint = { - x: point.x, - y: point.y + function enterMapMode() { + thisObject.inMapMode = true } - if (point.x > browserCanvas.width) { - returnPoint.x = browserCanvas.width + function exitMapMode() { + thisObject.inMapMode = false } - if (point.x < 0) { - returnPoint.x = 0 + function toggleMapMode() { + if (thisObject.inMapMode === false) { + enterMapMode() + } else { + exitMapMode() + } } - if (point.y < COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) { - returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT + function onDragStarted(event) { + if (thisObject.inMapMode === false) { + if (event.buttons !== 2) { return } + event.candelDragging = true + enterMapMode() + } else { + if (event.buttons !== 1) { + event.candelDragging = true + return + } + + let mousePosition = { + x: event.x, + y: event.y + } + + let mouseAtSpace = { + x: mousePosition.x / browserCanvas.width * SPACE_SIZE, + y: mousePosition.y / browserCanvas.height * SPACE_SIZE + } + /* Let's see if we can snap to some of the root nodes that are isHierarchyHead */ + let snapCandidateNodes = canvas.designSpace.workspace.getHierarchyHeads() + for (let i = 0; i < snapCandidateNodes.length; i++) { + let node = snapCandidateNodes[i] + let nodePosition = { + x: node.payload.floatingObject.container.frame.position.x, + y: node.payload.floatingObject.container.frame.position.y + } + // nodePosition = node.payload.floatingObject.container.frame.frameThisPoint(nodePosition) + + let distance = Math.sqrt(Math.pow(mouseAtSpace.x - nodePosition.x, 2) + Math.pow(mouseAtSpace.y - nodePosition.y, 2)) + const SNAP_THREASHOLD = 1000 + if (distance < SNAP_THREASHOLD) { + mousePosition.x = nodePosition.x / SPACE_SIZE * browserCanvas.width + mousePosition.y = nodePosition.y / SPACE_SIZE * browserCanvas.height + } + } + + /* Movign the Floating Space to where the mouse is. */ + thisObject.container.frame.position.x = -mousePosition.x / browserCanvas.width * SPACE_SIZE + browserCanvas.width / 2 + thisObject.container.frame.position.y = -mousePosition.y / browserCanvas.height * SPACE_SIZE + browserCanvas.height / 2 + + exitMapMode() + } } - if (point.y > browserCanvas.height) { - returnPoint.y = browserCanvas.height + function isItFar(payload, dontCheckParent) { + /* If for any reason the paylaod is undefined we return false */ + if (payload === undefined) { return false } + if (thisObject.inMapMode === true) { return false } + + let radarFactor = 2 // How big is the margin + + /* If the chain parent is not far, they we dont consither this far. */ + if (dontCheckParent !== true) { + if (payload.chainParent !== undefined) { + if (isItFar(payload.chainParent.payload, true) === false) { return false } + } + } + + /* Exceptions that are never considered far. */ + if ( + payload.node.type === 'Trading System' || + payload.node.type === 'Network' || + payload.node.type === 'Crypto Ecosystem' || + payload.node.type === 'Charting Space' || + payload.node.type === 'Data Mine' || + payload.node.type === 'Super Scripts' + ) { + return false + } + + /* Another exception are the ones who have reference parents */ + if (payload.referenceParent !== undefined) { return false } + + /* Here we will check the position of a floatingobject to see if it is outside the screen, with a margin of one screen around. */ + let point = thisObject.container.frame.frameThisPoint(payload.position) + + if (point.x > browserCanvas.width + browserCanvas.width * radarFactor) { + return true + } + + if (point.x < 0 - browserCanvas.width * radarFactor) { + return true + } + + let bottom = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT + let heightDiff = browserCanvas.height - bottom + if (point.y < bottom - heightDiff * radarFactor) { + return true + } + + if (point.y > browserCanvas.height + heightDiff * radarFactor) { + return true + } + return false } - return returnPoint - } + function fitIntoVisibleArea(point) { + /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ - function oneScreenUp () { - if (visible === false) { return } - let displaceVector = { - x: 0, - y: browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 + let returnPoint = { + x: point.x, + y: point.y + } + + if (point.x > browserCanvas.width) { + returnPoint.x = browserCanvas.width + } + + if (point.x < 0) { + returnPoint.x = 0 + } + + if (point.y < COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) { + returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT + } + + if (point.y > browserCanvas.height) { + returnPoint.y = browserCanvas.height + } + + return returnPoint } - thisObject.container.displace(displaceVector) - return displaceVector - } + function oneScreenUp() { + if (visible === false) { return } + let displaceVector = { + x: 0, + y: browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 + } - function oneScreenDown () { - if (visible === false) { return } - let displaceVector = { - x: 0, - y: -browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 + thisObject.container.displace(displaceVector) + return displaceVector } - thisObject.container.displace(displaceVector) - return displaceVector - } + function oneScreenDown() { + if (visible === false) { return } + let displaceVector = { + x: 0, + y: -browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100 + } - function oneScreenLeft () { - if (visible === false) { return } - let displaceVector = { - x: browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, - y: 0 + thisObject.container.displace(displaceVector) + return displaceVector } - thisObject.container.displace(displaceVector) - return displaceVector - } + function oneScreenLeft() { + if (visible === false) { return } + let displaceVector = { + x: browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, + y: 0 + } - function oneScreenRight () { - if (visible === false) { return } - let displaceVector = { - x: -browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, - y: 0 + thisObject.container.displace(displaceVector) + return displaceVector } - thisObject.container.displace(displaceVector) - return displaceVector - } + function oneScreenRight() { + if (visible === false) { return } + let displaceVector = { + x: -browserCanvas.width * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100, + y: 0 + } - function positionAtNode (node) { - let position = thisObject.container.frame.frameThisPoint(node.payload.position) - - let displaceVector = { - x: browserCanvas.width / 2 - position.x, - y: (COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) + (browserCanvas.height - (COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT)) / 2 - position.y + thisObject.container.displace(displaceVector) + return displaceVector } - thisObject.container.displace(displaceVector) - } + function positionAtNode(node) { + let position = thisObject.container.frame.frameThisPoint(node.payload.position) - function isThisPointVisible (point) { - if (point.x > browserCanvas.width) { - return false + let displaceVector = { + x: browserCanvas.width / 2 - position.x, + y: (COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) + (browserCanvas.height - (COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT)) / 2 - position.y + } + + thisObject.container.displace(displaceVector) } - if (point.x < 0) { - return false + function isThisPointVisible(point) { + if (point.x > browserCanvas.width) { + return false + } + + if (point.x < 0) { + return false + } + + if (point.y < COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) { + return false + } + + if (point.y > browserCanvas.height) { + return false + } + + return true } - if (point.y < COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) { - return false + function makeVisible() { + visible = true } - if (point.y > browserCanvas.height) { - return false + function makeInvisible() { + visible = false } - return true - } + function getContainer(point) { + if (visible === false) { return } - function makeVisible () { - visible = true - } + let container - function makeInvisible () { - visible = false - } + if (floatingObjetOnFocus !== undefined) { + container = floatingObjetOnFocus.getContainer(point) + if (container !== undefined) { + container.space = 'Floating Space' + return container + } + } - function getContainer (point) { - if (visible === false) { return } + container = thisObject.floatingLayer.getContainer(point) + if (container !== undefined) { + container.space = 'Floating Space' + return container + } - let container - - if (floatingObjetOnFocus !== undefined) { - container = floatingObjetOnFocus.getContainer(point) - if (container !== undefined) { - container.space = 'Floating Space' - return container - } + if (visible === true) { + thisObject.container.space = 'Floating Space' + return thisObject.container + } } - container = thisObject.floatingLayer.getContainer(point) - if (container !== undefined) { - container.space = 'Floating Space' - return container + function physics() { + if (visible === false) { return } + browserZoomPhysics() + positionContraintsPhysics() + thisObject.floatingLayer.physics() } - if (visible === true) { - thisObject.container.space = 'Floating Space' - return thisObject.container + function positionContraintsPhysics() { + if (thisObject.container.frame.position.x > 0) { + thisObject.container.frame.position.x = 0 + } + if (thisObject.container.frame.position.y > 0) { + thisObject.container.frame.position.y = 0 + } + if (thisObject.container.frame.position.x + thisObject.container.frame.width < browserCanvas.width) { + thisObject.container.frame.position.x = browserCanvas.width - thisObject.container.frame.width + } + if (thisObject.container.frame.position.y + thisObject.container.frame.height < browserCanvas.height) { + thisObject.container.frame.position.y = browserCanvas.height - thisObject.container.frame.height + } } - } - function physics () { - if (visible === false) { return } - browserZoomPhysics() - positionContraintsPhysics() - thisObject.floatingLayer.physics() - } + function browserZoomPhysics() { + if (devicePixelRatio !== window.devicePixelRatio) { + devicePixelRatio = window.devicePixelRatio - function positionContraintsPhysics () { - if (thisObject.container.frame.position.x > 0) { - thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.x = browserCanvas.width / 2 - thisObject.container.frame.width / 2 + thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2 + } } - if (thisObject.container.frame.position.y > 0) { - thisObject.container.frame.position.y = 0 + + function draw() { + if (canWeDraw === false) { return } + if (visible === false) { return } + drawBackground() + thisObject.floatingLayer.draw() } - if (thisObject.container.frame.position.x + thisObject.container.frame.width < browserCanvas.width) { - thisObject.container.frame.position.x = browserCanvas.width - thisObject.container.frame.width + + function drawBackground() { + browserCanvasContext.beginPath() + + browserCanvasContext.rect(thisObject.container.frame.position.x, thisObject.container.frame.position.y, thisObject.container.frame.width, thisObject.container.frame.height) + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 1)' + + browserCanvasContext.closePath() + browserCanvasContext.fill() } - if (thisObject.container.frame.position.y + thisObject.container.frame.height < browserCanvas.height) { - thisObject.container.frame.position.y = browserCanvas.height - thisObject.container.frame.height - } - } - - function browserZoomPhysics () { - if (devicePixelRatio !== window.devicePixelRatio) { - devicePixelRatio = window.devicePixelRatio - - thisObject.container.frame.position.x = browserCanvas.width / 2 - thisObject.container.frame.width / 2 - thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2 - } - } - - function draw () { - if (canWeDraw === false) { return } - if (visible === false) { return } - drawBackground() - thisObject.floatingLayer.draw() - } - - function drawBackground () { - browserCanvasContext.beginPath() - - browserCanvasContext.rect(thisObject.container.frame.position.x, thisObject.container.frame.position.y, thisObject.container.frame.width, thisObject.container.frame.height) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 1)' - - browserCanvasContext.closePath() - browserCanvasContext.fill() - } } diff --git a/Spaces/PanelsSpace.js b/Spaces/PanelsSpace.js index a634fa26e..ecfcfdfa6 100644 --- a/Spaces/PanelsSpace.js +++ b/Spaces/PanelsSpace.js @@ -1,379 +1,379 @@ - /* +/* The Panel Space y the place wehre all panels live, no matter who create them. */ -function newPanelsSpace () { - let thisObject = { - visible: true, - container: undefined, - unHide: unHide, - hide: hide, - createNewPanel: createNewPanel, - destroyPanel: destroyPanel, - getPanel: getPanel, - physics: physics, - draw: draw, - panels: [], - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize - } +function newPanelsSpace() { + let thisObject = { + visible: true, + container: undefined, + unHide: unHide, + hide: hide, + createNewPanel: createNewPanel, + destroyPanel: destroyPanel, + getPanel: getPanel, + physics: physics, + draw: draw, + panels: [], + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize + } - let container = newContainer() - container.initialize() - thisObject.container = container - thisObject.container.isDraggeable = false + let container = newContainer() + container.initialize() + thisObject.container = container + thisObject.container.isDraggeable = false - container.frame.containerName = 'Panels Space' + container.frame.containerName = 'Panels Space' - return thisObject + return thisObject - function initialize () { + function initialize() { /* The space does not create any Panels for itself, it just sits and waits others need panels. */ - } - - function createNewPanel (pType, pParameters, pOwner, pSession) { - let panel - - switch (pType) { - - case 'Layers Panel': - { - panel = newLayersPanel() - panel.fitFunction = canvas.chartingSpace.fitFunction - panel.container.isVisibleFunction = canvas.chartingSpace.isThisPointVisible - panel.type = 'Layers Panel' - break - } - case 'Plotter Panel': - { - if (pParameters.panelNode.config.isLegacy !== true) { - panel = newPlotterPanel() - panel.fitFunction = canvas.chartingSpace.fitFunction - panel.container.isVisibleFunction = canvas.chartingSpace.isThisPointVisible - panel.session = pSession - panel.initialize(pParameters.panelNode) - } else { - panel = getNewPlotterPanel(pParameters.dataMine, pParameters.plotterCodeName, pParameters.moduleCodeName, pParameters.panelNode.config.codeName) - panel.fitFunction = canvas.chartingSpace.fitFunction - panel.container.isVisibleFunction = canvas.chartingSpace.isThisPointVisible - panel.session = pSession - panel.initialize() - } - panel.type = 'Plotter Panel' - break - } } - panel.owner = pOwner - thisObject.panels.push(panel) + function createNewPanel(pType, pParameters, pOwner, pSession) { + let panel - panel.handle = newUniqueId() + switch (pType) { - return panel.handle - } - - function unHide (owner, type) { - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - if (panel.owner === owner && panel.type === type) { - panel.isHidden = false - } - } - } - - function hide (owner, type) { - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - if (panel.owner === owner && panel.type === type) { - panel.isHidden = true - } - } - } - - function destroyPanel (pPanelHandle) { - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - - if (panel.handle === pPanelHandle) { - if (panel.finalize !== undefined) { - panel.finalize() + case 'Layers Panel': + { + panel = newLayersPanel() + panel.fitFunction = canvas.chartingSpace.fitFunction + panel.container.isVisibleFunction = canvas.chartingSpace.isThisPointVisible + panel.type = 'Layers Panel' + break + } + case 'Plotter Panel': + { + if (pParameters.panelNode.config.isLegacy !== true) { + panel = newPlotterPanel() + panel.fitFunction = canvas.chartingSpace.fitFunction + panel.container.isVisibleFunction = canvas.chartingSpace.isThisPointVisible + panel.session = pSession + panel.initialize(pParameters.panelNode) + } else { + panel = getNewPlotterPanel(pParameters.dataMine, pParameters.plotterCodeName, pParameters.moduleCodeName, pParameters.panelNode.config.codeName) + panel.fitFunction = canvas.chartingSpace.fitFunction + panel.container.isVisibleFunction = canvas.chartingSpace.isThisPointVisible + panel.session = pSession + panel.initialize() + } + panel.type = 'Plotter Panel' + break + } } - thisObject.panels.splice(i, 1) // Delete item from array. - return - } + panel.owner = pOwner + thisObject.panels.push(panel) + + panel.handle = newUniqueId() + + return panel.handle } - } - function getPanel (pPanelHandle) { - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - - if (panel.handle === pPanelHandle) { - return panel - } - } - } - - function physics () { - if (thisObject.visible !== true) { return } - - childrenPhysics() - positioningPhysics() - } - - function childrenPhysics () { - if (thisObject.panels !== undefined) { - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - let owner = canvas.chartingSpace.inViewport.get(panel.owner) - if (owner !== undefined) { - if (panel.physics !== undefined) { - panel.physics() - } - } - } - } - } - - function positioningPhysics () { - if (thisObject.panels !== undefined) { - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - if (panel.isVisible === false || panel.isHidden === true) { continue } - /* setting the speed of the panel */ - if (panel.container.speed === undefined) { - panel.container.speed = { - x: 2, - y: 2 - } - } - - /* Trying to move the panel and see if it is possible */ - let centerPoint = { - x: panel.container.frame.position.x, - y: panel.container.frame.position.y - } - centerPoint.x = centerPoint.x + panel.container.frame.width / 2 - centerPoint.y = centerPoint.y + panel.container.frame.height / 2 - - /* Lets see which quadrant the panel is at */ - let verticalLine = (canvas.chartingSpace.viewport.visibleArea.topRight.x - canvas.chartingSpace.viewport.visibleArea.topLeft.x) / 2 + canvas.chartingSpace.viewport.visibleArea.topLeft.x - let horizontalLine = (canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topRight.y) / 2 + canvas.chartingSpace.viewport.visibleArea.topRight.y - - if (panel.upDownButton !== undefined) { - if (panel.upDownButton.status === 'up') { - if (panel.leftRightButton !== undefined) { - if (panel.leftRightButton.status === 'left') { - panel.gravitatesTowards = 'topLeft' - } else { - panel.gravitatesTowards = 'topRight' - } - } else { - if (centerPoint.x < verticalLine) { - panel.gravitatesTowards = 'topLeft' - } else { - panel.gravitatesTowards = 'topRight' - } + function unHide(owner, type) { + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] + if (panel.owner === owner && panel.type === type) { + panel.isHidden = false } - } else { - if (panel.leftRightButton !== undefined) { - if (panel.leftRightButton.status === 'left') { - panel.gravitatesTowards = 'bottomLeft' - } else { - panel.gravitatesTowards = 'bottomRight' - } - } else { - if (centerPoint.x < verticalLine) { - panel.gravitatesTowards = 'bottomLeft' - } else { - panel.gravitatesTowards = 'bottomRight' - } - } - } - } else { - if (centerPoint.x < verticalLine && centerPoint.y < horizontalLine) { - panel.gravitatesTowards = 'topLeft' - } - if (centerPoint.x >= verticalLine && centerPoint.y < horizontalLine) { - panel.gravitatesTowards = 'topRight' - } - if (centerPoint.x < verticalLine && centerPoint.y >= horizontalLine) { - panel.gravitatesTowards = 'bottomLeft' - } - if (centerPoint.x >= verticalLine && centerPoint.y >= horizontalLine) { - panel.gravitatesTowards = 'bottomRight' - } } - - /* According to the quadrant we push the panels to the sides */ - if (panel.gravitatesTowards === 'topLeft' || panel.gravitatesTowards === 'bottomLeft') { - panel.container.frame.position.x = panel.container.frame.position.x - panel.container.speed.x - if (panel.leftRightButton !== undefined) { - if (panel.leftRightButton.status === 'left' || panel.leftRightButton.status === 'right') { // we avoid pushing other panels while in transition - } - } - isOverlapping(i, panel.container) - if (panel.container.frame.position.x < 0) { - panel.container.frame.position.x = 0 - } - } else { - panel.container.frame.position.x = panel.container.frame.position.x + panel.container.speed.x - isOverlapping(i, panel.container) - if (panel.container.frame.position.x + panel.container.frame.width > browserCanvas.width) { - panel.container.frame.position.x = browserCanvas.width - panel.container.frame.width - } - } - if (panel.container.frame.height <= canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topRight.y) { - if (panel.gravitatesTowards === 'topLeft' || panel.gravitatesTowards === 'topRight') { - panel.container.frame.position.y = panel.container.frame.position.y - panel.container.speed.y - isOverlapping(i, panel.container) - if (panel.container.frame.position.y < canvas.chartingSpace.viewport.visibleArea.topLeft.y) { - panel.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.topLeft.y - } - } else { - panel.container.frame.position.y = panel.container.frame.position.y + panel.container.speed.y - isOverlapping(i, panel.container) - if (panel.container.frame.position.y + panel.container.frame.height > canvas.chartingSpace.viewport.visibleArea.bottomRight.y) { - panel.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y - panel.container.frame.height - } - } - } - } } - function isOverlapping (currentIndex, currentContainer) { - let corner1 = { - x: currentContainer.frame.position.x, - y: currentContainer.frame.position.y - } - let corner2 = { - x: currentContainer.frame.position.x + currentContainer.frame.width, - y: currentContainer.frame.position.y - } - let corner3 = { - x: currentContainer.frame.position.x + currentContainer.frame.width, - y: currentContainer.frame.position.y + currentContainer.frame.height - } - let corner4 = { - x: currentContainer.frame.position.x, - y: currentContainer.frame.position.y + currentContainer.frame.height - } - - for (let i = 0; i < currentIndex; i++) { - let panel = thisObject.panels[i] - if (panel.leftRightButton !== undefined) { - if (panel.leftRightButton.status !== 'left' && panel.leftRightButton.status !== 'right') { // we avoid pushing other panels while in transition - continue - } + function hide(owner, type) { + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] + if (panel.owner === owner && panel.type === type) { + panel.isHidden = true + } } - if (panel.isVisible === true && panel.isHidden === false) { - if (isThisPointInsideThisFrame(corner1, panel.container.frame) === true) { - pushOut(currentContainer, panel.container, panel.gravitatesTowards) - } - if (isThisPointInsideThisFrame(corner2, panel.container.frame) === true) { - pushOut(currentContainer, panel.container, panel.gravitatesTowards) - } - if (isThisPointInsideThisFrame(corner3, panel.container.frame) === true) { - pushOut(currentContainer, panel.container, panel.gravitatesTowards) - } - if (isThisPointInsideThisFrame(corner4, panel.container.frame) === true) { - pushOut(currentContainer, panel.container, panel.gravitatesTowards) - } - } - } - - function pushOut (currentContainer, controlContainer, corner) { - switch (corner) { - case 'topLeft': { - currentContainer.frame.position.x = controlContainer.frame.position.x + controlContainer.frame.width - break - } - case 'topRight': { - currentContainer.frame.position.x = controlContainer.frame.position.x - currentContainer.frame.width - break - } - case 'bottomLeft': { - currentContainer.frame.position.x = controlContainer.frame.position.x + controlContainer.frame.width - break - } - case 'bottomRight': { - currentContainer.frame.position.x = controlContainer.frame.position.x - currentContainer.frame.width - break - } - } - } - - function isThisPointInsideThisFrame (point, frame) { - let corner1 = { - x: frame.position.x, - y: frame.position.y - } - let corner2 = { - x: frame.position.x + frame.width, - y: frame.position.y - } - let corner3 = { - x: frame.position.x + frame.width, - y: frame.position.y + frame.height - } - let corner4 = { - x: frame.position.x, - y: frame.position.y + frame.height - } - if (point.x >= corner1.x && point.y >= corner1.y && point.x <= corner3.x && point.y <= corner3.y) { - return true - } else { - return false - } - } - return false } - } - function draw () { - if (canWeDraw === false) { return } - if (thisObject.visible !== true) { return } + function destroyPanel(pPanelHandle) { + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] - thisObject.container.frame.draw(false, false) + if (panel.handle === pPanelHandle) { + if (panel.finalize !== undefined) { + panel.finalize() + } - for (let i = 0; i < thisObject.panels.length; i++) { - let panel = thisObject.panels[i] - let owner = canvas.chartingSpace.inViewport.get(panel.owner) - if (owner !== undefined) { - if (panel.isVisible === true && panel.isHidden === false) { - panel.draw() + thisObject.panels.splice(i, 1) // Delete item from array. + return + } } - } } - } - function getContainer (point, purpose) { - if (thisObject.visible !== true) { return } + function getPanel(pPanelHandle) { + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] - let container - /* - We search for the container of panels in the oposite direction than we do it for drawing them, - so panels overlapping others are picked firt although they are drawn last. - */ - for (let i = thisObject.panels.length - 1; i >= 0; i--) { - let panel = thisObject.panels[i] - let owner = canvas.chartingSpace.inViewport.get(panel.owner) - if (owner !== undefined) { - if (panel.isVisible === true && panel.isHidden === false) { - container = panel.getContainer(point, purpose) + if (panel.handle === pPanelHandle) { + return panel + } } - } - if (container !== undefined) { - container.space = 'Panels Space' - return container - } } - // thisObject.container.space = 'Panels Space' - // return thisObject.container - } + + function physics() { + if (thisObject.visible !== true) { return } + + childrenPhysics() + positioningPhysics() + } + + function childrenPhysics() { + if (thisObject.panels !== undefined) { + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] + let owner = canvas.chartingSpace.inViewport.get(panel.owner) + if (owner !== undefined) { + if (panel.physics !== undefined) { + panel.physics() + } + } + } + } + } + + function positioningPhysics() { + if (thisObject.panels !== undefined) { + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] + if (panel.isVisible === false || panel.isHidden === true) { continue } + /* setting the speed of the panel */ + if (panel.container.speed === undefined) { + panel.container.speed = { + x: 2, + y: 2 + } + } + + /* Trying to move the panel and see if it is possible */ + let centerPoint = { + x: panel.container.frame.position.x, + y: panel.container.frame.position.y + } + centerPoint.x = centerPoint.x + panel.container.frame.width / 2 + centerPoint.y = centerPoint.y + panel.container.frame.height / 2 + + /* Lets see which quadrant the panel is at */ + let verticalLine = (canvas.chartingSpace.viewport.visibleArea.topRight.x - canvas.chartingSpace.viewport.visibleArea.topLeft.x) / 2 + canvas.chartingSpace.viewport.visibleArea.topLeft.x + let horizontalLine = (canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topRight.y) / 2 + canvas.chartingSpace.viewport.visibleArea.topRight.y + + if (panel.upDownButton !== undefined) { + if (panel.upDownButton.status === 'up') { + if (panel.leftRightButton !== undefined) { + if (panel.leftRightButton.status === 'left') { + panel.gravitatesTowards = 'topLeft' + } else { + panel.gravitatesTowards = 'topRight' + } + } else { + if (centerPoint.x < verticalLine) { + panel.gravitatesTowards = 'topLeft' + } else { + panel.gravitatesTowards = 'topRight' + } + } + } else { + if (panel.leftRightButton !== undefined) { + if (panel.leftRightButton.status === 'left') { + panel.gravitatesTowards = 'bottomLeft' + } else { + panel.gravitatesTowards = 'bottomRight' + } + } else { + if (centerPoint.x < verticalLine) { + panel.gravitatesTowards = 'bottomLeft' + } else { + panel.gravitatesTowards = 'bottomRight' + } + } + } + } else { + if (centerPoint.x < verticalLine && centerPoint.y < horizontalLine) { + panel.gravitatesTowards = 'topLeft' + } + if (centerPoint.x >= verticalLine && centerPoint.y < horizontalLine) { + panel.gravitatesTowards = 'topRight' + } + if (centerPoint.x < verticalLine && centerPoint.y >= horizontalLine) { + panel.gravitatesTowards = 'bottomLeft' + } + if (centerPoint.x >= verticalLine && centerPoint.y >= horizontalLine) { + panel.gravitatesTowards = 'bottomRight' + } + } + + /* According to the quadrant we push the panels to the sides */ + if (panel.gravitatesTowards === 'topLeft' || panel.gravitatesTowards === 'bottomLeft') { + panel.container.frame.position.x = panel.container.frame.position.x - panel.container.speed.x + if (panel.leftRightButton !== undefined) { + if (panel.leftRightButton.status === 'left' || panel.leftRightButton.status === 'right') { // we avoid pushing other panels while in transition + } + } + isOverlapping(i, panel.container) + if (panel.container.frame.position.x < 0) { + panel.container.frame.position.x = 0 + } + } else { + panel.container.frame.position.x = panel.container.frame.position.x + panel.container.speed.x + isOverlapping(i, panel.container) + if (panel.container.frame.position.x + panel.container.frame.width > browserCanvas.width) { + panel.container.frame.position.x = browserCanvas.width - panel.container.frame.width + } + } + if (panel.container.frame.height <= canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topRight.y) { + if (panel.gravitatesTowards === 'topLeft' || panel.gravitatesTowards === 'topRight') { + panel.container.frame.position.y = panel.container.frame.position.y - panel.container.speed.y + isOverlapping(i, panel.container) + if (panel.container.frame.position.y < canvas.chartingSpace.viewport.visibleArea.topLeft.y) { + panel.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.topLeft.y + } + } else { + panel.container.frame.position.y = panel.container.frame.position.y + panel.container.speed.y + isOverlapping(i, panel.container) + if (panel.container.frame.position.y + panel.container.frame.height > canvas.chartingSpace.viewport.visibleArea.bottomRight.y) { + panel.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.bottomRight.y - panel.container.frame.height + } + } + } + } + } + + function isOverlapping(currentIndex, currentContainer) { + let corner1 = { + x: currentContainer.frame.position.x, + y: currentContainer.frame.position.y + } + let corner2 = { + x: currentContainer.frame.position.x + currentContainer.frame.width, + y: currentContainer.frame.position.y + } + let corner3 = { + x: currentContainer.frame.position.x + currentContainer.frame.width, + y: currentContainer.frame.position.y + currentContainer.frame.height + } + let corner4 = { + x: currentContainer.frame.position.x, + y: currentContainer.frame.position.y + currentContainer.frame.height + } + + for (let i = 0; i < currentIndex; i++) { + let panel = thisObject.panels[i] + if (panel.leftRightButton !== undefined) { + if (panel.leftRightButton.status !== 'left' && panel.leftRightButton.status !== 'right') { // we avoid pushing other panels while in transition + continue + } + } + if (panel.isVisible === true && panel.isHidden === false) { + if (isThisPointInsideThisFrame(corner1, panel.container.frame) === true) { + pushOut(currentContainer, panel.container, panel.gravitatesTowards) + } + if (isThisPointInsideThisFrame(corner2, panel.container.frame) === true) { + pushOut(currentContainer, panel.container, panel.gravitatesTowards) + } + if (isThisPointInsideThisFrame(corner3, panel.container.frame) === true) { + pushOut(currentContainer, panel.container, panel.gravitatesTowards) + } + if (isThisPointInsideThisFrame(corner4, panel.container.frame) === true) { + pushOut(currentContainer, panel.container, panel.gravitatesTowards) + } + } + } + + function pushOut(currentContainer, controlContainer, corner) { + switch (corner) { + case 'topLeft': { + currentContainer.frame.position.x = controlContainer.frame.position.x + controlContainer.frame.width + break + } + case 'topRight': { + currentContainer.frame.position.x = controlContainer.frame.position.x - currentContainer.frame.width + break + } + case 'bottomLeft': { + currentContainer.frame.position.x = controlContainer.frame.position.x + controlContainer.frame.width + break + } + case 'bottomRight': { + currentContainer.frame.position.x = controlContainer.frame.position.x - currentContainer.frame.width + break + } + } + } + + function isThisPointInsideThisFrame(point, frame) { + let corner1 = { + x: frame.position.x, + y: frame.position.y + } + let corner2 = { + x: frame.position.x + frame.width, + y: frame.position.y + } + let corner3 = { + x: frame.position.x + frame.width, + y: frame.position.y + frame.height + } + let corner4 = { + x: frame.position.x, + y: frame.position.y + frame.height + } + if (point.x >= corner1.x && point.y >= corner1.y && point.x <= corner3.x && point.y <= corner3.y) { + return true + } else { + return false + } + } + return false + } + } + + function draw() { + if (canWeDraw === false) { return } + if (thisObject.visible !== true) { return } + + thisObject.container.frame.draw(false, false) + + for (let i = 0; i < thisObject.panels.length; i++) { + let panel = thisObject.panels[i] + let owner = canvas.chartingSpace.inViewport.get(panel.owner) + if (owner !== undefined) { + if (panel.isVisible === true && panel.isHidden === false) { + panel.draw() + } + } + } + } + + function getContainer(point, purpose) { + if (thisObject.visible !== true) { return } + + let container + /* + We search for the container of panels in the oposite direction than we do it for drawing them, + so panels overlapping others are picked firt although they are drawn last. + */ + for (let i = thisObject.panels.length - 1; i >= 0; i--) { + let panel = thisObject.panels[i] + let owner = canvas.chartingSpace.inViewport.get(panel.owner) + if (owner !== undefined) { + if (panel.isVisible === true && panel.isHidden === false) { + container = panel.getContainer(point, purpose) + } + } + if (container !== undefined) { + container.space = 'Panels Space' + return container + } + } + // thisObject.container.space = 'Panels Space' + // return thisObject.container + } } diff --git a/Spaces/SideSpace.js b/Spaces/SideSpace.js index a950c9b7c..145edec11 100644 --- a/Spaces/SideSpace.js +++ b/Spaces/SideSpace.js @@ -1,168 +1,168 @@ -function newSideSpace () { - const MODULE_NAME = 'Side Space' - let thisObject = { - sidePanelTab: undefined, - container: undefined, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - let isInitialized = false - - thisObject.container = newContainer() - thisObject.container.name = MODULE_NAME - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - thisObject.container.detectMouseOver = true - thisObject.container.status = 'hidden' - - let listView - - resize() - - let openingEventSubscriptionId - let closedEventSubscriptionId - let browserResizedEventSubscriptionId - return thisObject - - function initialize () { - thisObject.sidePanelTab = newSidePanelTab() - thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) - thisObject.sidePanelTab.initialize() - - browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) - - initializeListView() - isInitialized = true - } - - function finalize () { - canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) - thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) - thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) - } - - function initializeListView () { - listView = newListView() - listView.initialize() - listView.container.connectToParent(thisObject.container, false, false) - openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', listView.turnOn) - closedEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closed', listView.turnOff) - } - - function resize () { - thisObject.container.frame.width = SIDE_PANEL_WIDTH - thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT - thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH - thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT - - if (listView !== undefined) { - listView.resize() +function newSideSpace() { + const MODULE_NAME = 'Side Space' + let thisObject = { + sidePanelTab: undefined, + container: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize } - if (thisObject.sidePanelTab !== undefined) { - thisObject.sidePanelTab.resize() - } - } + let isInitialized = false - function getContainer (point, purpose) { - let container + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.status = 'hidden' - container = thisObject.sidePanelTab.getContainer(point, purpose) - if (container !== undefined) { return container } + let listView - container = listView.getContainer(point, purpose) - if (container !== undefined) { return container } + resize() - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } + let openingEventSubscriptionId + let closedEventSubscriptionId + let browserResizedEventSubscriptionId + return thisObject - function physics () { - thisObject.sidePanelTab.physics() - listView.physics() - } + function initialize() { + thisObject.sidePanelTab = newSidePanelTab() + thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) + thisObject.sidePanelTab.initialize() - function draw () { - if (canWeDraw === false) { return } - if (isInitialized === false) { return } - borders() - thisObject.sidePanelTab.draw() - listView.draw() - } + browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) - function borders () { - let point1 - let point2 - let point3 - let point4 - - point1 = { - x: 0, - y: 0 + initializeListView() + isInitialized = true } - point2 = { - x: thisObject.container.frame.width, - y: 0 + function finalize() { + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) } - point3 = { - x: thisObject.container.frame.width, - y: thisObject.container.frame.height + function initializeListView() { + listView = newListView() + listView.initialize() + listView.container.connectToParent(thisObject.container, false, false) + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', listView.turnOn) + closedEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closed', listView.turnOff) } - point4 = { - x: 0, - y: thisObject.container.frame.height + function resize() { + thisObject.container.frame.width = SIDE_PANEL_WIDTH + thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT + thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH + thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT + + if (listView !== undefined) { + listView.resize() + } + + if (thisObject.sidePanelTab !== undefined) { + thisObject.sidePanelTab.resize() + } } - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) - point4 = thisObject.container.frame.frameThisPoint(point4) + function getContainer(point, purpose) { + let container - browserCanvasContext.setLineDash([0, 0]) - browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - browserCanvasContext.lineTo(point4.x, point4.y) - browserCanvasContext.lineTo(point1.x, point1.y) - browserCanvasContext.closePath() + container = thisObject.sidePanelTab.getContainer(point, purpose) + if (container !== undefined) { return container } - let opacity = 1 + container = listView.getContainer(point, purpose) + if (container !== undefined) { return container } - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' - browserCanvasContext.fill() + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' - browserCanvasContext.lineWidth = 0.3 - browserCanvasContext.stroke() + function physics() { + thisObject.sidePanelTab.physics() + listView.physics() + } - /* Shadow */ + function draw() { + if (canWeDraw === false) { return } + if (isInitialized === false) { return } + borders() + thisObject.sidePanelTab.draw() + listView.draw() + } - if (thisObject.container.status !== 'hidden') { - for (let i = 0; i <= 30; i++) { - opacity = 1 - (i / 300) - 0.95 + function borders() { + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: thisObject.container.frame.width, + y: 0 + } + + point3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + point4 = { + x: 0, + y: thisObject.container.frame.height + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + point4 = thisObject.container.frame.frameThisPoint(point4) browserCanvasContext.setLineDash([0, 0]) browserCanvasContext.beginPath() - browserCanvasContext.moveTo(point2.x + i, point2.y) - browserCanvasContext.lineTo(point3.x + i, point3.y) + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' - browserCanvasContext.lineWidth = 1 + let opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' + browserCanvasContext.fill() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.lineWidth = 0.3 browserCanvasContext.stroke() - } + + /* Shadow */ + + if (thisObject.container.status !== 'hidden') { + for (let i = 0; i <= 30; i++) { + opacity = 1 - (i / 300) - 0.95 + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point2.x + i, point2.y) + browserCanvasContext.lineTo(point3.x + i, point3.y) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() + } + } } - } } diff --git a/Spaces/TopSpace.js b/Spaces/TopSpace.js index c88dd2960..1e511a780 100644 --- a/Spaces/TopSpace.js +++ b/Spaces/TopSpace.js @@ -1,109 +1,109 @@ -function newTopSpace () { - let thisObject = { - container: undefined, - draw: draw, - getContainer: getContainer, - initialize: initialize - } - - thisObject.container = newContainer() - thisObject.container.initialize() - - resize() - - thisObject.container.isDraggeable = false - let backgroundImage - let logoImage - return thisObject - - function initialize () { - canvas.eventHandler.listenToEvent('Browser Resized', resize) - - backgroundImage = new Image() - logoImage = new Image() - - loadImage('superalgos-header-background', backgroundImage) - loadImage('superalgos-logo-for-color-background', logoImage) - - function loadImage (name, image) { - const PATH = 'Images/' - - image.onload = onImageLoad - image.fileName = name - - function onImageLoad () { - image.canDraw = true - } - image.src = window.canvasApp.urlPrefix + PATH + name + '.png' +function newTopSpace() { + let thisObject = { + container: undefined, + draw: draw, + getContainer: getContainer, + initialize: initialize } - } - function resize () { - thisObject.container.frame.width = browserCanvas.width - thisObject.container.frame.height = TOP_SPACE_HEIGHT + thisObject.container = newContainer() + thisObject.container.initialize() - thisObject.container.frame.position.x = 0 - try { - thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.bottomLeft.y - } catch (e) { } - } + resize() - function getContainer (point) { + thisObject.container.isDraggeable = false + let backgroundImage + let logoImage + return thisObject - } + function initialize() { + canvas.eventHandler.listenToEvent('Browser Resized', resize) - function draw () { - if (canWeDraw === false) { return } - thisObject.container.frame.draw(false, false) + backgroundImage = new Image() + logoImage = new Image() - drawBackground() - return - } + loadImage('superalgos-header-background', backgroundImage) + loadImage('superalgos-logo-for-color-background', logoImage) - function drawBackground () { - /* Solid Color */ - let opacity = 1 - browserCanvasContext.beginPath() - browserCanvasContext.rect(0, 0, thisObject.container.frame.width, thisObject.container.frame.height) - if (ARE_WE_RECORDING_A_VIDEO === true) { - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')' - } else { - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')' + function loadImage(name, image) { + const PATH = 'Images/' + + image.onload = onImageLoad + image.fileName = name + + function onImageLoad() { + image.canDraw = true + } + image.src = window.canvasApp.urlPrefix + PATH + name + '.png' + } } - browserCanvasContext.closePath() - browserCanvasContext.fill() - /* Background Image */ - if (backgroundImage !== undefined) { - if (backgroundImage.canDraw === true) { - let imagePosition = { - x: 0, - y: 0 + function resize() { + thisObject.container.frame.width = browserCanvas.width + thisObject.container.frame.height = TOP_SPACE_HEIGHT + + thisObject.container.frame.position.x = 0 + try { + thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.bottomLeft.y + } catch (e) { } + } + + function getContainer(point) { + + } + + function draw() { + if (canWeDraw === false) { return } + thisObject.container.frame.draw(false, false) + + drawBackground() + return + } + + function drawBackground() { + /* Solid Color */ + let opacity = 1 + browserCanvasContext.beginPath() + browserCanvasContext.rect(0, 0, thisObject.container.frame.width, thisObject.container.frame.height) + if (ARE_WE_RECORDING_A_VIDEO === true) { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')' + } else { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')' + } + browserCanvasContext.closePath() + browserCanvasContext.fill() + + /* Background Image */ + if (backgroundImage !== undefined) { + if (backgroundImage.canDraw === true) { + let imagePosition = { + x: 0, + y: 0 + } + + browserCanvasContext.drawImage( + backgroundImage, imagePosition.x, + imagePosition.y, + browserCanvas.width, + TOP_SPACE_HEIGHT - 2) + } } - browserCanvasContext.drawImage( - backgroundImage, imagePosition.x, - imagePosition.y, - browserCanvas.width, - TOP_SPACE_HEIGHT - 2) - } - } + /* Logo Image */ + if (logoImage !== undefined) { + if (logoImage.canDraw === true) { + let imagePosition = { + x: 10, + y: 0 + } - /* Logo Image */ - if (logoImage !== undefined) { - if (logoImage.canDraw === true) { - let imagePosition = { - x: 10, - y: 0 + browserCanvasContext.drawImage( + logoImage, imagePosition.x, + imagePosition.y, + 150, + TOP_SPACE_HEIGHT - 2) + } } - - browserCanvasContext.drawImage( - logoImage, imagePosition.x, - imagePosition.y, - 150, - TOP_SPACE_HEIGHT - 2) - } } - } } diff --git a/SplashScreen.js b/SplashScreen.js index 6e7dfa436..ca8662ced 100644 --- a/SplashScreen.js +++ b/SplashScreen.js @@ -1,160 +1,160 @@ - /* +/* The Splash Screen is to show some 'loading...' controls while the app is being loaded on the background. After the loading is complete the Splash Screens dissapears for good. */ -function newSplashScreen () { - let thisObject = { - container: undefined, - draw: draw, - timeMachines: [], - getContainer: getContainer, // returns the inner most container that holds the point received by parameter. - initialize: initialize - } - - let container = newContainer() - container.initialize() - thisObject.container = container - - resize() - - container.frame.containerName = 'Splash Screen' - - container.frame.position.x = 0 - container.frame.position.y = 0 - - container.isDraggeable = false - - let fadeOutCounter = 0 - let opacity = 1 - - let logo - let canDrawLogo = false - let isInitialized = false - let splashScreenNeeded = true - - return thisObject - - function initialize () { - logo = new Image() - logo.onload = onImageLoad - - function onImageLoad () { - canDrawLogo = true - } - logo.src = window.canvasApp.urlPrefix + 'Images/superalgos-logo.png' - canvas.eventHandler.listenToEvent('Browser Resized', resize) - - isInitialized = true - } - - function resize () { - thisObject.container.frame.width = browserCanvas.width - thisObject.container.frame.height = browserCanvas.height - } - - function draw () { - if (isInitialized === false) { return } - if (splashScreenNeeded === false) { - stepsInitializationCounter = 100 - canDrawLogo = false - - fadeOutCounter++ - - if (fadeOutCounter > 2) { - return - } - opacity = opacity - 1 +function newSplashScreen() { + let thisObject = { + container: undefined, + draw: draw, + timeMachines: [], + getContainer: getContainer, // returns the inner most container that holds the point received by parameter. + initialize: initialize } - thisObject.container.frame.draw(false, false) + let container = newContainer() + container.initialize() + thisObject.container = container + + resize() + + container.frame.containerName = 'Splash Screen' + + container.frame.position.x = 0 + container.frame.position.y = 0 + + container.isDraggeable = false + + let fadeOutCounter = 0 + let opacity = 1 + + let logo + let canDrawLogo = false + let isInitialized = false + let splashScreenNeeded = true + + return thisObject + + function initialize() { + logo = new Image() + logo.onload = onImageLoad + + function onImageLoad() { + canDrawLogo = true + } + logo.src = window.canvasApp.urlPrefix + 'Images/superalgos-logo.png' + canvas.eventHandler.listenToEvent('Browser Resized', resize) + + isInitialized = true + } + + function resize() { + thisObject.container.frame.width = browserCanvas.width + thisObject.container.frame.height = browserCanvas.height + } + + function draw() { + if (isInitialized === false) { return } + if (splashScreenNeeded === false) { + stepsInitializationCounter = 100 + canDrawLogo = false + + fadeOutCounter++ + + if (fadeOutCounter > 2) { + return + } + opacity = opacity - 1 + } + + thisObject.container.frame.draw(false, false) /* Set the background. */ - browserCanvasContext.beginPath() - browserCanvasContext.rect(0, 0, thisObject.container.frame.width, thisObject.container.frame.height) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')' - browserCanvasContext.closePath() - browserCanvasContext.fill() + browserCanvasContext.beginPath() + browserCanvasContext.rect(0, 0, thisObject.container.frame.width, thisObject.container.frame.height) + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')' + browserCanvasContext.closePath() + browserCanvasContext.fill() - if (canDrawLogo === false) { return } + if (canDrawLogo === false) { return } /* First the AA Logo. */ - let imageHeight = 192 / 2 - let imageWidth = 720 / 2 - let yDisplacement = -60 - let xDisplacement = -60 + let imageHeight = 192 / 2 + let imageWidth = 720 / 2 + let yDisplacement = -60 + let xDisplacement = -60 - let imagePoint = { - x: thisObject.container.frame.width * 1 / 2 - imageWidth / 2 + xDisplacement, - y: thisObject.container.frame.height * 1 / 2 - imageHeight / 2 + yDisplacement - } + let imagePoint = { + x: thisObject.container.frame.width * 1 / 2 - imageWidth / 2 + xDisplacement, + y: thisObject.container.frame.height * 1 / 2 - imageHeight / 2 + yDisplacement + } - imagePoint = thisObject.container.frame.frameThisPoint(imagePoint) + imagePoint = thisObject.container.frame.frameThisPoint(imagePoint) - browserCanvasContext.drawImage(logo, imagePoint.x, imagePoint.y, imageWidth, imageHeight) + browserCanvasContext.drawImage(logo, imagePoint.x, imagePoint.y, imageWidth, imageHeight) /* Second the % of Advance. */ - let label = '' + Math.trunc(stepsInitializationCounter) + ' %' - stepsInitializationCounter = stepsInitializationCounter + 5.0 + let label = '' + Math.trunc(stepsInitializationCounter) + ' %' + stepsInitializationCounter = stepsInitializationCounter + 5.0 - if (stepsInitializationCounter > 99) { - splashScreenNeeded = false - canWeDraw = true - stepsInitializationCounter = 99 - } + if (stepsInitializationCounter > 99) { + splashScreenNeeded = false + canWeDraw = true + stepsInitializationCounter = 99 + } - let fontSize = 15 + let fontSize = 15 - let labelPoint = { - x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 22, - y: thisObject.container.frame.height / 2 + fontSize / 2 + fontSize * 0.1 + 90 + yDisplacement - } + let labelPoint = { + x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 22, + y: thisObject.container.frame.height / 2 + fontSize / 2 + fontSize * 0.1 + 90 + yDisplacement + } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(0, 0, 0, ' + opacity + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(0, 0, 0, ' + opacity + ')' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - let title - let titlePoint + let title + let titlePoint /* Algo Bots Competitions Sub Title */ - fontSize = 35 + fontSize = 35 - title = 'Beta 6' + title = 'Beta 6' - titlePoint = { - x: thisObject.container.frame.width / 2 - title.length / 2 * fontSize * FONT_ASPECT_RATIO - 20, - y: thisObject.container.frame.height / 2 + 70 + yDisplacement + titlePoint = { + x: thisObject.container.frame.width / 2 - title.length / 2 * fontSize * FONT_ASPECT_RATIO - 20, + y: thisObject.container.frame.height / 2 + 70 + yDisplacement + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.font = 'Saira Condensed' + browserCanvasContext.fillStyle = 'rgba(0, 0, 0, ' + opacity + ')' + browserCanvasContext.fillText(title, titlePoint.x, titlePoint.y) } - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.font = 'Saira Condensed' - browserCanvasContext.fillStyle = 'rgba(0, 0, 0, ' + opacity + ')' - browserCanvasContext.fillText(title, titlePoint.x, titlePoint.y) - } - - function getContainer (point) { - var container + function getContainer(point) { + var container /* First we check if this point is inside this space. */ - if (thisObject.container.frame.isThisPointHere(point) === true) { + if (thisObject.container.frame.isThisPointHere(point) === true) { /* Now we see which is the inner most container that has it */ // add validation of inner most containers here. /* The point does not belong to any inner container, so we return the current container. */ - return thisObject.container - } else { + return thisObject.container + } else { /* This point does not belong to this space. */ - return undefined + return undefined + } } - } } diff --git a/Utilities.js b/Utilities.js index 4a434bba8..11eeb5a37 100644 --- a/Utilities.js +++ b/Utilities.js @@ -1,90 +1,90 @@ -function getNodeDefinition (node) { - let key = node.type - return APP_SCHEMA_MAP.get(key) +function getNodeDefinition(node) { + let key = node.type + return APP_SCHEMA_MAP.get(key) } -function dynamicDecimals (value, minDecimals) { - if (minDecimals === undefined) { - minDecimals = 0 - } - let decimals = 2 - if (value < 1) { decimals = 4 } - if (Math.abs(Math.trunc(value * 100)) < 1) { decimals = 6 } - if (Math.abs(Math.trunc(value * 10000)) < 1) { decimals = 8 } - if (Math.abs(Math.trunc(value * 1000000)) < 1) { decimals = 10 } - if (Math.abs(Math.trunc(value * 100000000)) < 1) { decimals = 12 } - if (Math.abs(Math.trunc(value * 10000000000)) < 1) { value = 0; decimals = 0 } - if (Math.trunc(value) === value) { decimals = minDecimals } - let returnValue = Number(value).toFixed(decimals) - return returnValue -} - -function convertTimeFrameToName (pTimeFrame) { - for (let i = 0; i < dailyFilePeriods.length; i++) { - let period = dailyFilePeriods[i] - if (period[0] === pTimeFrame) { - return period[1] +function dynamicDecimals(value, minDecimals) { + if (minDecimals === undefined) { + minDecimals = 0 } - } + let decimals = 2 + if (value < 1) { decimals = 4 } + if (Math.abs(Math.trunc(value * 100)) < 1) { decimals = 6 } + if (Math.abs(Math.trunc(value * 10000)) < 1) { decimals = 8 } + if (Math.abs(Math.trunc(value * 1000000)) < 1) { decimals = 10 } + if (Math.abs(Math.trunc(value * 100000000)) < 1) { decimals = 12 } + if (Math.abs(Math.trunc(value * 10000000000)) < 1) { value = 0; decimals = 0 } + if (Math.trunc(value) === value) { decimals = minDecimals } + let returnValue = Number(value).toFixed(decimals) + return returnValue +} - for (let i = 0; i < marketFilesPeriods.length; i++) { - let period = marketFilesPeriods[i] - if (period[0] === pTimeFrame) { - return period[1] +function convertTimeFrameToName(pTimeFrame) { + for (let i = 0; i < dailyFilePeriods.length; i++) { + let period = dailyFilePeriods[i] + if (period[0] === pTimeFrame) { + return period[1] + } } - } -} -function nextPorwerOf10 (number) { - for (let i = -10; i <= 10; i++) { - if (number < Math.pow(10, i)) { - return Math.pow(10, i) + for (let i = 0; i < marketFilesPeriods.length; i++) { + let period = marketFilesPeriods[i] + if (period[0] === pTimeFrame) { + return period[1] + } } - } } -function pad (str, max) { - str = str.toString() - return str.length < max ? pad('0' + str, max) : str +function nextPorwerOf10(number) { + for (let i = -10; i <= 10; i++) { + if (number < Math.pow(10, i)) { + return Math.pow(10, i) + } + } } -function moveToUserPosition (container, currentDate, currentRate, coordinateSystem, ignoreX, ignoreY, mousePosition, fitFunction) { - let targetPoint = { - x: currentDate.valueOf(), - y: currentRate - } - - /* Put this point in the coordinate system of the canvas.chartingSpace.viewport */ - targetPoint = coordinateSystem.transformThisPoint(targetPoint) - targetPoint = transformThisPoint(targetPoint, container) - - let displaceVector - - let targetNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(targetPoint) - let mouseNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mousePosition) - - displaceVector = { - x: mouseNoZoom.x - targetNoZoom.x, - y: mouseNoZoom.y - targetNoZoom.y - } - - if (ignoreX) { displaceVector.x = 0 } - if (ignoreY) { displaceVector.y = 0 } - - container.displace(displaceVector) +function pad(str, max) { + str = str.toString() + return str.length < max ? pad('0' + str, max) : str } -function removeTime (datetime) { - if (datetime === undefined) { return } +function moveToUserPosition(container, currentDate, currentRate, coordinateSystem, ignoreX, ignoreY, mousePosition, fitFunction) { + let targetPoint = { + x: currentDate.valueOf(), + y: currentRate + } - let dateOnly = new Date(Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS) + /* Put this point in the coordinate system of the canvas.chartingSpace.viewport */ + targetPoint = coordinateSystem.transformThisPoint(targetPoint) + targetPoint = transformThisPoint(targetPoint, container) - return dateOnly + let displaceVector + + let targetNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(targetPoint) + let mouseNoZoom = canvas.chartingSpace.viewport.unTransformThisPoint(mousePosition) + + displaceVector = { + x: mouseNoZoom.x - targetNoZoom.x, + y: mouseNoZoom.y - targetNoZoom.y + } + + if (ignoreX) { displaceVector.x = 0 } + if (ignoreY) { displaceVector.y = 0 } + + container.displace(displaceVector) } -function newUniqueId () { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) - return v.toString(16) - }) +function removeTime(datetime) { + if (datetime === undefined) { return } + + let dateOnly = new Date(Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS) + + return dateOnly +} + +function newUniqueId() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) + return v.toString(16) + }) } diff --git a/Utilities/CoordinateTransformations.js b/Utilities/CoordinateTransformations.js index 9f3f9444d..845210a9c 100644 --- a/Utilities/CoordinateTransformations.js +++ b/Utilities/CoordinateTransformations.js @@ -1,18 +1,18 @@ -function transformThisPoint (point, container) { +function transformThisPoint(point, container) { /* We make the point relative to the current frame */ - point = container.frame.frameThisPoint(point) + point = container.frame.frameThisPoint(point) /* We pass this point through the canvas.chartingSpace.viewport lends, meaning we apply the canvas.chartingSpace.viewport zoom and displacement. */ - point = canvas.chartingSpace.viewport.transformThisPoint(point) + point = canvas.chartingSpace.viewport.transformThisPoint(point) - return point + return point } -function unTransformThisPoint (point, container) { - point = canvas.chartingSpace.viewport.unTransformThisPoint(point) - point = container.frame.unframeThisPoint(point) +function unTransformThisPoint(point, container) { + point = canvas.chartingSpace.viewport.unTransformThisPoint(point) + point = container.frame.unframeThisPoint(point) - return point + return point } diff --git a/Utilities/DateRateTransformations.js b/Utilities/DateRateTransformations.js index 196c99ecc..4829787ed 100644 --- a/Utilities/DateRateTransformations.js +++ b/Utilities/DateRateTransformations.js @@ -1,53 +1,53 @@ -function getDateFromPointAtBrowserCanvas (point, container, coordinateSystem) { - point = unTransformThisPoint(point, container) - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getDateFromPointAtBrowserCanvas(point, container, coordinateSystem) { + point = unTransformThisPoint(point, container) + point = coordinateSystem.unInverseTransform(point, container.frame.height) - let date = new Date(point.x) + let date = new Date(point.x) - return date + return date } -function getDateFromPointAtChartsSpace (point, container, coordinateSystem) { - point = container.frame.unframeThisPoint(point) - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getDateFromPointAtChartsSpace(point, container, coordinateSystem) { + point = container.frame.unframeThisPoint(point) + point = coordinateSystem.unInverseTransform(point, container.frame.height) - let date = new Date(point.x) + let date = new Date(point.x) - return date + return date } -function getDateFromPointAtContainer (point, container, coordinateSystem) { - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getDateFromPointAtContainer(point, container, coordinateSystem) { + point = coordinateSystem.unInverseTransform(point, container.frame.height) - let date = new Date(point.x) + let date = new Date(point.x) - return date + return date } -function getRateFromPointAtBrowserCanvas (point, container, coordinateSystem) { - point = unTransformThisPoint(point, container) - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getRateFromPointAtBrowserCanvas(point, container, coordinateSystem) { + point = unTransformThisPoint(point, container) + point = coordinateSystem.unInverseTransform(point, container.frame.height) - return point.y + return point.y } -function getRateFromPointAtChartingSpace (point, container, coordinateSystem) { - point = container.frame.unframeThisPoint(point) - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getRateFromPointAtChartingSpace(point, container, coordinateSystem) { + point = container.frame.unframeThisPoint(point) + point = coordinateSystem.unInverseTransform(point, container.frame.height) - return point.y + return point.y } -function getRateFromPointAtContainer (point, container, coordinateSystem) { - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getRateFromPointAtContainer(point, container, coordinateSystem) { + point = coordinateSystem.unInverseTransform(point, container.frame.height) - return point.y + return point.y } -function getMilisecondsFromPoint (point, container, coordinateSystem) { - point = unTransformThisPoint(point, container) - point = coordinateSystem.unInverseTransform(point, container.frame.height) +function getMilisecondsFromPoint(point, container, coordinateSystem) { + point = unTransformThisPoint(point, container) + point = coordinateSystem.unInverseTransform(point, container.frame.height) - return point.x + return point.x } diff --git a/Utilities/Download.js b/Utilities/Download.js index 39e8e3884..b6007dac2 100644 --- a/Utilities/Download.js +++ b/Utilities/Download.js @@ -1,58 +1,58 @@ -function downloadText (filename, text) { - let element = document.createElement('a') - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)) - element.setAttribute('download', filename) - element.style.display = 'none' - document.body.appendChild(element) - element.click() - document.body.removeChild(element) +function downloadText(filename, text) { + let element = document.createElement('a') + element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)) + element.setAttribute('download', filename) + element.style.display = 'none' + document.body.appendChild(element) + element.click() + document.body.removeChild(element) } -function downloadCanvas (filename, canvasToUse) { - let data = canvasToUse.toDataURL('image/png', 1) - /* Change MIME type to trick the browser to downlaod the file instead of displaying it */ - data = data.replace(/^data:image\/[^;]*/, 'data:application/octet-stream') +function downloadCanvas(filename, canvasToUse) { + let data = canvasToUse.toDataURL('image/png', 1) + /* Change MIME type to trick the browser to downlaod the file instead of displaying it */ + data = data.replace(/^data:image\/[^;]*/, 'data:application/octet-stream') - /* In addition to 's "download" attribute, you can define HTTP-style headers */ - data = data.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=' + filename + '.png') + /* In addition to 's "download" attribute, you can define HTTP-style headers */ + data = data.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=' + filename + '.png') - let element = document.createElement('a') - element.setAttribute('href', data) - element.setAttribute('download', filename + '.PNG') - element.style.display = 'none' - document.body.appendChild(element) - element.click() - document.body.removeChild(element) + let element = document.createElement('a') + element.setAttribute('href', data) + element.setAttribute('download', filename + '.PNG') + element.style.display = 'none' + document.body.appendChild(element) + element.click() + document.body.removeChild(element) }; -function downloadPanorama (filename) { - let INITIAL_WIDTH = 800 - let FINAL_WIDTH = browserCanvas.width - INITIAL_WIDTH +function downloadPanorama(filename) { + let INITIAL_WIDTH = 800 + let FINAL_WIDTH = browserCanvas.width - INITIAL_WIDTH - if (ARE_WE_RECORDING_A_MARKET_PANORAMA === false) { - /* We start recording the panorame. */ - ARE_WE_RECORDING_A_MARKET_PANORAMA = true - marketPanoramaCanvas = document.createElement('canvas') - marketPanoramaCanvas.width = INITIAL_WIDTH * 50 - marketPanoramaCanvas.height = browserCanvas.height - marketPanoramaCanvas.getContext('2d').drawImage(browserCanvas, 0, 0, INITIAL_WIDTH, browserCanvas.height, 0, 0, INITIAL_WIDTH, browserCanvas.height) - CURRENT_PANORAMA_POSITION = INITIAL_WIDTH - } else { - /* We stop recording and download the resulting image. */ - ARE_WE_RECORDING_A_MARKET_PANORAMA = false - marketPanoramaCanvas.getContext('2d').drawImage(browserCanvas, browserCanvas.width - FINAL_WIDTH, 0, FINAL_WIDTH, browserCanvas.height, CURRENT_PANORAMA_POSITION, 0, FINAL_WIDTH, browserCanvas.height) - let finalResultCanvas = document.createElement('canvas') - finalResultCanvas.width = CURRENT_PANORAMA_POSITION + FINAL_WIDTH - finalResultCanvas.height = browserCanvas.height - finalResultCanvas.getContext('2d').drawImage(marketPanoramaCanvas, 0, 0, finalResultCanvas.width, browserCanvas.height, 0, 0, finalResultCanvas.width, browserCanvas.height) - downloadCanvas(filename, finalResultCanvas) - marketPanoramaCanvas = undefined - } + if (ARE_WE_RECORDING_A_MARKET_PANORAMA === false) { + /* We start recording the panorame. */ + ARE_WE_RECORDING_A_MARKET_PANORAMA = true + marketPanoramaCanvas = document.createElement('canvas') + marketPanoramaCanvas.width = INITIAL_WIDTH * 50 + marketPanoramaCanvas.height = browserCanvas.height + marketPanoramaCanvas.getContext('2d').drawImage(browserCanvas, 0, 0, INITIAL_WIDTH, browserCanvas.height, 0, 0, INITIAL_WIDTH, browserCanvas.height) + CURRENT_PANORAMA_POSITION = INITIAL_WIDTH + } else { + /* We stop recording and download the resulting image. */ + ARE_WE_RECORDING_A_MARKET_PANORAMA = false + marketPanoramaCanvas.getContext('2d').drawImage(browserCanvas, browserCanvas.width - FINAL_WIDTH, 0, FINAL_WIDTH, browserCanvas.height, CURRENT_PANORAMA_POSITION, 0, FINAL_WIDTH, browserCanvas.height) + let finalResultCanvas = document.createElement('canvas') + finalResultCanvas.width = CURRENT_PANORAMA_POSITION + FINAL_WIDTH + finalResultCanvas.height = browserCanvas.height + finalResultCanvas.getContext('2d').drawImage(marketPanoramaCanvas, 0, 0, finalResultCanvas.width, browserCanvas.height, 0, 0, finalResultCanvas.width, browserCanvas.height) + downloadCanvas(filename, finalResultCanvas) + marketPanoramaCanvas = undefined + } } -function addToMarketPanorama () { - let SECTION_WIDTH = 80 * 2 - let INITIAL_POSITION = 800 - SECTION_WIDTH - marketPanoramaCanvas.getContext('2d').drawImage(browserCanvas, INITIAL_POSITION, 0, SECTION_WIDTH, browserCanvas.height, CURRENT_PANORAMA_POSITION, 0, SECTION_WIDTH, browserCanvas.height) - CURRENT_PANORAMA_POSITION = CURRENT_PANORAMA_POSITION + SECTION_WIDTH +function addToMarketPanorama() { + let SECTION_WIDTH = 80 * 2 + let INITIAL_POSITION = 800 - SECTION_WIDTH + marketPanoramaCanvas.getContext('2d').drawImage(browserCanvas, INITIAL_POSITION, 0, SECTION_WIDTH, browserCanvas.height, CURRENT_PANORAMA_POSITION, 0, SECTION_WIDTH, browserCanvas.height) + CURRENT_PANORAMA_POSITION = CURRENT_PANORAMA_POSITION + SECTION_WIDTH } diff --git a/Utilities/DrawPrint.js b/Utilities/DrawPrint.js index 4e38f2a0c..37dad6bb4 100644 --- a/Utilities/DrawPrint.js +++ b/Utilities/DrawPrint.js @@ -1,221 +1,221 @@ -function roundedCornersBackground (params) { - if (params.xOffset === undefined) { params.xOffset = 0 } - borderPoint1 = { - x: params.cornerRadius + params.xOffset, - y: params.cornerRadius - } - - borderPoint2 = { - x: params.container.frame.width - params.cornerRadius, - y: params.cornerRadius - } - - borderPoint3 = { - x: params.container.frame.width - params.cornerRadius, - y: params.container.frame.height - params.cornerRadius - } - - borderPoint4 = { - x: params.cornerRadius + params.xOffset, - y: params.container.frame.height - params.cornerRadius - } - - /* Now the transformations. */ - - if (params.coordinateSystem !== undefined) { // For instance Candles would use this - borderPoint1 = params.coordinateSystem.transformThisPoint(borderPoint1) - borderPoint2 = params.coordinateSystem.transformThisPoint(borderPoint2) - borderPoint3 = params.coordinateSystem.transformThisPoint(borderPoint3) - borderPoint4 = params.coordinateSystem.transformThisPoint(borderPoint4) - } else { - if (params.outsideViewPort === true) { // If the element is not affected by zoom - borderPoint1 = transformThisPoint(borderPoint1, params.container) - borderPoint2 = transformThisPoint(borderPoint2, params.container) - borderPoint3 = transformThisPoint(borderPoint3, params.container) - borderPoint4 = transformThisPoint(borderPoint4, params.container) - } else { // For instance Panels use this - borderPoint1 = params.container.frame.frameThisPoint(borderPoint1) - borderPoint2 = params.container.frame.frameThisPoint(borderPoint2) - borderPoint3 = params.container.frame.frameThisPoint(borderPoint3) - borderPoint4 = params.container.frame.frameThisPoint(borderPoint4) +function roundedCornersBackground(params) { + if (params.xOffset === undefined) { params.xOffset = 0 } + borderPoint1 = { + x: params.cornerRadius + params.xOffset, + y: params.cornerRadius } - } - if (params.fitFunction !== undefined) { - borderPoint1 = params.fitFunction(borderPoint1) - borderPoint2 = params.fitFunction(borderPoint2) - borderPoint3 = params.fitFunction(borderPoint3) - borderPoint4 = params.fitFunction(borderPoint4) - } + borderPoint2 = { + x: params.container.frame.width - params.cornerRadius, + y: params.cornerRadius + } - browserCanvasContext.setLineDash([0, 0]) + borderPoint3 = { + x: params.container.frame.width - params.cornerRadius, + y: params.container.frame.height - params.cornerRadius + } - /* Shadow */ + borderPoint4 = { + x: params.cornerRadius + params.xOffset, + y: params.container.frame.height - params.cornerRadius + } - if (params.castShadow === true) { - let SHADOW_OFFSET = 2 + /* Now the transformations. */ + + if (params.coordinateSystem !== undefined) { // For instance Candles would use this + borderPoint1 = params.coordinateSystem.transformThisPoint(borderPoint1) + borderPoint2 = params.coordinateSystem.transformThisPoint(borderPoint2) + borderPoint3 = params.coordinateSystem.transformThisPoint(borderPoint3) + borderPoint4 = params.coordinateSystem.transformThisPoint(borderPoint4) + } else { + if (params.outsideViewPort === true) { // If the element is not affected by zoom + borderPoint1 = transformThisPoint(borderPoint1, params.container) + borderPoint2 = transformThisPoint(borderPoint2, params.container) + borderPoint3 = transformThisPoint(borderPoint3, params.container) + borderPoint4 = transformThisPoint(borderPoint4, params.container) + } else { // For instance Panels use this + borderPoint1 = params.container.frame.frameThisPoint(borderPoint1) + borderPoint2 = params.container.frame.frameThisPoint(borderPoint2) + borderPoint3 = params.container.frame.frameThisPoint(borderPoint3) + borderPoint4 = params.container.frame.frameThisPoint(borderPoint4) + } + } + + if (params.fitFunction !== undefined) { + borderPoint1 = params.fitFunction(borderPoint1) + borderPoint2 = params.fitFunction(borderPoint2) + borderPoint3 = params.fitFunction(borderPoint3) + borderPoint4 = params.fitFunction(borderPoint4) + } + + browserCanvasContext.setLineDash([0, 0]) + + /* Shadow */ + + if (params.castShadow === true) { + let SHADOW_OFFSET = 2 + + browserCanvasContext.beginPath() + + browserCanvasContext.arc(borderPoint1.x + SHADOW_OFFSET, borderPoint1.y + SHADOW_OFFSET, params.cornerRadius, 1.0 * Math.PI, 1.5 * Math.PI) + browserCanvasContext.lineTo(borderPoint2.x + SHADOW_OFFSET, borderPoint2.y - params.cornerRadius + SHADOW_OFFSET) + browserCanvasContext.arc(borderPoint2.x + SHADOW_OFFSET, borderPoint2.y + SHADOW_OFFSET, params.cornerRadius, 1.5 * Math.PI, 2.0 * Math.PI) + browserCanvasContext.lineTo(borderPoint3.x + params.cornerRadius + SHADOW_OFFSET, borderPoint3.y + SHADOW_OFFSET) + browserCanvasContext.arc(borderPoint3.x + SHADOW_OFFSET, borderPoint3.y + SHADOW_OFFSET, params.cornerRadius, 0 * Math.PI, 0.5 * Math.PI) + browserCanvasContext.lineTo(borderPoint4.x + SHADOW_OFFSET, borderPoint4.y + params.cornerRadius + SHADOW_OFFSET) + browserCanvasContext.arc(borderPoint4.x + SHADOW_OFFSET, borderPoint4.y + SHADOW_OFFSET, params.cornerRadius, 0.5 * Math.PI, 1.0 * Math.PI) + browserCanvasContext.lineTo(borderPoint1.x - params.cornerRadius + SHADOW_OFFSET, borderPoint1.y + SHADOW_OFFSET) + + browserCanvasContext.closePath() + + browserCanvasContext.lineWidth = 10 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.01 + ')' + browserCanvasContext.stroke() + + browserCanvasContext.lineWidth = 5 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.01 + ')' + browserCanvasContext.stroke() + + browserCanvasContext.lineWidth = 1 + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.15 + ')' + browserCanvasContext.stroke() + } + + /* Background */ browserCanvasContext.beginPath() - browserCanvasContext.arc(borderPoint1.x + SHADOW_OFFSET, borderPoint1.y + SHADOW_OFFSET, params.cornerRadius, 1.0 * Math.PI, 1.5 * Math.PI) - browserCanvasContext.lineTo(borderPoint2.x + SHADOW_OFFSET, borderPoint2.y - params.cornerRadius + SHADOW_OFFSET) - browserCanvasContext.arc(borderPoint2.x + SHADOW_OFFSET, borderPoint2.y + SHADOW_OFFSET, params.cornerRadius, 1.5 * Math.PI, 2.0 * Math.PI) - browserCanvasContext.lineTo(borderPoint3.x + params.cornerRadius + SHADOW_OFFSET, borderPoint3.y + SHADOW_OFFSET) - browserCanvasContext.arc(borderPoint3.x + SHADOW_OFFSET, borderPoint3.y + SHADOW_OFFSET, params.cornerRadius, 0 * Math.PI, 0.5 * Math.PI) - browserCanvasContext.lineTo(borderPoint4.x + SHADOW_OFFSET, borderPoint4.y + params.cornerRadius + SHADOW_OFFSET) - browserCanvasContext.arc(borderPoint4.x + SHADOW_OFFSET, borderPoint4.y + SHADOW_OFFSET, params.cornerRadius, 0.5 * Math.PI, 1.0 * Math.PI) - browserCanvasContext.lineTo(borderPoint1.x - params.cornerRadius + SHADOW_OFFSET, borderPoint1.y + SHADOW_OFFSET) + browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, params.cornerRadius, 1.0 * Math.PI, 1.5 * Math.PI) + browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - params.cornerRadius) + browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, params.cornerRadius, 1.5 * Math.PI, 2.0 * Math.PI) + browserCanvasContext.lineTo(borderPoint3.x + params.cornerRadius, borderPoint3.y) + browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, params.cornerRadius, 0 * Math.PI, 0.5 * Math.PI) + browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + params.cornerRadius) + browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, params.cornerRadius, 0.5 * Math.PI, 1.0 * Math.PI) + browserCanvasContext.lineTo(borderPoint1.x - params.cornerRadius, borderPoint1.y) browserCanvasContext.closePath() - browserCanvasContext.lineWidth = 10 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.01 + ')' + browserCanvasContext.fillStyle = 'rgba(' + params.backgroundColor + ', ' + params.opacity + ')' + + browserCanvasContext.fill() + + browserCanvasContext.lineWidth = params.lineWidth + browserCanvasContext.strokeStyle = 'rgba(' + params.borderColor + ', ' + params.opacity + ')' browserCanvasContext.stroke() - - browserCanvasContext.lineWidth = 5 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.01 + ')' - browserCanvasContext.stroke() - - browserCanvasContext.lineWidth = 1 - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.15 + ')' - browserCanvasContext.stroke() - } - - /* Background */ - - browserCanvasContext.beginPath() - - browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, params.cornerRadius, 1.0 * Math.PI, 1.5 * Math.PI) - browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - params.cornerRadius) - browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, params.cornerRadius, 1.5 * Math.PI, 2.0 * Math.PI) - browserCanvasContext.lineTo(borderPoint3.x + params.cornerRadius, borderPoint3.y) - browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, params.cornerRadius, 0 * Math.PI, 0.5 * Math.PI) - browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + params.cornerRadius) - browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, params.cornerRadius, 0.5 * Math.PI, 1.0 * Math.PI) - browserCanvasContext.lineTo(borderPoint1.x - params.cornerRadius, borderPoint1.y) - - browserCanvasContext.closePath() - - browserCanvasContext.fillStyle = 'rgba(' + params.backgroundColor + ', ' + params.opacity + ')' - - browserCanvasContext.fill() - - browserCanvasContext.lineWidth = params.lineWidth - browserCanvasContext.strokeStyle = 'rgba(' + params.borderColor + ', ' + params.opacity + ')' - browserCanvasContext.stroke() } -function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, container, fontColor, noFrameX, noFrameY, opacity) { - if (label === undefined) { return } - if (fontColor === undefined) { fontColor = UI_COLOR.WHITE } - let fontOffset = label.length * fontSize * FONT_ASPECT_RATIO + 10 - if (opacity === undefined) { opacity = 1 } +function drawLabel(label, xFactor, yFactor, xOffset, yOffset, fontSize, container, fontColor, noFrameX, noFrameY, opacity) { + if (label === undefined) { return } + if (fontColor === undefined) { fontColor = UI_COLOR.WHITE } + let fontOffset = label.length * fontSize * FONT_ASPECT_RATIO + 10 + if (opacity === undefined) { opacity = 1 } - let labelPoint = { - x: container.frame.width * xFactor + xOffset - fontOffset / 2, - y: container.frame.height * yFactor + yOffset - } - - labelPoint = container.frame.frameThisPoint(labelPoint) - - if (noFrameX !== undefined) { - labelPoint.x = noFrameX + xOffset - } - - if (noFrameY !== undefined) { - labelPoint.y = noFrameY + yOffset - } - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + fontColor + ', ' + opacity + ')' - - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) -} - -function drawIcon (icon, xFactor, yFactor, xOffset, yOffset, imageSize, container) { - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - let imagePosition = { - x: container.frame.width * xFactor + xOffset - imageSize / 2, - y: container.frame.height * yFactor + yOffset - imageSize / 2 - } - - imagePosition = container.frame.frameThisPoint(imagePosition) - - browserCanvasContext.drawImage( - icon, imagePosition.x, - imagePosition.y, - imageSize, - imageSize) + let labelPoint = { + x: container.frame.width * xFactor + xOffset - fontOffset / 2, + y: container.frame.height * yFactor + yOffset } - } -} -function drawContainerBackground (container, color, opacity, fitFunction) { - let fromPoint = { - x: 0, - y: 0 - } - - let toPoint = { - x: container.frame.width, - y: container.frame.height - } - - fromPoint = transformThisPoint(fromPoint, container) - toPoint = transformThisPoint(toPoint, container) - - fromPoint = fitFunction(fromPoint) - toPoint = fitFunction(toPoint) - - browserCanvasContext.beginPath() - browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) - browserCanvasContext.fillStyle = 'rgba(' + color + ', ' + opacity + ')' - browserCanvasContext.closePath() - browserCanvasContext.fill() -} - -function printLabel (labelToPrint, x, y, opacity, fontSize, color, center, container, fitFunction, noDecimals, fixedDecimals) { - if (labelToPrint === undefined) { return } - let labelPoint - if (color === undefined) { color = UI_COLOR.DARK } - if (fontSize === undefined) { fontSize = 10 }; - - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - let label = labelToPrint - if (isNaN(label) === false && label !== '') { - if (fixedDecimals !== true) { - label = dynamicDecimals(labelToPrint) - } - label = label.toLocaleString() - if (noDecimals === true) { - label = Math.trunc(label) - } - } - - let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO - - if (center === true) { - labelPoint = { - x: x - xOffset, - y: y - } - } else { - labelPoint = { - x: x, - y: y - } - } - - if (container !== undefined) { labelPoint = container.frame.frameThisPoint(labelPoint) - } - if (fitFunction !== undefined) { - labelPoint = fitFunction(labelPoint) - } + if (noFrameX !== undefined) { + labelPoint.x = noFrameX + xOffset + } - browserCanvasContext.fillStyle = 'rgba(' + color + ', ' + opacity + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) + if (noFrameY !== undefined) { + labelPoint.y = noFrameY + yOffset + } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + fontColor + ', ' + opacity + ')' + + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) +} + +function drawIcon(icon, xFactor, yFactor, xOffset, yOffset, imageSize, container) { + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + let imagePosition = { + x: container.frame.width * xFactor + xOffset - imageSize / 2, + y: container.frame.height * yFactor + yOffset - imageSize / 2 + } + + imagePosition = container.frame.frameThisPoint(imagePosition) + + browserCanvasContext.drawImage( + icon, imagePosition.x, + imagePosition.y, + imageSize, + imageSize) + } + } +} + +function drawContainerBackground(container, color, opacity, fitFunction) { + let fromPoint = { + x: 0, + y: 0 + } + + let toPoint = { + x: container.frame.width, + y: container.frame.height + } + + fromPoint = transformThisPoint(fromPoint, container) + toPoint = transformThisPoint(toPoint, container) + + fromPoint = fitFunction(fromPoint) + toPoint = fitFunction(toPoint) + + browserCanvasContext.beginPath() + browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) + browserCanvasContext.fillStyle = 'rgba(' + color + ', ' + opacity + ')' + browserCanvasContext.closePath() + browserCanvasContext.fill() +} + +function printLabel(labelToPrint, x, y, opacity, fontSize, color, center, container, fitFunction, noDecimals, fixedDecimals) { + if (labelToPrint === undefined) { return } + let labelPoint + if (color === undefined) { color = UI_COLOR.DARK } + if (fontSize === undefined) { fontSize = 10 }; + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + let label = labelToPrint + if (isNaN(label) === false && label !== '') { + if (fixedDecimals !== true) { + label = dynamicDecimals(labelToPrint) + } + label = label.toLocaleString() + if (noDecimals === true) { + label = Math.trunc(label) + } + } + + let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + + if (center === true) { + labelPoint = { + x: x - xOffset, + y: y + } + } else { + labelPoint = { + x: x, + y: y + } + } + + if (container !== undefined) { + labelPoint = container.frame.frameThisPoint(labelPoint) + } + + if (fitFunction !== undefined) { + labelPoint = fitFunction(labelPoint) + } + + browserCanvasContext.fillStyle = 'rgba(' + color + ', ' + opacity + ')' + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } diff --git a/Utilities/HiriarchyMap.js b/Utilities/HiriarchyMap.js index e27ec1614..6b37803b6 100644 --- a/Utilities/HiriarchyMap.js +++ b/Utilities/HiriarchyMap.js @@ -2,46 +2,46 @@ This function scans a node hiriatchy recursively and creates a Map by Id of all the nodes of it. */ -function getHiriarchyMap (rootNode) { - let hiriatchyMap = new Map() - evalNode(rootNode) - return hiriatchyMap +function getHiriarchyMap(rootNode) { + let hiriatchyMap = new Map() + evalNode(rootNode) + return hiriatchyMap - function evalNode (node) { - if (node === undefined) { return } + function evalNode(node) { + if (node === undefined) { return } - hiriatchyMap.set(node.id, node) + hiriatchyMap.set(node.id, node) - /* Now we go down through all this node children */ - let nodeDefinition = APP_SCHEMA_MAP.get(node.type) - if (nodeDefinition === undefined) { return } + /* Now we go down through all this node children */ + let nodeDefinition = APP_SCHEMA_MAP.get(node.type) + if (nodeDefinition === undefined) { return } - if (nodeDefinition.properties !== undefined) { - let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] + if (nodeDefinition.properties !== undefined) { + let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children. + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] - switch (property.type) { - case 'node': { - if (property.name !== previousPropertyName) { - if (node[property.name] !== undefined) { - evalNode(node[property.name]) - } - previousPropertyName = property.name + switch (property.type) { + case 'node': { + if (property.name !== previousPropertyName) { + if (node[property.name] !== undefined) { + evalNode(node[property.name]) + } + previousPropertyName = property.name + } + break + } + case 'array': { + if (node[property.name] !== undefined) { + let nodePropertyArray = node[property.name] + for (let m = 0; m < nodePropertyArray.length; m++) { + evalNode(nodePropertyArray[m]) + } + } + break + } + } } - break - } - case 'array': { - if (node[property.name] !== undefined) { - let nodePropertyArray = node[property.name] - for (let m = 0; m < nodePropertyArray.length; m++) { - evalNode(nodePropertyArray[m]) - } - } - break - } } - } } - } } diff --git a/Utilities/LoadSaveFrame.js b/Utilities/LoadSaveFrame.js index 5bda8c98b..67fecfbb0 100644 --- a/Utilities/LoadSaveFrame.js +++ b/Utilities/LoadSaveFrame.js @@ -1,24 +1,24 @@ -function saveFrame (payload, frame) { - payload.frame = { - position: { - x: frame.position.x, - y: frame.position.y - }, - width: frame.width, - height: frame.height, - radius: frame.radius - } +function saveFrame(payload, frame) { + payload.frame = { + position: { + x: frame.position.x, + y: frame.position.y + }, + width: frame.width, + height: frame.height, + radius: frame.radius + } } -function loadFrame (payload, frame) { - if (payload.node.savedPayload !== undefined) { - if (payload.node.savedPayload.frame !== undefined) { - frame.position.x = payload.node.savedPayload.frame.position.x - frame.position.y = payload.node.savedPayload.frame.position.y - frame.width = payload.node.savedPayload.frame.width - frame.height = payload.node.savedPayload.frame.height - frame.radius = payload.node.savedPayload.frame.radius - payload.node.savedPayload.frame = undefined +function loadFrame(payload, frame) { + if (payload.node.savedPayload !== undefined) { + if (payload.node.savedPayload.frame !== undefined) { + frame.position.x = payload.node.savedPayload.frame.position.x + frame.position.y = payload.node.savedPayload.frame.position.y + frame.width = payload.node.savedPayload.frame.width + frame.height = payload.node.savedPayload.frame.height + frame.radius = payload.node.savedPayload.frame.radius + payload.node.savedPayload.frame = undefined + } } - } } diff --git a/Utilities/NodeConfig.js b/Utilities/NodeConfig.js index 482e1ae3e..f33cc2754 100644 --- a/Utilities/NodeConfig.js +++ b/Utilities/NodeConfig.js @@ -1,18 +1,18 @@ -function savePropertyAtNodeConfig (payload, propertyName, value) { - try { - let config = JSON.parse(payload.node.config) - config[propertyName] = value - payload.node.config = JSON.stringify(config, null, 4) - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } +function savePropertyAtNodeConfig(payload, propertyName, value) { + try { + let config = JSON.parse(payload.node.config) + config[propertyName] = value + payload.node.config = JSON.stringify(config, null, 4) + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } } -function loadPropertyFromNodeConfig (payload, propertyName) { - try { - let config = JSON.parse(payload.node.config) - return config[propertyName] - } catch (err) { - // we ignore errors here since most likely they will be parsing errors. - } +function loadPropertyFromNodeConfig(payload, propertyName) { + try { + let config = JSON.parse(payload.node.config) + return config[propertyName] + } catch (err) { + // we ignore errors here since most likely they will be parsing errors. + } } diff --git a/VideoRecorder.js b/VideoRecorder.js index f222a8358..551db0ef7 100644 --- a/VideoRecorder.js +++ b/VideoRecorder.js @@ -1,218 +1,218 @@ -function newVideoRecorder () { - let thisObject = { - recordCanvas: recordCanvas, - physics: physics - } - let lastAction - let wheelAnimationCounter = 0 - let lastWheelPointerIcon - return thisObject - - function physics () { - wheelAnimationCounter-- - if (wheelAnimationCounter < 0) { - wheelAnimationCounter = 0 +function newVideoRecorder() { + let thisObject = { + recordCanvas: recordCanvas, + physics: physics } - } + let lastAction + let wheelAnimationCounter = 0 + let lastWheelPointerIcon + return thisObject - function recordCanvas () { - { - const DISTANCE_BETWEEN_ICONS = 35 - const ICON_SIZES = 50 - - let mousePointerIcon = canvas.designSpace.iconCollection.get('mouse-pointer') - let draggingIcon = canvas.designSpace.iconCollection.get('hand-drag') - - let leftClickIcon = canvas.designSpace.iconCollection.get('mouse-left-click') - let rightClickIcon = canvas.designSpace.iconCollection.get('mouse-right-click') - let wheelClickIcon = canvas.designSpace.iconCollection.get('mouse-wheel-click') - - let imagePosition - let buttonPressedIcon - - if (canvas.mouse.action === 'key down' && lastAction === 'dragging') { - canvas.mouse.action = 'dragging' - } - switch (canvas.mouse.action) { - case 'moving': { - pointerIcon = mousePointerIcon - break + function physics() { + wheelAnimationCounter-- + if (wheelAnimationCounter < 0) { + wheelAnimationCounter = 0 + } + } + + function recordCanvas() { + { + const DISTANCE_BETWEEN_ICONS = 35 + const ICON_SIZES = 50 + + let mousePointerIcon = canvas.designSpace.iconCollection.get('mouse-pointer') + let draggingIcon = canvas.designSpace.iconCollection.get('hand-drag') + + let leftClickIcon = canvas.designSpace.iconCollection.get('mouse-left-click') + let rightClickIcon = canvas.designSpace.iconCollection.get('mouse-right-click') + let wheelClickIcon = canvas.designSpace.iconCollection.get('mouse-wheel-click') + + let imagePosition + let buttonPressedIcon + + if (canvas.mouse.action === 'key down' && lastAction === 'dragging') { + canvas.mouse.action = 'dragging' + } + switch (canvas.mouse.action) { + case 'moving': { + pointerIcon = mousePointerIcon + break + } + case 'dragging': { + pointerIcon = draggingIcon + break + } + case 'wheel': { + wheelAnimationCounter = 25 + if (canvas.mouse.event.delta > 0) { + pointerIcon = canvas.designSpace.iconCollection.get('mouse-wheel-up') + lastWheelPointerIcon = pointerIcon + } else { + pointerIcon = canvas.designSpace.iconCollection.get('mouse-wheel-down') + lastWheelPointerIcon = pointerIcon + } + + break + } + case 'key down': { + if (wheelAnimationCounter > 0) { + pointerIcon = lastWheelPointerIcon + } else { + pointerIcon = mousePointerIcon + } + let key = canvas.mouse.event.key + if (key === undefined) { break } + switch (key.toLowerCase()) { + case 'Escape': + { + pointerIcon = canvas.designSpace.iconCollection.get('key-m') + break + } + case 'm': + { + pointerIcon = canvas.designSpace.iconCollection.get('key-m') + break + } + case 'a': + { + pointerIcon = canvas.designSpace.iconCollection.get('key-a') + break + } + case 'r': + { + pointerIcon = canvas.designSpace.iconCollection.get('key-r') + break + } + case 'c': + { + pointerIcon = canvas.designSpace.iconCollection.get('key-r') + break + } + } + break + } + case 'key up': { + pointerIcon = mousePointerIcon + break + } + } + + lastAction = canvas.mouse.action + + imagePosition = { + x: canvas.mouse.position.x, + y: canvas.mouse.position.y + } + drawMousePointer(pointerIcon, imagePosition, ICON_SIZES) + + switch (canvas.mouse.event.buttons) { + case 0: { + buttonPressedIcon = undefined + break + } + case 1: { + buttonPressedIcon = leftClickIcon + break + } + case 2: { + buttonPressedIcon = rightClickIcon + break + } + case 3: { + buttonPressedIcon = undefined + break + } + case 4: { + buttonPressedIcon = wheelClickIcon + break + } + } + + let firstRow = DISTANCE_BETWEEN_ICONS * 1 + ICON_SIZES * 1 + let secondRow = DISTANCE_BETWEEN_ICONS * 1 + ICON_SIZES * 2 + let icon + + imagePosition = { + x: canvas.mouse.position.x + DISTANCE_BETWEEN_ICONS * 2, + y: canvas.mouse.position.y + } + drawMousePointer(buttonPressedIcon, imagePosition, ICON_SIZES) + + if (canvas.mouse.event.shiftKey === true) { + icon = canvas.designSpace.iconCollection.get('key-shift') + imagePosition = { + x: canvas.mouse.position.x - DISTANCE_BETWEEN_ICONS * 3, + y: canvas.mouse.position.y + firstRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + if (canvas.mouse.event.ctrlKey === true || canvas.mouse.event.metaKey === true) { + icon = canvas.designSpace.iconCollection.get('key-ctrl') + imagePosition = { + x: canvas.mouse.position.x - DISTANCE_BETWEEN_ICONS * 3, + y: canvas.mouse.position.y + secondRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + if (canvas.mouse.event.altKey === true) { + icon = canvas.designSpace.iconCollection.get('key-alt') + imagePosition = { + x: canvas.mouse.position.x + DISTANCE_BETWEEN_ICONS * 3 + ICON_SIZES * 0, + y: canvas.mouse.position.y + secondRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + if (canvas.mouse.event.code === 'ArrowUp') { + icon = canvas.designSpace.iconCollection.get('key-up') + imagePosition = { + x: canvas.mouse.position.x - 0, + y: canvas.mouse.position.y + firstRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + if (canvas.mouse.event.code === 'ArrowDown') { + icon = canvas.designSpace.iconCollection.get('key-down') + imagePosition = { + x: canvas.mouse.position.x - 0, + y: canvas.mouse.position.y + secondRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + if (canvas.mouse.event.code === 'ArrowLeft') { + icon = canvas.designSpace.iconCollection.get('key-left') + imagePosition = { + x: canvas.mouse.position.x - DISTANCE_BETWEEN_ICONS * 0 - ICON_SIZES * 1, + y: canvas.mouse.position.y + secondRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + if (canvas.mouse.event.code === 'ArrowRight') { + icon = canvas.designSpace.iconCollection.get('key-right') + imagePosition = { + x: canvas.mouse.position.x + DISTANCE_BETWEEN_ICONS * 0 + ICON_SIZES * 1, + y: canvas.mouse.position.y + secondRow + } + drawMousePointer(icon, imagePosition, ICON_SIZES) + } + + function drawMousePointer(icon, imagePosition, imageSize) { + if (icon !== undefined) { + if (icon.canDrawIcon === true) { + browserCanvasContext.drawImage( + icon, imagePosition.x, + imagePosition.y, + imageSize, + imageSize) + } + } + } + mediaRecorder.capture(browserCanvas) } - case 'dragging': { - pointerIcon = draggingIcon - break - } - case 'wheel': { - wheelAnimationCounter = 25 - if (canvas.mouse.event.delta > 0) { - pointerIcon = canvas.designSpace.iconCollection.get('mouse-wheel-up') - lastWheelPointerIcon = pointerIcon - } else { - pointerIcon = canvas.designSpace.iconCollection.get('mouse-wheel-down') - lastWheelPointerIcon = pointerIcon - } - - break - } - case 'key down': { - if (wheelAnimationCounter > 0) { - pointerIcon = lastWheelPointerIcon - } else { - pointerIcon = mousePointerIcon - } - let key = canvas.mouse.event.key - if (key === undefined) { break } - switch (key.toLowerCase()) { - case 'Escape': - { - pointerIcon = canvas.designSpace.iconCollection.get('key-m') - break - } - case 'm': - { - pointerIcon = canvas.designSpace.iconCollection.get('key-m') - break - } - case 'a': - { - pointerIcon = canvas.designSpace.iconCollection.get('key-a') - break - } - case 'r': - { - pointerIcon = canvas.designSpace.iconCollection.get('key-r') - break - } - case 'c': - { - pointerIcon = canvas.designSpace.iconCollection.get('key-r') - break - } - } - break - } - case 'key up': { - pointerIcon = mousePointerIcon - break - } - } - - lastAction = canvas.mouse.action - - imagePosition = { - x: canvas.mouse.position.x, - y: canvas.mouse.position.y - } - drawMousePointer(pointerIcon, imagePosition, ICON_SIZES) - - switch (canvas.mouse.event.buttons) { - case 0: { - buttonPressedIcon = undefined - break - } - case 1: { - buttonPressedIcon = leftClickIcon - break - } - case 2: { - buttonPressedIcon = rightClickIcon - break - } - case 3: { - buttonPressedIcon = undefined - break - } - case 4: { - buttonPressedIcon = wheelClickIcon - break - } - } - - let firstRow = DISTANCE_BETWEEN_ICONS * 1 + ICON_SIZES * 1 - let secondRow = DISTANCE_BETWEEN_ICONS * 1 + ICON_SIZES * 2 - let icon - - imagePosition = { - x: canvas.mouse.position.x + DISTANCE_BETWEEN_ICONS * 2, - y: canvas.mouse.position.y - } - drawMousePointer(buttonPressedIcon, imagePosition, ICON_SIZES) - - if (canvas.mouse.event.shiftKey === true) { - icon = canvas.designSpace.iconCollection.get('key-shift') - imagePosition = { - x: canvas.mouse.position.x - DISTANCE_BETWEEN_ICONS * 3, - y: canvas.mouse.position.y + firstRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - if (canvas.mouse.event.ctrlKey === true || canvas.mouse.event.metaKey === true) { - icon = canvas.designSpace.iconCollection.get('key-ctrl') - imagePosition = { - x: canvas.mouse.position.x - DISTANCE_BETWEEN_ICONS * 3, - y: canvas.mouse.position.y + secondRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - if (canvas.mouse.event.altKey === true) { - icon = canvas.designSpace.iconCollection.get('key-alt') - imagePosition = { - x: canvas.mouse.position.x + DISTANCE_BETWEEN_ICONS * 3 + ICON_SIZES * 0, - y: canvas.mouse.position.y + secondRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - if (canvas.mouse.event.code === 'ArrowUp') { - icon = canvas.designSpace.iconCollection.get('key-up') - imagePosition = { - x: canvas.mouse.position.x - 0, - y: canvas.mouse.position.y + firstRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - if (canvas.mouse.event.code === 'ArrowDown') { - icon = canvas.designSpace.iconCollection.get('key-down') - imagePosition = { - x: canvas.mouse.position.x - 0, - y: canvas.mouse.position.y + secondRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - if (canvas.mouse.event.code === 'ArrowLeft') { - icon = canvas.designSpace.iconCollection.get('key-left') - imagePosition = { - x: canvas.mouse.position.x - DISTANCE_BETWEEN_ICONS * 0 - ICON_SIZES * 1, - y: canvas.mouse.position.y + secondRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - if (canvas.mouse.event.code === 'ArrowRight') { - icon = canvas.designSpace.iconCollection.get('key-right') - imagePosition = { - x: canvas.mouse.position.x + DISTANCE_BETWEEN_ICONS * 0 + ICON_SIZES * 1, - y: canvas.mouse.position.y + secondRow - } - drawMousePointer(icon, imagePosition, ICON_SIZES) - } - - function drawMousePointer (icon, imagePosition, imageSize) { - if (icon !== undefined) { - if (icon.canDrawIcon === true) { - browserCanvasContext.drawImage( - icon, imagePosition.x, - imagePosition.y, - imageSize, - imageSize) - } - } - } - mediaRecorder.capture(browserCanvas) } - } } diff --git a/WebDebugLog.js b/WebDebugLog.js index 6a758304e..2a6bc1af1 100644 --- a/WebDebugLog.js +++ b/WebDebugLog.js @@ -1,21 +1,21 @@ - function newWebDebugLog () { - try { - let thisObject = { - write: write, - fileName: 'undefined' - } +function newWebDebugLog() { + try { + let thisObject = { + write: write, + fileName: 'undefined' + } - return thisObject + return thisObject - function write (pText) { - console.log(spacePad(thisObject.fileName, 50) + ' : ' + pText) + function write(pText) { + console.log(spacePad(thisObject.fileName, 50) + ' : ' + pText) - function spacePad (str, max) { - str = str.toString() - return str.length < max ? spacePad(' ' + str, max) : str - } - } - } catch (err) { - console.log(spacePad(MODULE_NAME, 50) + ' : ' + '[ERROR] WebDebugLog --> err = ' + err.stack) - } - } + function spacePad(str, max) { + str = str.toString() + return str.length < max ? spacePad(' ' + str, max) : str + } + } + } catch (err) { + console.log(spacePad(MODULE_NAME, 50) + ' : ' + '[ERROR] WebDebugLog --> err = ' + err.stack) + } +} From 8cb6184a0e2c4f4f3ba62c939e5a5f539206c079 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 30 Jul 2020 11:42:49 +0200 Subject: [PATCH 005/192] Announcement Formula --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 4 ++-- Plotting/Plotter.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 1dcf1c978..4be088b43 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -26,7 +26,7 @@ function newSessionFunctions() { 'Exchange Account Asset->Asset->' + 'Trading Strategy->' + 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + - 'Announcement->Formula->' + + 'Announcement->Announcement Formula->' + 'Open Stage->Initial Definition->Open Execution->' + 'Position Size->Position Rate->Formula->' + 'Initial Stop->Initial Take Profit->' + @@ -35,7 +35,7 @@ function newSessionFunctions() { 'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' + 'Situation->Condition->Javascript Code->' + 'Close Stage->Close Execution->' + - 'Announcement->Formula->' + + 'Announcement->Announcement Formula->' + 'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' + 'Create Order Event->Cancel Order Event->' + 'Position Size->Position Rate->Formula->' + diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index 6b96b66d2..ff0533e40 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -153,13 +153,13 @@ function newPlotter() { let minPositionPoint = { x: event.x, - y: event.y + 2 + y: event.y + 4 } minUserPositionRate = getRateFromPointAtBrowserCanvas(minPositionPoint, thisObject.container, coordinateSystem) let maxPositionPoint = { x: event.x, - y: event.y - 2 + y: event.y - 4 } maxUserPositionRate = getRateFromPointAtBrowserCanvas(maxPositionPoint, thisObject.container, coordinateSystem) } From f99eecac08c1de3785450c983a42127a8ceff3c4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 30 Jul 2020 12:00:00 +0200 Subject: [PATCH 006/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 4be088b43..477ba1cb6 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -70,7 +70,7 @@ function newSessionFunctions() { 'Formula->' + 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + 'Market Order->Limit Order->' + - 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Size->Exit Type->Status->Order Name->Algorithm Name->Situation Name->' + + 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Size->Exit Type->Status->Order Name->Algorithm Name->Situation Name->Lock->' + 'Order Counters->Periods->' + 'Order Statistics->Size Filled->Percentage Filled->Amount Received->Actual Rate->Fees Paid->Days->User Defined Statistic->' From e2fa1d437fd3c18d0f0e28afafcbb04a1bcccce0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 1 Aug 2020 11:04:44 +0200 Subject: [PATCH 007/192] Changes in Trading Engine Data Structure --- .../FunctionLibraries/SessionFunctions.js | 21 +++++++++++-------- Spaces/DesignSpace.js | 7 ++++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 477ba1cb6..bea56cf46 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -28,7 +28,7 @@ function newSessionFunctions() { 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + 'Announcement->Announcement Formula->' + 'Open Stage->Initial Definition->Open Execution->' + - 'Position Size->Position Rate->Formula->' + + 'Position Size In Base Asset->Position Size In Quoted Asset->Position Rate->Formula->' + 'Initial Stop->Initial Take Profit->' + 'Manage Stage->' + 'Managed Stop Loss->Managed Take Profit->' + @@ -38,7 +38,7 @@ function newSessionFunctions() { 'Announcement->Announcement Formula->' + 'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' + 'Create Order Event->Cancel Order Event->' + - 'Position Size->Position Rate->Formula->' + + 'Size In Base Asset->Size In Quoted Asset->Position Rate->Formula->' + 'Situation->Condition->Javascript Code->' + 'Market Order->Limit Order->' + 'Simulated Exchange Events->Simulated Partial Fill->Simulated Actual Rate->Simulated Fees Paid->Formula->' @@ -49,9 +49,9 @@ function newSessionFunctions() { 'Trading Engine->' + 'Dynamic Indicators->Indicator Function->Formula->' + 'Episode->Current->Last->Previous->' + - 'Episode Counters->Episode Statistics->' + + 'Episode Base Asset->Episode Quoted Asset->Episode Counters->Episode Statistics->' + 'Periods->Strategies->Positions->Orders->Hits->Fails->' + - 'Profit Loss->Hit Ratio->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + + 'Profit Loss->Hit Ratio->Hit Fail->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + 'Formula->' + 'Candle->' + 'Begin->End->Open->Close->Min->Max->Index->' + @@ -59,20 +59,23 @@ function newSessionFunctions() { 'Distance To Event->' + 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + 'Strategy->' + - 'Serial Number->Identifier->Begin->End->Strategy Name->Index->Trigger Stage Status->Open Stage Status->Manage Stage Status->Close Stage Status->Status->Begin Rate->End Rate->Situation Name->' + + 'Serial Number->Identifier->Begin->End->Strategy Name->Index->Status->Begin Rate->End Rate->Situation Name->' + 'Strategy Counters->Periods->' + 'Position->' + - 'Serial Number->Identifier->Begin->End->Rate->Size->Open Stage Orders Size->Open Stage Filled Size->Close Stage Orders Size->Close Stage Filled Size->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + + 'Serial Number->Identifier->Begin->End->Rate->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + 'Stop Loss->Stop Loss Stage->Stop Loss Phase->' + 'Take Profit->Take Profit Stage->Take Profit Phase->' + 'Position Counters->Periods->' + - 'Position Statistics->Profit Loss->Days->ROI->Hit Fail->User Defined Statistic->' + + 'Position Statistics->Days->User Defined Statistic->' + + 'Position Base Asset->Position Quoted Asset->Size->Profit Loss->ROI->Hit Fail->' + 'Formula->' + 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + 'Market Order->Limit Order->' + - 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Size->Exit Type->Status->Order Name->Algorithm Name->Situation Name->Lock->' + + 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Exit Type->Status->Order Name->Algorithm Name->Situation Name->Lock->' + 'Order Counters->Periods->' + - 'Order Statistics->Size Filled->Percentage Filled->Amount Received->Actual Rate->Fees Paid->Days->User Defined Statistic->' + 'Order Base Asset->Order Quoted Asset->' + + 'Size->Size Filled->Amount Received->Fees Paid->' + + 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) diff --git a/Spaces/DesignSpace.js b/Spaces/DesignSpace.js index b67ffa44b..c745e4fb9 100644 --- a/Spaces/DesignSpace.js +++ b/Spaces/DesignSpace.js @@ -291,7 +291,12 @@ function newDesignSpace() { 'market-order', 'limit-order', 'execution-algorithm', - 'cancel-order' + 'cancel-order', + 'limit-sell-order', + 'close-execution', + 'market-sell-order', + 'limit-buy-order', + 'market-buy-order' ] for (let i = 0; i < iconsNames.length; i++) { From f28f1e8940dffc10e5005938ced0a7b75f1ae4a7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 1 Aug 2020 19:36:25 +0200 Subject: [PATCH 008/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index bea56cf46..787a0db83 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -74,7 +74,7 @@ function newSessionFunctions() { 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Exit Type->Status->Order Name->Algorithm Name->Situation Name->Lock->' + 'Order Counters->Periods->' + 'Order Base Asset->Order Quoted Asset->' + - 'Size->Size Filled->Amount Received->Fees Paid->' + + 'Size->Size Filled->Fees Paid->' + 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) From 9925edfd3f5799d834a9f017ef84268ce262686b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 2 Aug 2020 20:31:55 +0200 Subject: [PATCH 009/192] Update SessionFunctions.js --- .../Workspace/FunctionLibraries/SessionFunctions.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 787a0db83..20f46aa3a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -63,8 +63,8 @@ function newSessionFunctions() { 'Strategy Counters->Periods->' + 'Position->' + 'Serial Number->Identifier->Begin->End->Rate->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + - 'Stop Loss->Stop Loss Stage->Stop Loss Phase->' + - 'Take Profit->Take Profit Stage->Take Profit Phase->' + + 'Stop Loss->Stop Loss Stage->Stop Loss Phase->Stop Loss Position->' + + 'Take Profit->Take Profit Stage->Take Profit Phase->Take Profit Position->' + 'Position Counters->Periods->' + 'Position Statistics->Days->User Defined Statistic->' + 'Position Base Asset->Position Quoted Asset->Size->Profit Loss->ROI->Hit Fail->' + @@ -75,7 +75,9 @@ function newSessionFunctions() { 'Order Counters->Periods->' + 'Order Base Asset->Order Quoted Asset->' + 'Size->Size Filled->Fees Paid->' + - 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' + 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' + + 'Strategy Trigger Stage->Strategy Open Stage->Strategy Manage Stage->Strategy Close Stage->' + + 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size->Size Filled->Fees Paid->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) From 9beab56da4c2502629071568f31c2aaeb6916b84 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 3 Aug 2020 09:56:18 +0200 Subject: [PATCH 010/192] Update RecordValues.js --- Plotting/RecordValues.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Plotting/RecordValues.js b/Plotting/RecordValues.js index 486e81e4c..20917353d 100644 --- a/Plotting/RecordValues.js +++ b/Plotting/RecordValues.js @@ -75,7 +75,17 @@ function newRecordValues() { let property = productDefinition.record.properties[i] let value = currentRecord[property.config.codeName] let targetNode = propertyTargetNodeMap.get(property.id) - applyValue(targetNode[property.config.codeName], value) + /* + If the codeName of the Record Property can not match the name of the property at + the target node, the user can explicitly specify the property name at the configuration, + and in those cases we need to use that. This happens when there are many Record Properties + pointing to the same property at the Target Node. + */ + if (property.config.childProperty !== undefined) { + applyValue(targetNode[property.config.childProperty], value) + } else { + applyValue(targetNode[property.config.codeName], value) + } } } From 793f5cb4e5d4155b5012944266e44fa476b7e5ee Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 4 Aug 2020 18:33:00 +0200 Subject: [PATCH 011/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 20f46aa3a..1bc117e40 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -77,7 +77,7 @@ function newSessionFunctions() { 'Size->Size Filled->Fees Paid->' + 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' + 'Strategy Trigger Stage->Strategy Open Stage->Strategy Manage Stage->Strategy Close Stage->' + - 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size->Size Filled->Fees Paid->' + 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) From dc12d47c1a82504525a21f035cf45b3fed3a2c91 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 5 Aug 2020 20:30:38 +0200 Subject: [PATCH 012/192] Update SessionFunctions.js --- .../Workspace/FunctionLibraries/SessionFunctions.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 1bc117e40..f2c4c58e3 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -27,15 +27,16 @@ function newSessionFunctions() { 'Trading Strategy->' + 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + 'Announcement->Announcement Formula->' + - 'Open Stage->Initial Definition->Open Execution->' + - 'Position Size In Base Asset->Position Size In Quoted Asset->Position Rate->Formula->' + - 'Initial Stop->Initial Take Profit->' + + 'Open Stage->' + + 'Initial Definition->Initial Stop->Initial Take Profit->' + 'Manage Stage->' + 'Managed Stop Loss->Managed Take Profit->' + 'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' + 'Situation->Condition->Javascript Code->' + - 'Close Stage->Close Execution->' + + 'Close Stage->' + + 'Initial Targets->Target Size In Base Asset->Target Size In Quoted Asset->Target Rate->Formula->' + 'Announcement->Announcement Formula->' + + 'Open Execution->Close Execution->' + 'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' + 'Create Order Event->Cancel Order Event->' + 'Size In Base Asset->Size In Quoted Asset->Position Rate->Formula->' + @@ -62,12 +63,12 @@ function newSessionFunctions() { 'Serial Number->Identifier->Begin->End->Strategy Name->Index->Status->Begin Rate->End Rate->Situation Name->' + 'Strategy Counters->Periods->' + 'Position->' + - 'Serial Number->Identifier->Begin->End->Rate->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + + 'Serial Number->Identifier->Begin->End->Entry Target Rate->Exit Target Rate->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + 'Stop Loss->Stop Loss Stage->Stop Loss Phase->Stop Loss Position->' + 'Take Profit->Take Profit Stage->Take Profit Phase->Take Profit Position->' + 'Position Counters->Periods->' + 'Position Statistics->Days->User Defined Statistic->' + - 'Position Base Asset->Position Quoted Asset->Size->Profit Loss->ROI->Hit Fail->' + + 'Position Base Asset->Position Quoted Asset->Entry Target Size->Exit Target Size->Profit Loss->ROI->Hit Fail->' + 'Formula->' + 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + 'Market Order->Limit Order->' + From 8ba2c0443ffb222f7835e6d77a4746f6463dd1c9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 6 Aug 2020 14:34:35 +0200 Subject: [PATCH 013/192] animation improvement --- FloatingSpace/FloatingObject.js | 17 +++++++++++------ FloatingSpace/UiObject.js | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 7d15a19f3..79bb44217 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -459,9 +459,9 @@ function newFloatingObject() { function thisObjectPhysics() { // The radius also have a target. - let ANIMATION_STEP = Math.abs(thisObject.targetRadius - thisObject.rawRadius) / 5 + let ANIMATION_STEP = Math.abs(thisObject.targetRadius - thisObject.rawRadius) / 2 - if (ANIMATION_STEP === 0) { ANIMATION_STEP = 10 } + if (ANIMATION_STEP === 0) { ANIMATION_STEP = thisObject.rawRadius } if (Math.abs(thisObject.container.frame.radius - thisObject.targetRadius) >= ANIMATION_STEP) { if (thisObject.container.frame.radius < thisObject.targetRadius) { @@ -471,26 +471,30 @@ function newFloatingObject() { } thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) + } else { + thisObject.container.frame.radius = thisObject.targetRadius } // The imageSize also have a target. - if (Math.abs(thisObject.currentImageSize - thisObject.targetImageSize) >= ANIMATION_STEP) { if (thisObject.currentImageSize < thisObject.targetImageSize) { thisObject.currentImageSize = thisObject.currentImageSize + ANIMATION_STEP } else { thisObject.currentImageSize = thisObject.currentImageSize - ANIMATION_STEP } + } else { + thisObject.currentImageSize = thisObject.targetImageSize } // The fontSize also have a target. - if (Math.abs(thisObject.currentFontSize - thisObject.targetFontSize) >= ANIMATION_STEP / 10) { if (thisObject.currentFontSize < thisObject.targetFontSize) { thisObject.currentFontSize = thisObject.currentFontSize + ANIMATION_STEP / 10 } else { thisObject.currentFontSize = thisObject.currentFontSize - ANIMATION_STEP / 10 } + } else { + thisObject.currentFontSize = thisObject.targetFontSize } if (Math.abs(thisObject.currentHierarchyRing - thisObject.targetHierarchyRing) >= ANIMATION_STEP) { @@ -499,10 +503,11 @@ function newFloatingObject() { } else { thisObject.currentHierarchyRing = thisObject.currentHierarchyRing - ANIMATION_STEP } + } else { + thisObject.currentHierarchyRing = thisObject.targetHierarchyRing } /* Floating object position in screen coordinates */ - thisObject.payload.position.x = thisObject.container.frame.position.x thisObject.payload.position.y = thisObject.container.frame.position.y } @@ -616,7 +621,7 @@ function newFloatingObject() { thisObject.rawRadius = radius thisObject.targetRadius = radius - thisObject.container.frame.radius = radius / 5 + thisObject.container.frame.radius = radius thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index be7190251..8178a2802 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1323,7 +1323,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius + let radius = thisObject.payload.floatingObject.container.frame.radius /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize From ce25b99f18ec50e7c5fe5a98900acd42a8a4f253 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 6 Aug 2020 23:17:30 +0200 Subject: [PATCH 014/192] Animation Fixes --- .../FunctionLibraries/SessionFunctions.js | 3 ++- FloatingSpace/CircularMenuItem.js | 20 +++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index f2c4c58e3..73614a847 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -68,7 +68,8 @@ function newSessionFunctions() { 'Take Profit->Take Profit Stage->Take Profit Phase->Take Profit Position->' + 'Position Counters->Periods->' + 'Position Statistics->Days->User Defined Statistic->' + - 'Position Base Asset->Position Quoted Asset->Entry Target Size->Exit Target Size->Profit Loss->ROI->Hit Fail->' + + 'Position Base Asset->Position Quoted Asset->Entry Target Size->Exit Target Size->' + + 'Profit Loss->ROI->Hit Fail->' + 'Formula->' + 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + 'Market Order->Limit Order->' + diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index dd32c595a..8985a65cb 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -267,7 +267,7 @@ function newCircularMenuItem() { function internalClick() { if (thisObject.shorcutNumber !== undefined) { let label = thisObject.payload.node.name + ' ' + labelToPrint - canvas.cockpitSpace.setStatus(label, 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) + canvas.cockpitSpace.setStatus(label, 40, canvas.cockpitSpace.statusTypes.ALL_GOOD) } onMouseClick() @@ -291,16 +291,16 @@ function newCircularMenuItem() { /* The first click ask for confirmation. */ if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET) { - setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 250, STATUS_WAITING_CONFIRMATION) + setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 200, STATUS_WAITING_CONFIRMATION) return } /* A Click during confirmation executes the pre-defined action. */ if (temporaryStatus === STATUS_WAITING_CONFIRMATION || temporaryStatus === STATUS_PRIMARY_WORK_DONE) { executeAction() if (thisObject.workDoneLabel !== undefined) { - setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) } else { - setStatus('Done', UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + setStatus('Done', UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) } return } @@ -334,7 +334,7 @@ function newCircularMenuItem() { if (event !== undefined) { if (event.type === 'Secondary Action Already Executed') { - setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) return } } @@ -343,11 +343,11 @@ function newCircularMenuItem() { if (thisObject.secondaryAction === undefined) { // This means there are no more possible actions. if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { if (thisObject.workDoneLabel !== undefined) { - setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_PRIMARY_WORK_DONE) + setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_PRIMARY_WORK_DONE) } } else { if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED) + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 50, STATUS_PRIMARY_WORK_FAILED) } } } else { @@ -358,7 +358,7 @@ function newCircularMenuItem() { } } else { if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_PRIMARY_WORK_FAILED) + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 50, STATUS_PRIMARY_WORK_FAILED) } } } @@ -366,11 +366,11 @@ function newCircularMenuItem() { function onSecondaryCallBack(err) { if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { if (thisObject.secondaryWorkDoneLabel !== undefined) { - setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 100, STATUS_SECONDARY_WORK_DONE) + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) } } else { if (thisObject.secondaryWorkFailedLabel != undefined) { - setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 100, STATUS_SECONDARY_WORK_FAILED) + setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 50, STATUS_SECONDARY_WORK_FAILED) } } } From 4dc639fd1d58c5abdb7000f9607bbeee60c76ffb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 7 Aug 2020 09:21:15 +0200 Subject: [PATCH 015/192] Update SessionFunctions.js --- .../FunctionLibraries/SessionFunctions.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 73614a847..6e83a99b5 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -48,38 +48,38 @@ function newSessionFunctions() { lightingPath = '' + 'Trading Engine->' + - 'Dynamic Indicators->Indicator Function->Formula->' + - 'Episode->Current->Last->Previous->' + + 'Dynamic Indicators->Indicator Function->' + + 'Current->Last->Previous->' + + 'Episode->' + 'Episode Base Asset->Episode Quoted Asset->Episode Counters->Episode Statistics->' + - 'Periods->Strategies->Positions->Orders->Hits->Fails->' + + 'Strategies->Positions->Orders->Hits->Fails->' + 'Profit Loss->Hit Ratio->Hit Fail->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + - 'Formula->' + 'Candle->' + 'Begin->End->Open->Close->Min->Max->Index->' + 'Balance->Base Asset->Quoted Asset->' + 'Distance To Event->' + 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + 'Strategy->' + - 'Serial Number->Identifier->Begin->End->Strategy Name->Index->Status->Begin Rate->End Rate->Situation Name->' + - 'Strategy Counters->Periods->' + + 'Strategy Counters->' + 'Position->' + - 'Serial Number->Identifier->Begin->End->Entry Target Rate->Exit Target Rate->Exit Type->Status->Begin Rate->End Rate->Situation Name->' + + 'Entry Target Rate->Exit Target Rate->' + 'Stop Loss->Stop Loss Stage->Stop Loss Phase->Stop Loss Position->' + 'Take Profit->Take Profit Stage->Take Profit Phase->Take Profit Position->' + - 'Position Counters->Periods->' + + 'Position Counters->' + 'Position Statistics->Days->User Defined Statistic->' + 'Position Base Asset->Position Quoted Asset->Entry Target Size->Exit Target Size->' + 'Profit Loss->ROI->Hit Fail->' + - 'Formula->' + 'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' + 'Market Order->Limit Order->' + - 'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Exit Type->Status->Order Name->Algorithm Name->Situation Name->Lock->' + - 'Order Counters->Periods->' + + 'Exchange Id->Rate->Order Name->Algorithm Name->Lock->' + + 'Order Counters->' + 'Order Base Asset->Order Quoted Asset->' + 'Size->Size Filled->Fees Paid->' + 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' + 'Strategy Trigger Stage->Strategy Open Stage->Strategy Manage Stage->Strategy Close Stage->' + - 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->' + 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->' + + 'Serial Number->Identifier->Begin->End->Begin Rate->End Rate->Strategy Name->Status->Exit Type->' + + 'Index->Situation Name->Formula->Periods->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) From 81902ffe266da39b9f0c2c45f477616d654f324f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 8 Aug 2020 09:40:27 +0200 Subject: [PATCH 016/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 6e83a99b5..23a86e4ef 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -56,7 +56,6 @@ function newSessionFunctions() { 'Profit Loss->Hit Ratio->Hit Fail->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + 'Candle->' + 'Begin->End->Open->Close->Min->Max->Index->' + - 'Balance->Base Asset->Quoted Asset->' + 'Distance To Event->' + 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + 'Strategy->' + @@ -79,6 +78,7 @@ function newSessionFunctions() { 'Strategy Trigger Stage->Strategy Open Stage->Strategy Manage Stage->Strategy Close Stage->' + 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->' + 'Serial Number->Identifier->Begin->End->Begin Rate->End Rate->Strategy Name->Status->Exit Type->' + + 'Balance->Begin Balance->End Balance->Base Asset->Quoted Asset->' + 'Index->Situation Name->Formula->Periods->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) From d755487063149c02219b99b25cc5235d914197b5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 8 Aug 2020 12:26:08 +0200 Subject: [PATCH 017/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 23a86e4ef..59e6e8fc9 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -78,7 +78,7 @@ function newSessionFunctions() { 'Strategy Trigger Stage->Strategy Open Stage->Strategy Manage Stage->Strategy Close Stage->' + 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->' + 'Serial Number->Identifier->Begin->End->Begin Rate->End Rate->Strategy Name->Status->Exit Type->' + - 'Balance->Begin Balance->End Balance->Base Asset->Quoted Asset->' + + 'Balance->Begin Balance->End Balance->' + 'Index->Situation Name->Formula->Periods->' let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) From c6ee916cc77fc4168e1de6cc80e4bc6c1df193a4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 9 Aug 2020 20:04:50 +0200 Subject: [PATCH 018/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 59e6e8fc9..caccdb858 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -38,6 +38,7 @@ function newSessionFunctions() { 'Announcement->Announcement Formula->' + 'Open Execution->Close Execution->' + 'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' + + 'Order Rate->Formula->' + 'Create Order Event->Cancel Order Event->' + 'Size In Base Asset->Size In Quoted Asset->Position Rate->Formula->' + 'Situation->Condition->Javascript Code->' + From d86a4862ca1c0e86880401d9ebe19022c2437400 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 9 Aug 2020 21:13:47 +0200 Subject: [PATCH 019/192] Bug Fixed --- Plotting/Plotter.js | 10 ++++++++++ Plotting/RecordValues.js | 19 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index ff0533e40..128025d10 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -282,6 +282,16 @@ function newPlotter() { } } + if (productDefinition.config.nodePathType === 'array') { + /* + When we have an array configuration, we know that the last field of the record + contains the array index, which is needed to correctly plot this data. Since + this index is not part of the product definition, we will restore its value in + this way: + */ + record.index = dataFile[i][recordDefinition.properties.length] + } + if ( (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) && (record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x) diff --git a/Plotting/RecordValues.js b/Plotting/RecordValues.js index 20917353d..931e988a8 100644 --- a/Plotting/RecordValues.js +++ b/Plotting/RecordValues.js @@ -59,11 +59,15 @@ function newRecordValues() { function scanProperties(productRootNode, index) { for (let i = 0; i < productDefinition.record.properties.length; i++) { let property = productDefinition.record.properties[i] + let key = property.id + if (index !== undefined) { + key = property.id + '-' + index + } if (property.config.nodePath !== undefined) { let propertyRoot = eval(property.config.nodePath) - propertyTargetNodeMap.set(property.id, propertyRoot) + propertyTargetNodeMap.set(key, propertyRoot) } else { - propertyTargetNodeMap.set(property.id, productRootNode) + propertyTargetNodeMap.set(key, productRootNode) } } } @@ -74,7 +78,16 @@ function newRecordValues() { for (let i = 0; i < productDefinition.record.properties.length; i++) { let property = productDefinition.record.properties[i] let value = currentRecord[property.config.codeName] - let targetNode = propertyTargetNodeMap.get(property.id) + let key = property.id + if (productDefinition.config.nodePathType === 'array') { + /* + When we have an array configuration, in this case we will use the index + property that was injected into the record in order to build the key to + get the node where we have to send the value. + */ + key = property.id + '-' + currentRecord.index + } + let targetNode = propertyTargetNodeMap.get(key) /* If the codeName of the Record Property can not match the name of the property at the target node, the user can explicitly specify the property name at the configuration, From f6ab7057183f443c3e1578a5ac32037549e06eba Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 10 Aug 2020 13:48:55 +0200 Subject: [PATCH 020/192] Update Plotter.js --- Plotting/Plotter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index 128025d10..3ee380ac9 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -293,7 +293,7 @@ function newPlotter() { } if ( - (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) && + (record.begin >= farLeftDate.valueOf() || record.end <= farRightDate.valueOf()) && (record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x) ) { record.previous = previous From 93ede405909f8808c7cffea04fd9ea42abfb2379 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 10 Aug 2020 16:09:05 +0200 Subject: [PATCH 021/192] Update Plotter.js --- Plotting/Plotter.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index 3ee380ac9..acb4aaf2c 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -300,10 +300,8 @@ function newPlotter() { jsonifiedArray.push(record) previous = record - if (record.begin === undefined || record.end === undefined) { console.log('Could not find the property begin or end which are needed for the plotter to work.') } - if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) { - thisObject.currentRecord = record - thisObject.container.eventHandler.raiseEvent('Current Record Changed', thisObject.currentRecord) + if (record.begin === undefined || record.end === undefined) { + console.log('Could not find the property begin or end which are needed for the plotter to work. productDefinition.config.codeName = ' + productDefinition.config.codeName) } } } From db226404e95d009226a303ad8c6f6b2318bc02e3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 10 Aug 2020 18:56:31 +0200 Subject: [PATCH 022/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index caccdb858..a5abfd14f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -55,7 +55,7 @@ function newSessionFunctions() { 'Episode Base Asset->Episode Quoted Asset->Episode Counters->Episode Statistics->' + 'Strategies->Positions->Orders->Hits->Fails->' + 'Profit Loss->Hit Ratio->Hit Fail->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + - 'Candle->' + + 'Candle->Cycle->' + 'Begin->End->Open->Close->Min->Max->Index->' + 'Distance To Event->' + 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + From 7ee43f848c1fedcdf8b65473cddd03ac76e7959a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 13 Aug 2020 13:18:47 +0200 Subject: [PATCH 023/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index a5abfd14f..ac1f65eed 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -77,7 +77,7 @@ function newSessionFunctions() { 'Size->Size Filled->Fees Paid->' + 'Order Statistics->Percentage Filled->Actual Rate->Days->User Defined Statistic->' + 'Strategy Trigger Stage->Strategy Open Stage->Strategy Manage Stage->Strategy Close Stage->' + - 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->' + + 'Begin->End->Exit Type->Status->Begin Rate->End Rate->Stage Base Asset->Stage Quoted Asset->Size Placed->Target Size->Size Filled->Fees Paid->Stage Defined In->' + 'Serial Number->Identifier->Begin->End->Begin Rate->End Rate->Strategy Name->Status->Exit Type->' + 'Balance->Begin Balance->End Balance->' + 'Index->Situation Name->Formula->Periods->' From 3dd058f98cb77946fc5dfde0b659ecac3dfa076a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 13 Aug 2020 14:59:09 +0200 Subject: [PATCH 024/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index ac1f65eed..687671f11 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -28,7 +28,6 @@ function newSessionFunctions() { 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + 'Announcement->Announcement Formula->' + 'Open Stage->' + - 'Initial Definition->Initial Stop->Initial Take Profit->' + 'Manage Stage->' + 'Managed Stop Loss->Managed Take Profit->' + 'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' + @@ -63,8 +62,8 @@ function newSessionFunctions() { 'Strategy Counters->' + 'Position->' + 'Entry Target Rate->Exit Target Rate->' + - 'Stop Loss->Stop Loss Stage->Stop Loss Phase->Stop Loss Position->' + - 'Take Profit->Take Profit Stage->Take Profit Phase->Take Profit Position->' + + 'Stop Loss->Stop Loss Phase->Stop Loss Position->' + + 'Take Profit->Take Profit Phase->Take Profit Position->' + 'Position Counters->' + 'Position Statistics->Days->User Defined Statistic->' + 'Position Base Asset->Position Quoted Asset->Entry Target Size->Exit Target Size->' + From 7765c989ed5373a4be16c81fb44f3907e47fe51b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 14 Aug 2020 14:06:57 +0200 Subject: [PATCH 025/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 687671f11..2db538eef 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -53,7 +53,7 @@ function newSessionFunctions() { 'Episode->' + 'Episode Base Asset->Episode Quoted Asset->Episode Counters->Episode Statistics->' + 'Strategies->Positions->Orders->Hits->Fails->' + - 'Profit Loss->Hit Ratio->Hit Fail->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' + + 'Profit Loss->Hit Ratio->Hit Fail->Days->ROI->Annualized Rate Of Return->User Defined Statistic->' + 'Candle->Cycle->' + 'Begin->End->Open->Close->Min->Max->Index->' + 'Distance To Event->' + From 066bb358c03ac9022a74552f57fed24ea0e09b52 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 15 Aug 2020 11:14:55 +0200 Subject: [PATCH 026/192] Update Plotter.js --- Plotting/Plotter.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index acb4aaf2c..f2fdccf6c 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -94,6 +94,7 @@ function newPlotter() { function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) { try { + /* Store the information received. */ marketFiles = pStorage.marketFiles[0] dailyFiles = pStorage.dailyFiles[0] @@ -423,15 +424,6 @@ function newPlotter() { currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS) } - /* Lests check if all the visible screen is going to be covered by candle-record. */ - let lowerEnd = leftDate.valueOf() - let upperEnd = rightDate.valueOf() - - if (records.length > 0) { - if (records[0].begin > lowerEnd || records[records.length - 1].end < upperEnd) { - setTimeout(recalculate, 2000) - } - } } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingDailyFiles -> err = ' + err.stack) } } @@ -897,7 +889,9 @@ function newPlotter() { } function onDragFinished() { - recalculate() + if (canvas.chartingSpace.visible === true) { + recalculate() + } } function onDisplace(event) { From 8d7fdee634f64e5e982cc43d937abd1f95b072ff Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 15 Aug 2020 13:22:45 +0200 Subject: [PATCH 027/192] Update UiObject.js --- FloatingSpace/UiObject.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 8178a2802..458101cc6 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1699,10 +1699,10 @@ function newUiObject() { if (thisObject.isOnFocus === true) { VISIBLE_RADIUS = thisObject.container.frame.radius browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 2, 0, Math.PI * 2, true) + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS * 1.2, 0, Math.PI * 2, true) browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.25)' + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.75)' browserCanvasContext.fill() } From 9b305a79de0fd635e0333452a9871f3b2acbd07c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 15 Aug 2020 13:27:28 +0200 Subject: [PATCH 028/192] Update CircularMenuItem.js --- FloatingSpace/CircularMenuItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 8985a65cb..08fa845b2 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -68,7 +68,7 @@ function newCircularMenuItem() { let selfMouseNotOverEventSubscriptionId let labelToPrint = '' - let defaultBackgroudColor = UI_COLOR.RED + let defaultBackgroudColor = UI_COLOR.BLACK let backgroundColorToUse = UI_COLOR.RED let temporaryStatus = 0 let temporaryStatusCounter = 0 From e5e869cb35867101867c4dc3751c5ba5a4c81041 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 15 Aug 2020 13:52:27 +0200 Subject: [PATCH 029/192] Bug Fixed --- ChartingSpace/EdgeEditor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ChartingSpace/EdgeEditor.js b/ChartingSpace/EdgeEditor.js index 2b0cf02e7..d6d447ff1 100644 --- a/ChartingSpace/EdgeEditor.js +++ b/ChartingSpace/EdgeEditor.js @@ -185,6 +185,7 @@ function newEdgeEditor() { } function onKeyPressed(event) { + if (whereIsMouseOver !== 'center' ) {return} const STEP = 10 if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowLeft') { From 95ed61c61b63a2cae34a902151c54c3651714dfa Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 15 Aug 2020 14:04:13 +0200 Subject: [PATCH 030/192] Update Layer.js --- Panels/Layer.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Panels/Layer.js b/Panels/Layer.js index 180378e5d..0605b5355 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -566,7 +566,7 @@ function newLayer() { browserCanvasContext.strokeStyle = progressBar.strokeStyle.replace('@Opacity', progressBar.opacity.toString()) - browserCanvasContext.setLineDash([1, 4]) + browserCanvasContext.setLineDash([2, 4]) browserCanvasContext.lineWidth = lineWidth browserCanvasContext.stroke() } @@ -631,14 +631,14 @@ function newLayer() { label3FontSize = 9 } - drawLabel(label1, 1 / 2, 6 / 10, -5, 0, label1FontSize, thisObject.container) + drawLabel(label1, 1 / 2, 5.2 / 10, -5, 0, label1FontSize, thisObject.container) drawLabel(label2, 1 / 2, 8.2 / 10, -5, 0, label2FontSize, thisObject.container) drawLabel(label3, 1 / 2, 9.5 / 10, -5, 0, label3FontSize, thisObject.container) - drawProgressBar(marketFileProgressBar, 1, -45) - drawProgressBar(dailyFileProgressBar, 1, -46) - drawProgressBar(singleFileProgressBar, 1, -47) - drawProgressBar(fileSequenceProgressBar, 1, -48) + drawProgressBar(marketFileProgressBar, 2, -45 + 18) + drawProgressBar(dailyFileProgressBar, 2, -46 + 18) + drawProgressBar(singleFileProgressBar, 2, -47 + 18) + drawProgressBar(fileSequenceProgressBar, 2, -48 + 18) drawIcon(thisObject.exchangeIcon, 1 / 8, 2 / 10, 0, 0, 14, thisObject.container) drawIcon(thisObject.plotterTypeIcon, 7 / 8, 2 / 10, 0, 0, 14, thisObject.container) @@ -646,3 +646,4 @@ function newLayer() { drawIcon(thisObject.quotedAssetIcon, 4.6 / 8, 2 / 10, 0, 0, 14, thisObject.container) } } + From 100affdf9f70648e70436836a0f4f67516eac7d1 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 20 Aug 2020 14:55:50 +0200 Subject: [PATCH 031/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 2db538eef..b5b5c4e1a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -57,6 +57,7 @@ function newSessionFunctions() { 'Candle->Cycle->' + 'Begin->End->Open->Close->Min->Max->Index->' + 'Distance To Event->' + + 'Head Of The Market->Process Date->' + 'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' + 'Strategy->' + 'Strategy Counters->' + From 90300e5cdc685e901676e3a3ad7bc77985fb96df Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 21 Aug 2020 11:39:03 +0200 Subject: [PATCH 032/192] Update TaskFunctions.js --- DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index db9aa5e3f..2548a0135 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -31,7 +31,7 @@ function newTaskFunctions() { 'Indicator Bot Instance->Time Frames Filter->' + 'Trading Bot Instance->' + 'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' + - 'Market Reference->' + + 'Market Reference->Execution Started Event->' + 'Key Reference->Exchange Account Key->' + 'Market->Exchange Markets->Crypto Exchange->' + 'Market Base Asset->Market Quoted Asset->Asset->' + From eda2b1406460390a2fbe62f4e4f4b9d6fef6c22f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 21 Aug 2020 17:33:27 +0200 Subject: [PATCH 033/192] Decimals Handling Improved --- FloatingSpace/UiObject.js | 6 ++++-- Plotting/RecordValues.js | 8 ++++---- Utilities.js | 15 ++++++++------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 458101cc6..fb77577ce 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -110,6 +110,7 @@ function newUiObject() { let errorMessage = '' let currentValue = 0 + let valueMinDecimals = undefined let currentPercentage = '' let currentStatus = '' let rightDragging = false @@ -745,10 +746,11 @@ function newUiObject() { hasError = false } - function setValue(value, counter) { + function setValue(value, counter, minDecimals) { if (value !== undefined) { currentValue = value hasValue = true + valueMinDecimals = minDecimals if (counter !== undefined) { valueCounter = counter } else { @@ -1438,7 +1440,7 @@ function newUiObject() { label = currentValue if (!isNaN(currentValue)) { if (currentValue.toFixed !== undefined) { - label = dynamicDecimals(currentValue) + label = dynamicDecimals(currentValue, valueMinDecimals) } } diff --git a/Plotting/RecordValues.js b/Plotting/RecordValues.js index 931e988a8..799b3d4a8 100644 --- a/Plotting/RecordValues.js +++ b/Plotting/RecordValues.js @@ -95,14 +95,14 @@ function newRecordValues() { pointing to the same property at the Target Node. */ if (property.config.childProperty !== undefined) { - applyValue(targetNode[property.config.childProperty], value) + applyValue(targetNode[property.config.childProperty], value, property.config.decimals) } else { - applyValue(targetNode[property.config.codeName], value) + applyValue(targetNode[property.config.codeName], value, property.config.decimals) } } } - function applyValue(node, value) { + function applyValue(node, value, minDecimals) { if (canvas.chartingSpace.visible !== true) { return } if (node === undefined) { return } if (node === undefined) { return } @@ -110,6 +110,6 @@ function newRecordValues() { if (node.payload.uiObject === undefined) { return } if (value === true) { value = 'true' } if (value === false) { value = 'false' } - node.payload.uiObject.setValue(value, 1) + node.payload.uiObject.setValue(value, 1, minDecimals) } } diff --git a/Utilities.js b/Utilities.js index 11eeb5a37..5c68b4b3a 100644 --- a/Utilities.js +++ b/Utilities.js @@ -7,14 +7,15 @@ function dynamicDecimals(value, minDecimals) { if (minDecimals === undefined) { minDecimals = 0 } - let decimals = 2 - if (value < 1) { decimals = 4 } - if (Math.abs(Math.trunc(value * 100)) < 1) { decimals = 6 } - if (Math.abs(Math.trunc(value * 10000)) < 1) { decimals = 8 } - if (Math.abs(Math.trunc(value * 1000000)) < 1) { decimals = 10 } - if (Math.abs(Math.trunc(value * 100000000)) < 1) { decimals = 12 } + let decimals = 0 + if (value < 1) { decimals = 2 } + if (Math.abs(Math.trunc(value * 100)) < 1) { decimals = 4 } + if (Math.abs(Math.trunc(value * 10000)) < 1) { decimals = 6 } + if (Math.abs(Math.trunc(value * 1000000)) < 1) { decimals = 8 } + if (Math.abs(Math.trunc(value * 100000000)) < 1) { decimals = 10 } if (Math.abs(Math.trunc(value * 10000000000)) < 1) { value = 0; decimals = 0 } - if (Math.trunc(value) === value) { decimals = minDecimals } + if (decimals < minDecimals) {decimals = minDecimals} + let returnValue = Number(value).toFixed(decimals) return returnValue } From c17a655b1bdddf1c293c24e40d871bcc60909cbe Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 23 Aug 2020 09:39:06 +0200 Subject: [PATCH 034/192] Improvement on Socket Connection Error --- DesignSpace/Workspace/Workspace.js | 28 +++++++++++++++++++++++----- EventsServerClient.js | 26 ++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 7008cb873..5b56eb6b7 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -67,6 +67,7 @@ function newWorkspace() { thisObject.nodeChildren = newNodeChildren() + let savingWorkspaceIntervalId let isInitialized = false let workingAtTask = 0 let circularProgressBar = newBusyProgressBar() @@ -118,7 +119,7 @@ function newWorkspace() { thisObject.enabled = true canvas.cockpitSpace.initializePosition() canvas.splashScreen.initialize() - setInterval(saveWorkspace, 60000) + savingWorkspaceIntervalId = setInterval(saveWorkspace, 60000) isInitialized = true } } catch (err) { @@ -162,7 +163,7 @@ function newWorkspace() { if (host === undefined) { host = 'localhost' } if (webSocketsPort === undefined) { webSocketsPort = '8080' } - let eventsServerClient = newEventsServerClient(host, webSocketsPort, networkNode.name) + let eventsServerClient = newEventsServerClient(host, webSocketsPort, networkNode.name, networkNode) eventsServerClient.initialize() thisObject.eventsServerClients.set(networkNode.id, eventsServerClient) @@ -233,6 +234,14 @@ function newWorkspace() { } } + function finalizeEventsServerClients() { + thisObject.eventsServerClients.forEach(finalize) + + function finalize(eventServerClient) { + eventServerClient.finalize() + } + } + function replacingWorkspacePhysics() { if (thisObject.enabled !== true) { return } @@ -249,21 +258,30 @@ function newWorkspace() { workingAtTask++ break case 3: + finalizeEventsServerClients() + thisObject.eventsServerClients = new Map() + workingAtTask++ + break + case 4: + clearInterval(savingWorkspaceIntervalId) + workingAtTask++ + break + case 5: thisObject.workspaceNode = loadedWorkspaceNode loadedWorkspaceNode = undefined workingAtTask++ break - case 4: + case 6: functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode) setupEventsServerClients() runTasksAndSessions(true) workingAtTask++ break - case 5: + case 7: canvas.chartingSpace.reset() workingAtTask++ break - case 6: + case 8: workingAtTask = 0 circularProgressBar.visible = false break diff --git a/EventsServerClient.js b/EventsServerClient.js index 2956a6916..5dad4e0c2 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -1,5 +1,5 @@ -function newEventsServerClient(host, port, hostName) { +function newEventsServerClient(host, port, hostName, networkNode) { /* Web Sockets Connection */ const MODULE_NAME = 'System Event Handler' @@ -17,6 +17,7 @@ function newEventsServerClient(host, port, hostName) { let thisObject = { isConnected: isConnected, initialize: initialize, + finalize: finalize, physics: physics, createEventHandler: createEventHandler, deleteEventHandler: deleteEventHandler, @@ -37,6 +38,21 @@ function newEventsServerClient(host, port, hostName) { setuptWebSockets(callBackFunction) } + function finalize() { + WEB_SOCKETS_CONNECTION.close() + WEB_SOCKETS_CONNECTION.onerror = undefined + WEB_SOCKETS_CONNECTION.onmessage = undefined + WEB_SOCKETS_CONNECTION.onopen = undefined + WEB_SOCKETS_CONNECTION = undefined + + eventListeners = undefined + responseWaiters = undefined + commandsWaitingConfirmation = undefined + commandsSentByTimestamp = undefined + nonce = undefined + thisObject = undefined + } + function isConnected() { if (WEB_SOCKETS_CONNECTION.readyState === 1) { return true @@ -156,7 +172,13 @@ function newEventsServerClient(host, port, hostName) { } if (thisObject.isConnected() !== true) { - canvas.cockpitSpace.setStatus('Connecting to Superalgos Backend at ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING) + if (networkNode !== undefined) { + if (networkNode.payload !== undefined) { + if (networkNode.payload.uiObject !== undefined) { + networkNode.payload.uiObject.setErrorMessage('Connecting to Superalgos Backend at ' + hostName + ' Network Node') + } + } + } } else { retryCommandsPhysics() } From 7fdd31d9c0c7b3b3c5a2cc62bf40a6f1e184ec1d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 23 Aug 2020 11:02:34 +0200 Subject: [PATCH 035/192] Update Workspace.js --- DesignSpace/Workspace/Workspace.js | 80 +++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 5b56eb6b7..b71ff93d2 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -189,35 +189,54 @@ function newWorkspace() { } function saveWorkspace() { - if (isInitialized === false) { return } - /* When there is an exception while loading the app, the rootNodes of the workspace get into null value. To avoid saving a corrupt staate we are going to verufy we are not in that situation before saving. */ let workspace = canvas.designSpace.workspace.workspaceNode + /* Validation if it is too early to save. */ + if (isInitialized === false) { return } + + /* Validation of 2 sessions opened at the same time. */ let savedSessionTimestamp = window.localStorage.getItem('Session Timestamp') if (Number(savedSessionTimestamp) !== sessionTimestamp) { - canvas.cockpitSpace.setStatus('Could not save the Workspace. You have more that one instance of the Superlagos User Interface open at the same time. Plese close this instance as it is older than the others.', 150, canvas.cockpitSpace.statusTypes.WARNING) - } else { - let textToSave = stringifyWorkspace() - window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave) - window.localStorage.setItem('Session Timestamp', sessionTimestamp) + canvas.cockpitSpace.setStatus( + 'Could not save the Workspace. You have more that one instance of the Superlagos User Interface open at the same time. Plese close this instance as it is older than the others.' + , 150, canvas.cockpitSpace.statusTypes.WARNING) + return + } - if (workspace.name !== undefined) { - let url = 'SaveWorkspace/' + workspace.name - callServer(textToSave, url, onResponse) - } + /* Validation that there is something to save */ + let textToSave = stringifyWorkspace() + if (textToSave === undefined) { + canvas.cockpitSpace.setStatus( + 'Could not save the Workspace. Something is preventing the System to do it at this time.' + , 150, canvas.cockpitSpace.statusTypes.WARNING) + return + } - function onResponse(err) { - if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { - window.localStorage.setItem('Last Used Workspace', workspace.name) - window.localStorage.setItem('Session Timestamp', sessionTimestamp) - if (ARE_WE_RECORDING_A_MARKET_PANORAMA === false) { - canvas.cockpitSpace.setStatus(workspace.name + ' Saved.', 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) - } - } else { - canvas.cockpitSpace.setStatus('Could not save the Workspace at the Backend. Please check the Backend Console for more information.', 150, canvas.cockpitSpace.statusTypes.WARNING) + window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave) + window.localStorage.setItem('Session Timestamp', sessionTimestamp) + + /* Validation Workspace has a name */ + if (workspace.name === undefined) { + canvas.cockpitSpace.setStatus( + 'Could not save the Workspace. You need to specify a name for it.' + , 150, canvas.cockpitSpace.statusTypes.WARNING) + return + } + + let url = 'SaveWorkspace/' + workspace.name + callServer(textToSave, url, onResponse) + return true + + function onResponse(err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + window.localStorage.setItem('Last Used Workspace', workspace.name) + window.localStorage.setItem('Session Timestamp', sessionTimestamp) + if (ARE_WE_RECORDING_A_MARKET_PANORAMA === false) { + canvas.cockpitSpace.setStatus(workspace.name + ' Saved.', 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) } + } else { + canvas.cockpitSpace.setStatus('Could not save the Workspace at the Backend. Please check the Backend Console for more information.', 150, canvas.cockpitSpace.statusTypes.WARNING) } - return true } } @@ -311,7 +330,16 @@ function newWorkspace() { rootNodes: stringifyReadyNodes } - return JSON.stringify(workspace) + /* + Sometimes it happens that there are no rootNodes. + In those situations the workspace can not be stringified, + to prevent later saving it corrupting the original file. + */ + if (stringifyReadyNodes.length > 0) { + return JSON.stringify(workspace) + } else { + return + } } function stopAllRunningTasks() { @@ -460,14 +488,18 @@ function newWorkspace() { { let text = stringifyWorkspace(true) let fileName = 'Share - ' + payload.node.type + ' - ' + payload.node.name + '.json' - downloadText(fileName, text) + if (text !== undefined) { + downloadText(fileName, text) + } } break case 'Backup Workspace': { let text = stringifyWorkspace(false) let fileName = 'Backup - ' + payload.node.type + ' - ' + payload.node.name + '.json' - downloadText(fileName, text) + if (text !== undefined) { + downloadText(fileName, text) + } } break case 'Edit Code': From 33835cfb0898befda68476c70e3918e3c760e52a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 23 Aug 2020 15:28:35 +0200 Subject: [PATCH 036/192] Displaying Error Improved --- FloatingSpace/UiObject.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index fb77577ce..00c0bc344 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1054,7 +1054,7 @@ function newUiObject() { if (thisObject.isOnFocus === false) { drawReferenceLine() drawChainLine() - + drawBodyAndPicture() if (isDragging === false && thisObject.isOnFocus === true) { thisObject.menu.drawBackground() } @@ -1067,6 +1067,7 @@ function newUiObject() { function drawMiddleground() { if (thisObject.isOnFocus === false) { + drawErrorMessage() drawValue() drawPercentage() drawStatus() @@ -1077,7 +1078,7 @@ function newUiObject() { function drawForeground() { if (thisObject.isOnFocus === false) { - drawBodyAndPicture() + if (isDragging === false) { thisObject.menu.drawForeground() } @@ -1699,18 +1700,18 @@ function newUiObject() { } if (thisObject.isOnFocus === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius + VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS * 1.2, 0, Math.PI * 2, true) + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.75)' + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.60)' browserCanvasContext.fill() } if (hasError === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 1 + VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 let OPACITY = errorMessageCounter / 30 browserCanvasContext.beginPath() @@ -1719,8 +1720,8 @@ function newUiObject() { browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([19, 20]) + browserCanvasContext.lineWidth = 5 + browserCanvasContext.setLineDash([5, 10]) browserCanvasContext.stroke() } From e3fb03ce3f5cd67cd37a5fc193b285dac6781cbe Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 23 Aug 2020 16:00:41 +0200 Subject: [PATCH 037/192] Look and Feel UI --- Canvas.js | 21 +++++---------------- FloatingSpace/UiObject.js | 32 +++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Canvas.js b/Canvas.js index d5b2cf6ac..d07cb3823 100644 --- a/Canvas.js +++ b/Canvas.js @@ -48,7 +48,6 @@ function newCanvas() { thisObject.eventHandler = newEventHandler() let lastContainerMouseOver - let lastShortcutKeyRejection thisObject.mouse = { position: { @@ -467,23 +466,13 @@ function newCanvas() { nodeOnFocus.payload.uiObject.setValue('Shortcut Key Removed ') return } else { - if (lastShortcutKeyRejection !== event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) { - /* The first time we show a warning that this key is in use. */ - nodeOnFocus.payload.uiObject.setErrorMessage('Key already in use by ' + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) - lastShortcutKeyRejection = event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name - return - } else { - /* After the warning, we allow the key to be re-assigned */ - nodeUsingThisKey.payload.uiObject.shortcutKey = '' - nodeUsingThisKey === undefined - } + /* After the warning, we allow the key to be re-assigned */ + nodeUsingThisKey.payload.uiObject.shortcutKey = '' + nodeUsingThisKey === undefined + nodeOnFocus.payload.uiObject.shortcutKey = event.key + nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + event.key) } } - /* If there is not node using this key and a node in focus, we assign this key to this node */ - if (nodeUsingThisKey === undefined && nodeOnFocus !== undefined) { - nodeOnFocus.payload.uiObject.shortcutKey = event.key - nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + event.key) - } return } } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 00c0bc344..b30b99d2d 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1078,7 +1078,7 @@ function newUiObject() { function drawForeground() { if (thisObject.isOnFocus === false) { - + if (isDragging === false) { thisObject.menu.drawForeground() } @@ -1670,19 +1670,20 @@ function newUiObject() { let nodeDefinition = getNodeDefinition(thisObject.payload.node) if (nodeDefinition !== undefined) { + /* Hierarchy Head Ring */ if (nodeDefinition.isHierarchyHead === true) { - VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 2.8 + VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 3.8 if (canvas.floatingSpace.inMapMode === true) { VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) } - let OPACITY = 1 + let OPACITY = 0.5 browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([4, 16]) + browserCanvasContext.setLineDash([1, 10]) browserCanvasContext.stroke() browserCanvasContext.beginPath() @@ -1693,33 +1694,42 @@ function newUiObject() { if (thisObject.payload.node.isIncluded === true) { browserCanvasContext.setLineDash([0, 0]) } else { - browserCanvasContext.setLineDash([20, 20]) + browserCanvasContext.setLineDash([10, 20]) } browserCanvasContext.stroke() } } if (thisObject.isOnFocus === true) { + /* Black Translucent Background when node is in focus */ VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.60)' - + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.65)' browserCanvasContext.fill() + /* Border when node is in focus */ + if (hasError !== true && nodeDefinition.isHierarchyHead !== true) { + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' + browserCanvasContext.lineWidth = 3 + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke() + } } if (hasError === true) { VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 + if (canvas.floatingSpace.inMapMode === true) { + VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) + } let OPACITY = errorMessageCounter / 30 - browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 5 browserCanvasContext.setLineDash([5, 10]) browserCanvasContext.stroke() From 19318dcaeb345a69102a621b8b3731c877898236 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 23 Aug 2020 16:45:34 +0200 Subject: [PATCH 038/192] Face Washing --- FloatingSpace/CircularProgressBar.js | 12 ++++++------ FloatingSpace/UiObject.js | 23 ++++++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/FloatingSpace/CircularProgressBar.js b/FloatingSpace/CircularProgressBar.js index 070f55e22..afa76606d 100644 --- a/FloatingSpace/CircularProgressBar.js +++ b/FloatingSpace/CircularProgressBar.js @@ -110,7 +110,7 @@ function newCircularProgressBar() { if (canvas.floatingSpace.inMapMode === true) { return } if (needToDrawRing !== true) { return } - const VISIBLE_RADIUS = thisObject.container.frame.radius * 2 + const VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 let visiblePosition = { x: thisObject.container.frame.position.x, @@ -121,7 +121,7 @@ function newCircularProgressBar() { visiblePosition = thisObject.fitFunction(visiblePosition) for (let i = 0; i < 60; i++) { - let OPACITY = opacityCounters[i] / 1000 + let OPACITY = opacityCounters[i] / 4000 if (OPACITY === 0) { continue } @@ -133,13 +133,13 @@ function newCircularProgressBar() { browserCanvasContext.closePath() browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY * 2 + ')' - browserCanvasContext.lineWidth = 6 + opacityCounters[i] / 100 / 2 - browserCanvasContext.setLineDash([3, 4]) + browserCanvasContext.lineWidth = 6 + opacityCounters[i] / 100 / 4 + browserCanvasContext.setLineDash([1, 10]) browserCanvasContext.stroke() browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 0 + opacityCounters[i] / 100 / 2 - browserCanvasContext.setLineDash([3, 4]) + browserCanvasContext.lineWidth = 0 + opacityCounters[i] / 100 / 4 + browserCanvasContext.setLineDash([2, 10]) browserCanvasContext.stroke() } } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index b30b99d2d..0ae1fd355 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1429,10 +1429,10 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 1.35 + let radius = thisObject.container.frame.radius * 1.00 /* Label Text */ let labelPoint - let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 + let fontSize = thisObject.payload.floatingObject.currentFontSize * 8 / 7 let label if (radius > 6) { @@ -1451,7 +1451,7 @@ function newUiObject() { } if (label.length > 30) { - fontSize = fontSize / 2 + fontSize = fontSize * 2 / 3 } labelPoint = { @@ -1483,7 +1483,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 1.75 + let radius = thisObject.container.frame.radius * 1.30 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 @@ -1526,7 +1526,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 0.9 + let radius = thisObject.container.frame.radius * 0.8 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 / 2 @@ -1706,10 +1706,10 @@ function newUiObject() { browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.65)' + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.70)' browserCanvasContext.fill() /* Border when node is in focus */ - if (hasError !== true && nodeDefinition.isHierarchyHead !== true) { + if (hasError !== true && nodeDefinition.isHierarchyHead !== true && thisObject.circularProgressBar === undefined) { browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() @@ -1717,6 +1717,15 @@ function newUiObject() { browserCanvasContext.lineWidth = 3 browserCanvasContext.setLineDash([0, 0]) browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 1, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + 1 + ')' + browserCanvasContext.lineWidth = 2 + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke() + } } From f4cc1bf39ebcfd5e722691f104f2458d091b0b88 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 24 Aug 2020 10:09:46 +0200 Subject: [PATCH 039/192] fix --- EventsServerClient.js | 2 +- FloatingSpace/UiObject.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/EventsServerClient.js b/EventsServerClient.js index 5dad4e0c2..3f06f2b4a 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -175,7 +175,7 @@ function newEventsServerClient(host, port, hostName, networkNode) { if (networkNode !== undefined) { if (networkNode.payload !== undefined) { if (networkNode.payload.uiObject !== undefined) { - networkNode.payload.uiObject.setErrorMessage('Connecting to Superalgos Backend at ' + hostName + ' Network Node') + networkNode.payload.uiObject.setErrorMessage('Trying to Connect to Superalgos Backend') } } } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 0ae1fd355..4488ec405 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1367,6 +1367,9 @@ function newUiObject() { function drawErrorMessage() { if (hasError === false) { return } + if (canvas.floatingSpace.inMapMode === true) { + return + } /* Text Follows */ let position = { From 7e6919b39189001e5d04047a23f5a0a688490517 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 24 Aug 2020 15:33:55 +0200 Subject: [PATCH 040/192] Improvements on Network Node --- DesignSpace/Workspace/Workspace.js | 17 +------ EventsServerClient.js | 76 +++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index b71ff93d2..1fc06b306 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -148,22 +148,7 @@ function newWorkspace() { for (let j = 0; j < rootNode.networkNodes.length; j++) { let networkNode = rootNode.networkNodes[j] - let host - let webSocketsPort - /* At this point the node does not have the payload property yet, that is why we have to do this manually */ - try { - let config = JSON.parse(networkNode.config) - host = config.host - webSocketsPort = config.webSocketsPort - } catch (err) { - console.log('[ERROR] networkNode ' + networkNode.name + ' has an invalid configuration. Cannot know the host name and webSocketsPort.') - return - } - - if (host === undefined) { host = 'localhost' } - if (webSocketsPort === undefined) { webSocketsPort = '8080' } - - let eventsServerClient = newEventsServerClient(host, webSocketsPort, networkNode.name, networkNode) + let eventsServerClient = newEventsServerClient(networkNode) eventsServerClient.initialize() thisObject.eventsServerClients.set(networkNode.id, eventsServerClient) diff --git a/EventsServerClient.js b/EventsServerClient.js index 3f06f2b4a..f01aa482a 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -1,5 +1,5 @@ -function newEventsServerClient(host, port, hostName, networkNode) { +function newEventsServerClient(networkNode) { /* Web Sockets Connection */ const MODULE_NAME = 'System Event Handler' @@ -8,10 +8,6 @@ function newEventsServerClient(host, port, hostName, networkNode) { const logger = newWebDebugLog() logger.fileName = MODULE_NAME - if (host === '' || host === undefined) { host = 'localhost' } - if (port === '' || port === undefined) { port = '8081' } - - const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + '' let WEB_SOCKETS_CONNECTION let thisObject = { @@ -31,6 +27,7 @@ function newEventsServerClient(host, port, hostName, networkNode) { let commandsWaitingConfirmation = new Map() let commandsSentByTimestamp = new Map() let nonce = 0 + let lastTryToReconnectDatetime return thisObject @@ -54,10 +51,10 @@ function newEventsServerClient(host, port, hostName, networkNode) { } function isConnected() { - if (WEB_SOCKETS_CONNECTION.readyState === 1) { - return true - } else { - return false + if (WEB_SOCKETS_CONNECTION !== undefined) { + if (WEB_SOCKETS_CONNECTION.readyState === 1) { + return true + } } } @@ -163,23 +160,46 @@ function newEventsServerClient(host, port, hostName, networkNode) { function physics() { if (WEB_SOCKETS_CONNECTION !== undefined) { - if (WEB_SOCKETS_CONNECTION.readyState === 3) { // Connection closed. May happen after computer goes to sleep. - setuptWebSockets(onOpen) + if (WEB_SOCKETS_CONNECTION.readyState === 3) { + /* + Connection closed. May happen after computer goes to sleep. + We will try to reconnect, but we will do it no more that once + a minute. + */ + if (lastTryToReconnectDatetime === undefined) { + setuptWebSockets(onOpen) + lastTryToReconnectDatetime = (new Date()).valueOf() + } else { + let now = (new Date()).valueOf() + if (now - lastTryToReconnectDatetime > 60000) { + setuptWebSockets(onOpen) + } + } + function onOpen() { if (INFO_LOG === true) { logger.write('[INFO] setuptWebSockets -> Found Web Sockets Connection Closed. Reconnected to WebSockets Server.') } } } + } else { + /* + If there is a problem with the configuration then we go through + this path, retrying this until the configuration is fixed. + */ + setuptWebSockets(onOpen) } - if (thisObject.isConnected() !== true) { - if (networkNode !== undefined) { - if (networkNode.payload !== undefined) { - if (networkNode.payload.uiObject !== undefined) { - networkNode.payload.uiObject.setErrorMessage('Trying to Connect to Superalgos Backend') + if (thisObject.isConnected() !== true ) { + if ( lastTryToReconnectDatetime !== undefined) { + if (networkNode !== undefined) { + if (networkNode.payload !== undefined) { + if (networkNode.payload.uiObject !== undefined) { + networkNode.payload.uiObject.setErrorMessage('Failed to Connect to Superalgos Backend via WebSockets. Retrying in 1 minute.') + } } } } } else { + networkNode.payload.uiObject.setStatus('Connected to Superalgos Backend via WebSockets.') retryCommandsPhysics() } @@ -188,6 +208,30 @@ function newEventsServerClient(host, port, hostName, networkNode) { function setuptWebSockets(callBackFunction) { try { + let host + let port + /* At this point the node does not have the payload property yet, that is why we have to do this manually */ + try { + let config = JSON.parse(networkNode.config) + host = config.host + port = config.webSocketsPort + } catch (err) { + networkNode.payload.uiObject.setErrorMessage('Bad configuration. Cannot know the host name or the webSocketsPort.') + return + } + + if (host === undefined) { + networkNode.payload.uiObject.setErrorMessage('Bad configuration. You need to have a host property.') + return + } + + if (port === undefined) { + networkNode.payload.uiObject.setErrorMessage('Bad configuration. You need to have a webSocketsPort property.') + return + } + + const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + '' + WEB_SOCKETS_CONNECTION = new WebSocket(WEB_SOCKETS_URL) WEB_SOCKETS_CONNECTION.onerror = error => { console.log('WebSocket error:' + JSON.stringify(error)) From bd17df4d334fd96891b8667eb7b15597d20c7cbf Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 24 Aug 2020 20:50:16 +0200 Subject: [PATCH 041/192] Update UiObject.js --- FloatingSpace/UiObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 4488ec405..9d1c1edeb 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1394,7 +1394,7 @@ function newUiObject() { label = errorMessage - if (label !== undefined) { + if (label !== undefined && label !== null) { if (label.length > MAX_LABEL_LENGTH) { label = label.substring(0, MAX_LABEL_LENGTH) + '...' } From 8d9510316f860d9f4de1e26b8084ac212aa1cab4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 24 Aug 2020 21:32:29 +0200 Subject: [PATCH 042/192] Update SessionFunctions.js --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index b5b5c4e1a..736649dd3 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -87,7 +87,7 @@ function newSessionFunctions() { lightingPath = '' + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + 'Parameters->' + - 'Session Base Asset->Session Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->Snapshots->User Defined Parameters->' + + 'Session Base Asset->Session Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->Snapshots->Heartbeats->User Defined Parameters->' + 'Exchange Account Asset->Asset->' + 'Social Bots->Telegram Bot->' From db493bd6fd78b95453a2f38ea72c671dd038f152 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 26 Aug 2020 12:53:18 +0200 Subject: [PATCH 043/192] Update UiObject.js --- FloatingSpace/UiObject.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 9d1c1edeb..c426b5fd8 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1054,7 +1054,7 @@ function newUiObject() { if (thisObject.isOnFocus === false) { drawReferenceLine() drawChainLine() - drawBodyAndPicture() + if (isDragging === false && thisObject.isOnFocus === true) { thisObject.menu.drawBackground() } @@ -1067,6 +1067,7 @@ function newUiObject() { function drawMiddleground() { if (thisObject.isOnFocus === false) { + drawBodyAndPicture() drawErrorMessage() drawValue() drawPercentage() From 304ce8fd50c78915fb3f832485904f6ade9754f5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 27 Aug 2020 15:27:29 +0200 Subject: [PATCH 044/192] Update RecordValues.js --- Plotting/RecordValues.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Plotting/RecordValues.js b/Plotting/RecordValues.js index 799b3d4a8..073268fd0 100644 --- a/Plotting/RecordValues.js +++ b/Plotting/RecordValues.js @@ -53,10 +53,10 @@ function newRecordValues() { The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values. */ let productRootNode = productRoot - scanProperties(productRootNode) + scanProperties(productDefinition, productRootNode) } - function scanProperties(productRootNode, index) { + function scanProperties(productDefinition, productRootNode, index) { for (let i = 0; i < productDefinition.record.properties.length; i++) { let property = productDefinition.record.properties[i] let key = property.id @@ -64,7 +64,17 @@ function newRecordValues() { key = property.id + '-' + index } if (property.config.nodePath !== undefined) { - let propertyRoot = eval(property.config.nodePath) + let propertyRoot + try { + propertyRoot = eval(property.config.nodePath) + } catch(err) { + console.log('Definition Error at Product ' + productDefinition.name) + console.log('productDefinition.config = ' + JSON.stringify(productDefinition.config)) + console.log('Definition Error at Property ' + property.name) + console.log('property.config = ' + JSON.stringify(property.config)) + console.log('property.config.nodePath = ' + property.config.nodePath) + return + } propertyTargetNodeMap.set(key, propertyRoot) } else { propertyTargetNodeMap.set(key, productRootNode) From f3faa93a91d3dd26b36d5834d726b08edb38c05a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 28 Aug 2020 10:50:32 +0200 Subject: [PATCH 045/192] Error handling --- EventsServerClient.js | 3 +++ FloatingSpace/UiObject.js | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/EventsServerClient.js b/EventsServerClient.js index f01aa482a..8d3c871f2 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -215,6 +215,9 @@ function newEventsServerClient(networkNode) { let config = JSON.parse(networkNode.config) host = config.host port = config.webSocketsPort + + /* Check if we really have to stablish the connection. */ + if (config.autoConnect === false) {return} } catch (err) { networkNode.payload.uiObject.setErrorMessage('Bad configuration. Cannot know the host name or the webSocketsPort.') return diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index c426b5fd8..89db5cc2c 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -23,6 +23,7 @@ function newUiObject() { isRunning: undefined, shortcutKey: undefined, isShowing: undefined, + hasError: undefined, run: run, stop: stop, heartBeat: heartBeat, @@ -74,7 +75,6 @@ function newUiObject() { let isRunningAtBackend let runningAtBackendCounter = 0 - let hasError let errorMessageCounter = 0 let hasValue @@ -690,7 +690,7 @@ function newUiObject() { errorMessageCounter-- if (errorMessageCounter < 0) { errorMessageCounter = 0 - hasError = false + thisObject.hasError = false } } @@ -735,7 +735,7 @@ function newUiObject() { function setErrorMessage(message, duration) { if (message !== undefined) { errorMessage = message - hasError = true + thisObject.hasError = true if (duration === undefined) { duration = 1 } errorMessageCounter = 100 * duration } @@ -743,7 +743,7 @@ function newUiObject() { function resetErrorMessage() { errorMessage = undefined - hasError = false + thisObject.hasError = false } function setValue(value, counter, minDecimals) { @@ -1367,7 +1367,7 @@ function newUiObject() { } function drawErrorMessage() { - if (hasError === false) { return } + if (thisObject.hasError === false) { return } if (canvas.floatingSpace.inMapMode === true) { return } @@ -1713,7 +1713,7 @@ function newUiObject() { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.70)' browserCanvasContext.fill() /* Border when node is in focus */ - if (hasError !== true && nodeDefinition.isHierarchyHead !== true && thisObject.circularProgressBar === undefined) { + if (thisObject.hasError !== true && nodeDefinition.isHierarchyHead !== true && thisObject.circularProgressBar === undefined) { browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() @@ -1733,7 +1733,7 @@ function newUiObject() { } } - if (hasError === true) { + if (thisObject.hasError === true) { VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 if (canvas.floatingSpace.inMapMode === true) { VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) From 4e1b3def3c87d01edc50a62dc8c605142167f1bd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 28 Aug 2020 14:02:40 +0200 Subject: [PATCH 046/192] Error branches --- FloatingSpace/UiObject.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 89db5cc2c..cd08551ab 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -738,6 +738,27 @@ function newUiObject() { thisObject.hasError = true if (duration === undefined) { duration = 1 } errorMessageCounter = 100 * duration + + /* + Next, we are going to try to inform the parent that this + node has an error, as a way to show the end user where the + node with error is. This is useful to detect errors in nodes + that are located at braches that are collapsed. + */ + + if (thisObject.payload !== undefined) { + if (thisObject.payload.parentNode !== undefined) { + if (thisObject.payload.parentNode.payload !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) { + if (thisObject.payload.parentNode.payload.uiObject !== true) { + thisObject.payload.parentNode.payload.uiObject.setErrorMessage('Error Inside this Branch') + } + } + } + } + } + } } } From 9f573728dd2e25963cf2c1f729b59072c374b11a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 28 Aug 2020 16:18:42 +0200 Subject: [PATCH 047/192] Look and Feel --- FloatingSpace/CircularMenuItem.js | 18 ++++--- FloatingSpace/CodeEditor.js | 9 ++-- FloatingSpace/ConfigEditor.js | 6 +-- FloatingSpace/FormulaEditor.js | 8 +-- FloatingSpace/UiObject.js | 74 +++++++++++++++------------- FloatingSpace/UiObjectConstructor.js | 2 +- 6 files changed, 64 insertions(+), 53 deletions(-) diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 08fa845b2..420211e7b 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -156,8 +156,7 @@ function newCircularMenuItem() { function physics() { if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } - let INCREASE_STEP = 2 // (thisObject.targetRadius - thisObject.rawRadius) / 4 - // if (INCREASE_STEP === 0) { INCREASE_STEP = 2 } + let INCREASE_STEP = 2 if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= INCREASE_STEP) { if (thisObject.currentRadius < thisObject.targetRadius) { @@ -191,8 +190,17 @@ function newCircularMenuItem() { radiusGrowthFactor = 4 } - thisObject.container.frame.position.x = thisObject.payload.floatingObject.targetRadius * radiusGrowthFactor / 7 * Math.cos(toRadians(thisObject.angle)) - thisObject.currentRadius * 1.5 - thisObject.container.frame.position.y = thisObject.payload.floatingObject.targetRadius * radiusGrowthFactor / 7 * Math.sin(toRadians(thisObject.angle)) - thisObject.container.frame.height / 2 + thisObject.container.frame.position.x = + thisObject.payload.floatingObject.targetRadius * + radiusGrowthFactor / 7 + * Math.cos(toRadians(thisObject.angle)) - + thisObject.currentRadius * 1.5 + + thisObject.container.frame.position.y = + thisObject.payload.floatingObject.targetRadius * + radiusGrowthFactor / 7 + * Math.sin(toRadians(thisObject.angle)) - + thisObject.container.frame.height / 2 temporaryStatusPhysics() @@ -428,7 +436,6 @@ function newCircularMenuItem() { menuPosition = thisObject.container.frame.frameThisPoint(menuPosition) /* Menu Item */ - let iconSize if (isMouseOver === true) { iconSize = thisObject.currentRadius + EXTRA_MOUSE_OVER_ICON_SIZE @@ -441,7 +448,6 @@ function newCircularMenuItem() { browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - iconSize, menuPosition.y - iconSize, iconSize * 2, iconSize * 2) /* Menu Label */ - if (thisObject.type === 'Icon & Text') { label = labelToPrint if (thisObject.shorcutNumber !== undefined) { diff --git a/FloatingSpace/CodeEditor.js b/FloatingSpace/CodeEditor.js index 6ab244702..c490156c3 100644 --- a/FloatingSpace/CodeEditor.js +++ b/FloatingSpace/CodeEditor.js @@ -32,7 +32,7 @@ function newCodeEditor() { thisObject.container.frame.position.y = 0 let isMouseOver = false - let SIZE_FACTOR = 1.4 + let SIZE_FACTOR = 1.0 return thisObject @@ -113,7 +113,7 @@ function newCodeEditor() { thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR + thisObject.container.frame.width = thisObject.container.frame.radius * 1 * SIZE_FACTOR thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR let textAreaPosition = { @@ -150,19 +150,20 @@ function newCodeEditor() { if (radius > 0.5) { browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) + browserCanvasContext.arc(position.x, position.y, radius + 3, 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' browserCanvasContext.fill() browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) + browserCanvasContext.arc(position.x, position.y, radius , 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + 1 + ')' browserCanvasContext.fill() } } } + function drawForeground() { let iconPosition = { x: 0, diff --git a/FloatingSpace/ConfigEditor.js b/FloatingSpace/ConfigEditor.js index e62179f68..e8864a0e8 100644 --- a/FloatingSpace/ConfigEditor.js +++ b/FloatingSpace/ConfigEditor.js @@ -119,7 +119,7 @@ function newConfigEditor() { thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR + thisObject.container.frame.width = thisObject.container.frame.radius * 1 * SIZE_FACTOR thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR let textAreaPosition = { @@ -156,13 +156,13 @@ function newConfigEditor() { if (radius > 0.5) { browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) + browserCanvasContext.arc(position.x, position.y, radius + 3, 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' browserCanvasContext.fill() browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) + browserCanvasContext.arc(position.x, position.y, radius , 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + 1 + ')' browserCanvasContext.fill() diff --git a/FloatingSpace/FormulaEditor.js b/FloatingSpace/FormulaEditor.js index 0b3887637..2a781b67c 100644 --- a/FloatingSpace/FormulaEditor.js +++ b/FloatingSpace/FormulaEditor.js @@ -32,7 +32,7 @@ function newFormulaEditor() { thisObject.container.frame.position.y = 0 let isMouseOver = false - let SIZE_FACTOR = 1.2 + let SIZE_FACTOR = 1.0 return thisObject @@ -113,7 +113,7 @@ function newFormulaEditor() { thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR + thisObject.container.frame.width = thisObject.container.frame.radius * 1 * SIZE_FACTOR thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR let textAreaPosition = { @@ -150,13 +150,13 @@ function newFormulaEditor() { if (radius > 0.5) { browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true) + browserCanvasContext.arc(position.x, position.y, radius + 3, 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')' browserCanvasContext.fill() browserCanvasContext.beginPath() - browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true) + browserCanvasContext.arc(position.x, position.y, radius , 0, Math.PI * 2, true) browserCanvasContext.closePath() browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', ' + 1 + ')' browserCanvasContext.fill() diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index cd08551ab..db89f27d4 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1075,7 +1075,7 @@ function newUiObject() { if (thisObject.isOnFocus === false) { drawReferenceLine() drawChainLine() - + if (isDragging === false && thisObject.isOnFocus === true) { thisObject.menu.drawBackground() } @@ -1367,7 +1367,7 @@ function newUiObject() { labelPoint = { x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 4 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + y: position.y + radius * 2 / 3 + fontSize * FONT_ASPECT_RATIO + 15 } if (canvas.floatingSpace.inMapMode === true) { @@ -1694,40 +1694,14 @@ function newUiObject() { browserCanvasContext.fill() let nodeDefinition = getNodeDefinition(thisObject.payload.node) - if (nodeDefinition !== undefined) { - /* Hierarchy Head Ring */ - if (nodeDefinition.isHierarchyHead === true) { - VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 3.8 - if (canvas.floatingSpace.inMapMode === true) { - VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) - } - let OPACITY = 0.5 - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 10 - browserCanvasContext.setLineDash([1, 10]) - browserCanvasContext.stroke() - - browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) - browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' - browserCanvasContext.lineWidth = 1 - if (thisObject.payload.node.isIncluded === true) { - browserCanvasContext.setLineDash([0, 0]) - } else { - browserCanvasContext.setLineDash([10, 20]) - } - browserCanvasContext.stroke() - } + if (nodeDefinition === undefined) { + console.log('Node ' + thisObject.payload.node + ' without Node Definition at APP SCHEMA.') + return } if (thisObject.isOnFocus === true) { /* Black Translucent Background when node is in focus */ - VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 + VISIBLE_RADIUS = thisObject.container.frame.radius browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() @@ -1742,7 +1716,7 @@ function newUiObject() { browserCanvasContext.lineWidth = 3 browserCanvasContext.setLineDash([0, 0]) browserCanvasContext.stroke() - + browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS - 1, 0, Math.PI * 2, true) browserCanvasContext.closePath() @@ -1754,8 +1728,38 @@ function newUiObject() { } } + /* Hierarchy Head Ring */ + if (nodeDefinition.isHierarchyHead === true) { + VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 3.8 + if (canvas.floatingSpace.inMapMode === true) { + VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) + } + let OPACITY = 0.5 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([1, 10]) + browserCanvasContext.stroke() + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 1 + if (thisObject.payload.node.isIncluded === true) { + browserCanvasContext.setLineDash([0, 0]) + } else { + browserCanvasContext.setLineDash([10, 20]) + } + browserCanvasContext.stroke() + } + + if (thisObject.hasError === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 + VISIBLE_RADIUS = thisObject.container.frame.radius if (canvas.floatingSpace.inMapMode === true) { VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) } @@ -1770,7 +1774,7 @@ function newUiObject() { } if (isHighlighted === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 1 + VISIBLE_RADIUS = thisObject.container.frame.radius let OPACITY = highlightCounter / 10 browserCanvasContext.beginPath() diff --git a/FloatingSpace/UiObjectConstructor.js b/FloatingSpace/UiObjectConstructor.js index 83c151737..77695128b 100644 --- a/FloatingSpace/UiObjectConstructor.js +++ b/FloatingSpace/UiObjectConstructor.js @@ -488,7 +488,7 @@ function newUiObjectConstructor() { const FRICTION = 0.95 const INITIAL_FRICTION = 0.97 const INITIAL_FONT_SIZE = 12 * 1.5 - const INITIAL_RADIOUS = 45 * 1.5 + const INITIAL_RADIOUS = 100 const INITIAL_IMAGE_SIZE = 80 * 1.2 const INITIAL_HIERARCHY_RING = 20 From 80ecf31f02a08b41f40bfde068f614d619eaee41 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 28 Aug 2020 16:42:51 +0200 Subject: [PATCH 048/192] Update UiObject.js --- FloatingSpace/UiObject.js | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index db89f27d4..abb67de11 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -488,7 +488,7 @@ function newUiObject() { } } if (foundCompatible === false) { - if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { + if (distance < thisObject.payload.floatingObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { nearbyNode.payload.uiObject.getReadyToChainAttach() isChainAttaching = true chainAttachToNode = nearbyNode @@ -595,7 +595,7 @@ function newUiObject() { let nearbyNode = floatingObject.payload.node if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { if (foundCompatible === false) { - if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { + if (distance < thisObject.payload.floatingObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { nearbyNode.payload.uiObject.getReadyToReferenceAttach() isReferenceAttaching = true referenceAttachToNode = nearbyNode @@ -1203,7 +1203,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - if (thisObject.container.frame.radius > 1) { + if (thisObject.payload.floatingObject.container.frame.radius > 1) { let LINE_STYLE = UI_COLOR.TITANIUM_YELLOW if (thisObject.payload.floatingObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED) { LINE_STYLE = UI_COLOR.GOLDEN_ORANGE @@ -1243,7 +1243,7 @@ function newUiObject() { browserCanvasContext.setLineDash([0, 0]) } - if (thisObject.container.frame.radius > 0.5) { + if (thisObject.payload.floatingObject.container.frame.radius > 0.5) { let radius = 1 browserCanvasContext.beginPath() @@ -1285,7 +1285,7 @@ function newUiObject() { let LINE_STYLE = UI_COLOR.GREY - if (thisObject.container.frame.radius > 1) { + if (thisObject.payload.floatingObject.container.frame.radius > 1) { browserCanvasContext.beginPath() browserCanvasContext.moveTo(position.x, position.y) browserCanvasContext.lineTo(targetPoint.x, targetPoint.y) @@ -1305,7 +1305,7 @@ function newUiObject() { browserCanvasContext.setLineDash([0, 0]) } - if (thisObject.container.frame.radius > 0.5) { + if (thisObject.payload.floatingObject.container.frame.radius > 0.5) { let radius = 1 browserCanvasContext.beginPath() @@ -1405,7 +1405,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 2.5 + let radius = thisObject.payload.floatingObject.container.frame.radius * 2.5 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 3 / 4 @@ -1454,7 +1454,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 1.00 + let radius = thisObject.payload.floatingObject.container.frame.radius * 1.00 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 8 / 7 @@ -1508,7 +1508,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 1.30 + let radius = thisObject.payload.floatingObject.container.frame.radius * 1.30 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 @@ -1551,7 +1551,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius * 0.8 + let radius = thisObject.payload.floatingObject.container.frame.radius * 0.8 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 / 2 @@ -1657,7 +1657,7 @@ function newUiObject() { position = canvas.floatingSpace.transformPointToMap(position) } - let radius = thisObject.container.frame.radius + let radius = thisObject.payload.floatingObject.container.frame.radius if (radius > 0.5) { let VISIBLE_RADIUS = 5 @@ -1701,7 +1701,7 @@ function newUiObject() { if (thisObject.isOnFocus === true) { /* Black Translucent Background when node is in focus */ - VISIBLE_RADIUS = thisObject.container.frame.radius + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() @@ -1759,7 +1759,7 @@ function newUiObject() { if (thisObject.hasError === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius if (canvas.floatingSpace.inMapMode === true) { VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) } @@ -1774,7 +1774,7 @@ function newUiObject() { } if (isHighlighted === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius let OPACITY = highlightCounter / 10 browserCanvasContext.beginPath() @@ -1789,7 +1789,7 @@ function newUiObject() { } if (isReadyToChainAttach === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + readyToChainAttachDisplayCounter - readyToChainAttachDisplayCounter / 2 + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius * 2.5 + readyToChainAttachDisplayCounter - readyToChainAttachDisplayCounter / 2 let OPACITY = readyToChainAttachCounter / 10 browserCanvasContext.beginPath() @@ -1818,7 +1818,7 @@ function newUiObject() { } if (isAvailableToChainAttach === true && isReadyToChainAttach === false) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius * 2.5 let OPACITY = availableToChainAttachCounter / 10 browserCanvasContext.beginPath() @@ -1839,7 +1839,7 @@ function newUiObject() { } if (isReadyToReferenceAttach === true) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + readyToReferenceAttachDisplayCounter - readyToReferenceAttachDisplayCounter / 2 + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius * 2.5 + readyToReferenceAttachDisplayCounter - readyToReferenceAttachDisplayCounter / 2 let OPACITY = readyToReferenceAttachCounter / 10 browserCanvasContext.beginPath() @@ -1868,7 +1868,7 @@ function newUiObject() { } if (isAvailableToReferenceAttach === true && isReadyToReferenceAttach === false) { - VISIBLE_RADIUS = thisObject.container.frame.radius * 2.5 + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius * 2.5 let OPACITY = availableToReferenceAttachCounter / 10 browserCanvasContext.beginPath() @@ -1921,8 +1921,8 @@ function newUiObject() { if (executingIcon !== undefined) { if (executingIcon.canDrawIcon === true) { if (isRunningAtBackend === true) { - const DISTANCE_FROM_CENTER = thisObject.container.frame.radius / 3 + 50 - const EXECUTING_ICON_SIZE = 20 + thisObject.container.frame.radius / 6 + const DISTANCE_FROM_CENTER = thisObject.payload.floatingObject.container.frame.radius / 3 + 50 + const EXECUTING_ICON_SIZE = 20 + thisObject.payload.floatingObject.container.frame.radius / 6 browserCanvasContext.drawImage( executingIcon, position.x - EXECUTING_ICON_SIZE / 2, From 1c09156478d1f515a9d43d73f4e697f7e4fb85f3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 28 Aug 2020 20:30:06 +0200 Subject: [PATCH 049/192] node path --- .../Workspace/FunctionLibraries/NodePath.js | 56 +++++++++++++++++++ DesignSpace/Workspace/Workspace.js | 14 ++++- Utilities/Clipboard.js | 35 ++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 DesignSpace/Workspace/FunctionLibraries/NodePath.js create mode 100644 Utilities/Clipboard.js diff --git a/DesignSpace/Workspace/FunctionLibraries/NodePath.js b/DesignSpace/Workspace/FunctionLibraries/NodePath.js new file mode 100644 index 000000000..02dc6362c --- /dev/null +++ b/DesignSpace/Workspace/FunctionLibraries/NodePath.js @@ -0,0 +1,56 @@ +function newNodePath() { + thisObject = { + getNodePath: getNodePath + } + + return thisObject + + function getNodePath(node) { + + let nodePath = 'value' + + recursiveGet(node) + + return 'tradingEngine.' + nodePath + + function recursiveGet(node) { + + if (node.payload === undefined) { return } + if (node.payload.parentNode === undefined) { return } + + let nodeDefinition = getNodeDefinition(node.payload.parentNode) + if (nodeDefinition === undefined) { return } + if (nodeDefinition.properties === undefined) { return } + + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + let parentProperty = node.payload.parentNode[property.name] + if (parentProperty === undefined) { continue } + + switch (property.type) { + case 'node': { + if (parentProperty.id === node.id) { + /* We found it */ + nodePath = property.name + '.' + nodePath + recursiveGet(node.payload.parentNode) + } + } + break + case 'array': { + for (let j = 0; j < parentProperty.length; j++) { + let arrayProperty = parentProperty[j] + if (arrayProperty === undefined) {continue} + if (arrayProperty.id === node.id) { + /* We found it */ + nodePath = property.name + '[' + j + ']' + '.' + nodePath + recursiveGet(node.payload.parentNode) + } + } + } + break + } + } + } + } +} diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 1fc06b306..db4879ff6 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -64,6 +64,7 @@ function newWorkspace() { let functionLibraryCCXTFunctions = newCCXTFunctions() let functionLibraryWebhookFunctions = newWebhookFunctions() let functionLibraryDependenciesFilter = newDependenciesFilter() + let functionLibraryNodePath = newNodePath() thisObject.nodeChildren = newNodeChildren() @@ -323,7 +324,7 @@ function newWorkspace() { if (stringifyReadyNodes.length > 0) { return JSON.stringify(workspace) } else { - return + return } } @@ -454,6 +455,17 @@ function newWorkspace() { async function onMenuItemClick(payload, action, relatedUiObject, callBackFunction) { switch (action) { + case 'Copy Node Path': + { + let nodePath = functionLibraryNodePath.getNodePath(payload.node) + + copyTextToClipboard(nodePath) + + canvas.cockpitSpace.setStatus( + nodePath + ' copied to the Clipboard.' + , 50, canvas.cockpitSpace.statusTypes.ALL_GOOD) + } + break case 'Add UI Object': { functionLibraryUiObjectsFromNodes.addUIObject(payload.node, relatedUiObject) diff --git a/Utilities/Clipboard.js b/Utilities/Clipboard.js new file mode 100644 index 000000000..d6af25c88 --- /dev/null +++ b/Utilities/Clipboard.js @@ -0,0 +1,35 @@ +function fallbackCopyTextToClipboard(text) { + var textArea = document.createElement("textarea"); + textArea.value = text; + + // Avoid scrolling to bottom + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + var successful = document.execCommand('copy'); + var msg = successful ? 'successful' : 'unsuccessful'; + //console.log('Fallback: Copying text command was ' + msg); + } catch (err) { + console.error('Fallback: Oops, unable to copy', err); + } + + document.body.removeChild(textArea); +} + +function copyTextToClipboard(text) { + if (!navigator.clipboard) { + fallbackCopyTextToClipboard(text); + return; + } + navigator.clipboard.writeText(text).then(function() { + //console.log('Async: Copying to clipboard was successful!'); + }, function(err) { + console.error('Async: Could not copy text: ', err); + }); +} \ No newline at end of file From ffe97c3726ce93605ab6eb58b274fae3ccfd0c74 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 28 Aug 2020 22:48:18 +0200 Subject: [PATCH 050/192] Update CircularProgressBar.js --- FloatingSpace/CircularProgressBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/CircularProgressBar.js b/FloatingSpace/CircularProgressBar.js index afa76606d..348411ea0 100644 --- a/FloatingSpace/CircularProgressBar.js +++ b/FloatingSpace/CircularProgressBar.js @@ -110,7 +110,7 @@ function newCircularProgressBar() { if (canvas.floatingSpace.inMapMode === true) { return } if (needToDrawRing !== true) { return } - const VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5 + const VISIBLE_RADIUS = thisObject.container.frame.radius let visiblePosition = { x: thisObject.container.frame.position.x, From 0183cf850c099e3b772589a4877c880f94b1e87a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 29 Aug 2020 10:48:13 +0200 Subject: [PATCH 051/192] Update LayersPanel.js --- Panels/LayersPanel.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Panels/LayersPanel.js b/Panels/LayersPanel.js index 11d165da5..fc8438d73 100644 --- a/Panels/LayersPanel.js +++ b/Panels/LayersPanel.js @@ -405,6 +405,8 @@ function newLayersPanel() { function removeFromLocalLayers(id) { for (let i = 0; i < localLayers.length; i++) { let layer = localLayers[i] + if (layer.payload === undefined) {continue} + if (layer.payload.node === undefined) {continue} if (layer.payload.node.id === id) { thisObject.layers.push(layer) localLayers.splice(i, 1) From 077b8cb865b7ecc653beebb4a7fb2874ea9f2aa5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 29 Aug 2020 13:38:01 +0200 Subject: [PATCH 052/192] Warniings & Infos --- ChartingSpace/PlottersManager.js | 32 ++++++ FloatingSpace/UiObject.js | 167 ++++++++++++++++++++++++++++++- Panels/Layer.js | 2 +- Plotting/NodesInfos.js | 47 +++++++++ Plotting/NodesWarnings.js | 47 +++++++++ 5 files changed, 291 insertions(+), 4 deletions(-) create mode 100644 Plotting/NodesInfos.js create mode 100644 Plotting/NodesWarnings.js diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index 458a2599b..5338823ad 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -271,6 +271,30 @@ function newPlottersManager() { } connector.nodesErrors.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesErrors.onRecordChange) } + if (plotterModule.nodesWarnings !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesWarnings = newNodesWarnings() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesWarnings.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesWarnings.initialize(tradingEngine) + break + } + connector.nodesWarnings.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesWarnings.onRecordChange) + } + if (plotterModule.nodesInfos !== undefined && plotterModule.config.connectTo !== undefined) { + connector.nodesInfos = newNodesInfos() + switch (plotterModule.config.connectTo) { + case 'Trading System': + connector.nodesInfos.initialize(tradingSystem) + break + case 'Trading Engine': + connector.nodesInfos.initialize(tradingEngine) + break + } + connector.nodesInfos.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesInfos.onRecordChange) + } if (plotterModule.nodesRunning !== undefined && plotterModule.config.connectTo !== undefined) { connector.nodesRunning = newNodesRunning() switch (plotterModule.config.connectTo) { @@ -392,6 +416,14 @@ function newPlottersManager() { connector.plotter.container.eventHandler.stopListening(connector.nodesErrors.onRecordChangeEventsSubscriptionId) connector.nodesErrors.finalize() } + if (connector.nodesWarnings !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesWarnings.onRecordChangeEventsSubscriptionId) + connector.nodesWarnings.finalize() + } + if (connector.nodesInfos !== undefined) { + connector.plotter.container.eventHandler.stopListening(connector.nodesInfos.onRecordChangeEventsSubscriptionId) + connector.nodesInfos.finalize() + } if (connector.nodesStatus !== undefined) { connector.plotter.container.eventHandler.stopListening(connector.nodesStatus.onRecordChangeEventsSubscriptionId) connector.nodesStatus.finalize() diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index abb67de11..e3cc02d78 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -24,6 +24,8 @@ function newUiObject() { shortcutKey: undefined, isShowing: undefined, hasError: undefined, + hasWarning: undefined, + hasInfo: undefined, run: run, stop: stop, heartBeat: heartBeat, @@ -35,6 +37,10 @@ function newUiObject() { runningAtBackend: runningAtBackend, setErrorMessage: setErrorMessage, resetErrorMessage: resetErrorMessage, + setWarningMessage: setWarningMessage, + resetWarningMessage: resetWarningMessage, + setInfoMessage: setInfoMessage, + resetInfoMessage: resetInfoMessage, setValue: setValue, resetValue: resetValue, setPercentage: setPercentage, @@ -76,6 +82,8 @@ function newUiObject() { let runningAtBackendCounter = 0 let errorMessageCounter = 0 + let warningMessageCounter = 0 + let infoMessageCounter = 0 let hasValue let valueCounter = 0 @@ -109,6 +117,9 @@ function newUiObject() { let isDragging = false let errorMessage = '' + let warningMessage = '' + let infoMessage = '' + let currentValue = 0 let valueMinDecimals = undefined let currentPercentage = '' @@ -327,6 +338,8 @@ function newUiObject() { highlightPhisycs() runningAtBackendPhisycs() errorMessagePhisycs() + warningMessagePhisycs() + infoMessagePhisycs() valuePhisycs() percentagePhisycs() statusPhisycs() @@ -694,6 +707,22 @@ function newUiObject() { } } + function warningMessagePhisycs() { + warningMessageCounter-- + if (warningMessageCounter < 0) { + warningMessageCounter = 0 + thisObject.hasWarning = false + } + } + + function infoMessagePhisycs() { + infoMessageCounter-- + if (infoMessageCounter < 0) { + infoMessageCounter = 0 + thisObject.hasInfo = false + } + } + function valuePhisycs() { valueCounter-- if (valueCounter < 0) { @@ -767,6 +796,76 @@ function newUiObject() { thisObject.hasError = false } + function setWarningMessage(message, duration) { + if (message !== undefined) { + warningMessage = message + thisObject.hasWarning = true + if (duration === undefined) { duration = 1 } + warningMessageCounter = 100 * duration + + /* + Next, we are going to try to inform the parent that this + node has an warning, as a way to show the end user where the + node with warning is. This is useful to detect warnings in nodes + that are located at braches that are collapsed. + */ + + if (thisObject.payload !== undefined) { + if (thisObject.payload.parentNode !== undefined) { + if (thisObject.payload.parentNode.payload !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) { + if (thisObject.payload.parentNode.payload.uiObject !== true) { + thisObject.payload.parentNode.payload.uiObject.setWarningMessage('Warning Inside this Branch') + } + } + } + } + } + } + } + } + + function resetWarningMessage() { + warningMessage = undefined + thisObject.hasWarning = false + } + + function setInfoMessage(message, duration) { + if (message !== undefined) { + infoMessage = message + thisObject.hasInfo = true + if (duration === undefined) { duration = 1 } + infoMessageCounter = 100 * duration + + /* + Next, we are going to try to inform the parent that this + node has an info, as a way to show the end user where the + node with info is. This is useful to detect infos in nodes + that are located at braches that are collapsed. + */ + + if (thisObject.payload !== undefined) { + if (thisObject.payload.parentNode !== undefined) { + if (thisObject.payload.parentNode.payload !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) { + if (thisObject.payload.parentNode.payload.uiObject !== true) { + thisObject.payload.parentNode.payload.uiObject.setInfoMessage('Info Inside this Branch') + } + } + } + } + } + } + } + } + + function resetInfoMessage() { + infoMessage = undefined + thisObject.hasInfo = false + } + function setValue(value, counter, minDecimals) { if (value !== undefined) { currentValue = value @@ -837,6 +936,8 @@ function newUiObject() { function run(pEventsServerClient, callBackFunction) { finalizeEventsServerClient() resetErrorMessage() + resetWarningMessage() + resetInfoMessage() resetPercentage() resetValue() resetStatus() @@ -1090,6 +1191,8 @@ function newUiObject() { if (thisObject.isOnFocus === false) { drawBodyAndPicture() drawErrorMessage() + drawWarningMessage() + drawInfoMessage() drawValue() drawPercentage() drawStatus() @@ -1170,6 +1273,8 @@ function newUiObject() { } drawErrorMessage() + drawWarningMessage() + drawInfoMessage() drawValue() drawPercentage() drawStatus() @@ -1389,6 +1494,24 @@ function newUiObject() { function drawErrorMessage() { if (thisObject.hasError === false) { return } + drawMessage(errorMessage) + } + + function drawWarningMessage() { + if (thisObject.hasError === true) { return } + if (thisObject.hasWarning !== true) { return } + drawMessage(warningMessage) + } + + function drawInfoMessage() { + if (thisObject.hasError === true) { return } + if (thisObject.hasWarning === true) { return } + if (thisObject.hasInfo !== true) { return } + drawMessage(infoMessage) + } + + function drawMessage(message) { + if (canvas.floatingSpace.inMapMode === true) { return } @@ -1414,7 +1537,7 @@ function newUiObject() { if (radius > 6) { const MAX_LABEL_LENGTH = 80 - label = errorMessage + label = message if (label !== undefined && label !== null) { if (label.length > MAX_LABEL_LENGTH) { @@ -1695,7 +1818,7 @@ function newUiObject() { let nodeDefinition = getNodeDefinition(thisObject.payload.node) if (nodeDefinition === undefined) { - console.log('Node ' + thisObject.payload.node + ' without Node Definition at APP SCHEMA.') + console.log('Node ' + thisObject.payload.node + ' without Node Definition at APP SCHEMA.') return } @@ -1708,7 +1831,13 @@ function newUiObject() { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.70)' browserCanvasContext.fill() /* Border when node is in focus */ - if (thisObject.hasError !== true && nodeDefinition.isHierarchyHead !== true && thisObject.circularProgressBar === undefined) { + if ( + thisObject.hasError !== true && + thisObject.WarningError !== true && + thisObject.hasInfo !== true && + nodeDefinition.isHierarchyHead !== true && + thisObject.circularProgressBar === undefined + ) { browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() @@ -1757,7 +1886,39 @@ function newUiObject() { browserCanvasContext.stroke() } + /* Info Ring */ + if (thisObject.hasInfo === true) { + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius + if (canvas.floatingSpace.inMapMode === true) { + VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) + } + let OPACITY = infoMessageCounter / 30 + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 5 + browserCanvasContext.setLineDash([5, 10]) + browserCanvasContext.stroke() + } + /* Warning Ring */ + if (thisObject.hasWarning === true) { + VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius + if (canvas.floatingSpace.inMapMode === true) { + VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) + } + let OPACITY = warningMessageCounter / 30 + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = 5 + browserCanvasContext.setLineDash([5, 10]) + browserCanvasContext.stroke() + } + + /* Error Ring */ if (thisObject.hasError === true) { VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius if (canvas.floatingSpace.inMapMode === true) { diff --git a/Panels/Layer.js b/Panels/Layer.js index 0605b5355..edb0ccba7 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -177,7 +177,7 @@ function newLayer() { 'Image->Image Condition->Image Position->Point->' + 'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' + 'Plotter Panel->Javascript Code->Panel Data->Data Formula->' + - 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' + 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Warnings->Nodes Infos->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) /* Here we validate that we have all the needed information */ diff --git a/Plotting/NodesInfos.js b/Plotting/NodesInfos.js new file mode 100644 index 000000000..2009596aa --- /dev/null +++ b/Plotting/NodesInfos.js @@ -0,0 +1,47 @@ +function newNodesInfos() { + const MODULE_NAME = 'Nodes Infos' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME + + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize + } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.infos + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === '') { + node.payload.uiObject.resetInfoMessage() + } else { + node.payload.uiObject.setInfoMessage(value) + } + } +} diff --git a/Plotting/NodesWarnings.js b/Plotting/NodesWarnings.js new file mode 100644 index 000000000..8e09ebe08 --- /dev/null +++ b/Plotting/NodesWarnings.js @@ -0,0 +1,47 @@ +function newNodesWarnings() { + const MODULE_NAME = 'Nodes Warnings' + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME + + let thisObject = { + onRecordChange: onRecordChange, + initialize: initialize, + finalize: finalize + } + let hiriarchyMap + return thisObject + + function finalize() { + hiriarchyMap = undefined + } + + function initialize(pRootNode) { + let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id) + hiriarchyMap = getHiriarchyMap(rootNode) + } + + function onRecordChange(currentRecord) { + if (currentRecord === undefined) { return } + let array = currentRecord.warnings + if (array === undefined) { return } + for (let i = 0; i < array.length; i++) { + let arrayItem = array[i] + let nodeId = arrayItem[0] + let value = arrayItem[1] + applyValue(nodeId, value) + } + } + + function applyValue(nodeId, value) { + if (canvas.chartingSpace.visible !== true) { return } + let node = hiriarchyMap.get(nodeId) + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (value === '') { + node.payload.uiObject.resetWarningMessage() + } else { + node.payload.uiObject.setWarningMessage(value) + } + } +} From ee4bb2a8934d839568ff0db691cf7664c252a0a2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 29 Aug 2020 16:45:53 +0200 Subject: [PATCH 053/192] online Warnings and Info --- FloatingSpace/UiObject.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index e3cc02d78..7e17106e3 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -127,8 +127,11 @@ function newUiObject() { let rightDragging = false let eventSubscriptionIdOnError + let eventSubscriptionIdOnWarning + let eventSubscriptionIdOnInfo let eventSubscriptionIdOnRunning let eventSubscriptionIdOnStopped + let lastHeartBeat let onRunningCallBackFunction let onRunningCallBackFunctionWasCalled = false @@ -201,6 +204,12 @@ function newUiObject() { if (eventSubscriptionIdOnError !== undefined) { eventsServerClient.stopListening(key, eventSubscriptionIdOnError, 'UiObject') } + if (eventSubscriptionIdOnWarning !== undefined) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnWarning, 'UiObject') + } + if (eventSubscriptionIdOnInfo !== undefined) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnInfo, 'UiObject') + } } } @@ -955,6 +964,8 @@ function newUiObject() { setupRunningEventListener(callBackFunction) setupErrorEventListener(callBackFunction) + setupWarningEventListener() + setupInfoEventListener() } function setupRunningEventListener(callBackFunction) { @@ -1017,6 +1028,32 @@ function newUiObject() { } } + function setupWarningEventListener() { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Warning', undefined, key, onResponse, onWarning) + + function onResponse(message) { + eventSubscriptionIdOnWarning = message.eventSubscriptionId + } + + function onWarning(message) { + setWarningMessage(message.event.warningMessage, 10) + } + } + + function setupInfoEventListener() { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Info', undefined, key, onResponse, onInfo) + + function onResponse(message) { + eventSubscriptionIdOnInfo = message.eventSubscriptionId + } + + function onInfo(message) { + setInfoMessage(message.event.infoMessage, 10) + } + } + function stop(callBackFunction, event) { /* We will wait to the event that the execution was terminated in order to call back the menu item */ let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id From d5de76c3c688fe12a57c4281dbb4820f9458ae4b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 29 Aug 2020 17:48:22 +0200 Subject: [PATCH 054/192] real time errors, warnings and infos --- .../FunctionLibraries/UiObjectsFromNodes.js | 5 +++ DesignSpace/Workspace/Workspace.js | 5 +++ FloatingSpace/UiObject.js | 45 +++++++++++++------ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 10edaa3a4..f76a584d9 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -3,6 +3,7 @@ function newUiObjectsFromNodes() { runTasks: runTasks, runSessions: runSessions, recreateWorkspace: recreateWorkspace, + getNodeById: getNodeById, tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents, createUiObjectFromNode: createUiObjectFromNode, addUIObject: addUIObject, @@ -16,6 +17,10 @@ function newUiObjectsFromNodes() { return thisObject + function getNodeById(nodeId) { + return mapOfNodes.get(nodeId) + } + function recreateWorkspace(node, callBackFunction) { mapOfNodes = new Map() tasksToRun = [] diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index db4879ff6..a639b464b 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -17,6 +17,7 @@ function newWorkspace() { getHierarchyHeadsById: getHierarchyHeadsById, getNodeThatIsOnFocus: getNodeThatIsOnFocus, getNodeByShortcutKey: getNodeByShortcutKey, + getNodeById: getNodeById, stopAllRunningTasks: stopAllRunningTasks, onMenuItemClick: onMenuItemClick, physics: physics, @@ -226,6 +227,10 @@ function newWorkspace() { } } + function getNodeById(nodeId) { + return functionLibraryUiObjectsFromNodes.getNodeById(nodeId) + } + function physics() { eventsServerClientsPhysics() replacingWorkspacePhysics() diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 7e17106e3..502ffb08d 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -347,8 +347,8 @@ function newUiObject() { highlightPhisycs() runningAtBackendPhisycs() errorMessagePhisycs() - warningMessagePhisycs() - infoMessagePhisycs() + warningMessagePhisycs() + infoMessagePhisycs() valuePhisycs() percentagePhisycs() statusPhisycs() @@ -1010,6 +1010,21 @@ function newUiObject() { stop(callBackFunction, event) } + function getTargetUiObject(message) { + let uiObject = thisObject + if (message.event.nodeId !== undefined) { + let targetNode = canvas.designSpace.workspace.getNodeById(message.event.nodeId) + if (targetNode !== undefined) { + if (targetNode.payload !== undefined) { + if (targetNode.payload.uiObject !== undefined) { + uiObject = targetNode.payload.uiObject + } + } + } + } + return uiObject + } + function setupErrorEventListener(callBackFunction) { let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError) @@ -1019,7 +1034,9 @@ function newUiObject() { } function onError(message) { - setErrorMessage(message.event.errorMessage, 10) + + let uiObject = getTargetUiObject(message) + uiObject.setErrorMessage(message.event.errorMessage, 10) let event = { type: 'Secondary Action Already Executed' @@ -1037,7 +1054,8 @@ function newUiObject() { } function onWarning(message) { - setWarningMessage(message.event.warningMessage, 10) + let uiObject = getTargetUiObject(message) + uiObject.setWarningMessage(message.event.warningMessage, 10) } } @@ -1050,7 +1068,8 @@ function newUiObject() { } function onInfo(message) { - setInfoMessage(message.event.infoMessage, 10) + let uiObject = getTargetUiObject(message) + uiObject.setInfoMessage(message.event.infoMessage, 10) } } @@ -1531,20 +1550,20 @@ function newUiObject() { function drawErrorMessage() { if (thisObject.hasError === false) { return } - drawMessage(errorMessage) + drawMessage(errorMessage) } function drawWarningMessage() { if (thisObject.hasError === true) { return } if (thisObject.hasWarning !== true) { return } - drawMessage(warningMessage) + drawMessage(warningMessage) } function drawInfoMessage() { if (thisObject.hasError === true) { return } if (thisObject.hasWarning === true) { return } if (thisObject.hasInfo !== true) { return } - drawMessage(infoMessage) + drawMessage(infoMessage) } function drawMessage(message) { @@ -1869,12 +1888,12 @@ function newUiObject() { browserCanvasContext.fill() /* Border when node is in focus */ if ( - thisObject.hasError !== true && - thisObject.WarningError !== true && - thisObject.hasInfo !== true && - nodeDefinition.isHierarchyHead !== true && + thisObject.hasError !== true && + thisObject.WarningError !== true && + thisObject.hasInfo !== true && + nodeDefinition.isHierarchyHead !== true && thisObject.circularProgressBar === undefined - ) { + ) { browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) browserCanvasContext.closePath() From a23e17244aa05ee3ae387e0b446cdf6664390631 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 29 Aug 2020 20:25:41 +0200 Subject: [PATCH 055/192] cleaning --- FloatingSpace/FloatingLayer.js | 6 ------ FloatingSpace/FloatingObject.js | 3 +++ FloatingSpace/UiObject.js | 1 + 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index bb59a9a7c..95aec16f9 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -74,12 +74,6 @@ function newFloatingLayer() { if (container !== undefined) { return container } } - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - container = floatingObject.getContainer(point) - if (container !== undefined) { return container } - } - return container } diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 79bb44217..a89979978 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -111,9 +111,12 @@ function newFloatingObject() { } function getContainer(point) { + + if (thisObject.payload === undefined) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { return } if (canvas.floatingSpace.inMapMode === true) { return } + let container container = thisObject.payload.uiObject.getContainer(point) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 502ffb08d..3b7ab2109 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -242,6 +242,7 @@ function newUiObject() { } function getContainer(point) { + let container if (isDragging === false && thisObject.isOnFocus === true) { From 89f3e4b5988196a18008ce750889be3ab9abfcb7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 30 Aug 2020 14:02:35 +0200 Subject: [PATCH 056/192] Data Mine Functions --- .../FunctionLibraries/DataMineFunctions.js | 85 +++++++++++++++++++ DesignSpace/Workspace/Workspace.js | 6 ++ 2 files changed, 91 insertions(+) create mode 100644 DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js diff --git a/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js new file mode 100644 index 000000000..bda6c8492 --- /dev/null +++ b/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js @@ -0,0 +1,85 @@ +function newDataMineFunctions() { + thisObject = { + addMissingOutputDatasets: addMissingOutputDatasets + } + + return thisObject + + function addMissingOutputDatasets(node, functionLibraryUiObjectsFromNodes) { + + /* Validations to see if we can do this or not. */ + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (node.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a parent node to execute this action.') + return + } + if (node.payload.parentNode.payload === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a parent node to execute this action.') + return + } + if (node.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a grand parent node to execute this action.') + return + } + + /* + Next, we are going to scan recursively through all nodes of type Product Definition Folder + and Product Definition. For each Product Definition Folder we will create a counterpart + Output Dataset Folder, and for each Product Definition found we will create a Output Definition + for each Dataset defined inside the Product Definition. + */ + scanForProductDefinitions(node.payload.parentNode.payload.parentNode, node) + + function scanForProductDefinitions(originNode, destinationNode) { + if (originNode === undefined) { return } + if (destinationNode === undefined) { return } + + /* Now we go down through all the children of the origin node, recreating at the destination node the same children structure*/ + let nodeDefinition = getNodeDefinition(originNode) + if (nodeDefinition === undefined) { return } + + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.name) { + case 'products': { + let originNodePropertyArray = originNode[property.name] + for (let m = 0; m < originNodePropertyArray.length; m++) { + let originProduct = originNodePropertyArray[m] + for (let n = 0; n < originProduct.datasets.length; n++) { + let datasetDefinition = originProduct.datasets[n] + let outputDataset = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, 'Output Dataset') + outputDataset.payload.referenceParent = datasetDefinition + } + } + break + } + case 'productDefinitionFolders': { + let originNodePropertyArray = originNode[property.name] + let destinationNodePropertyArray = destinationNode['outputDatasetFolders'] + for (let m = 0; m < originNodePropertyArray.length; m++) { + let originFolder = originNodePropertyArray[m] + let found = false + let destinationFolder + for (let n = 0; n < destinationNodePropertyArray.length; n++) { + destinationFolder = destinationNodePropertyArray[n] + if (originFolder.name === destinationFolder.name) { + found = true + } + } + if (found === false) { + destinationFolder = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, 'Output Dataset Folder') + destinationFolder.name = originFolder.name + } + scanForProductDefinitions(originFolder, destinationFolder) + } + break + } + } + } + } + } + } +} diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index a639b464b..bfad80b57 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -66,6 +66,7 @@ function newWorkspace() { let functionLibraryWebhookFunctions = newWebhookFunctions() let functionLibraryDependenciesFilter = newDependenciesFilter() let functionLibraryNodePath = newNodePath() + let functionLibraryDataMineFunctions = newDataMineFunctions() thisObject.nodeChildren = newNodeChildren() @@ -612,6 +613,11 @@ function newWorkspace() { functionLibraryCCXTFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) } break + case 'Add Missing Output Datasets': + { + functionLibraryDataMineFunctions.addMissingOutputDatasets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) + } + break case 'Send Webhook Test Message': { functionLibraryWebhookFunctions.sendTestMessage(payload.node, callBackFunction) From 27130d6ca75afffe099a2f791a019c0d542cbb99 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 30 Aug 2020 16:03:11 +0200 Subject: [PATCH 057/192] APP SCHEMA from session to task --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 1 - DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js | 6 +++++- Panels/Layer.js | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 736649dd3..e46ed99af 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -97,7 +97,6 @@ function newSessionFunctions() { /* Raise event to run the session */ let event = { - appSchema: JSON.stringify(APP_SCHEMA_ARRAY), session: JSON.stringify(session), tradingSystem: JSON.stringify(tradingSystem), tradingEngine: JSON.stringify(tradingEngine), diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 2548a0135..2eb918bdc 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -37,7 +37,10 @@ function newTaskFunctions() { 'Market Base Asset->Market Quoted Asset->Asset->' + 'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' + 'Process Definition->' + - 'Process Output->Output Dataset->Dataset Definition->Product Definition->' + + 'Process Output->' + + 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + + 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + + 'Output Dataset->Dataset Definition->Product Definition->' + 'Process Dependencies->' + 'Status Dependency->Status Report->Process Definition->' + 'Data Dependency->Dataset Definition->Product Definition->' + @@ -73,6 +76,7 @@ function newTaskFunctions() { let networkDefinition = functionLibraryProtocolNode.getProtocolNode(networkNode.payload.parentNode, false, true, true, false, false, networkLightingPath) let event = { + appSchema: JSON.stringify(APP_SCHEMA_ARRAY), taskId: node.id, taskName: node.name, taskDefinition: JSON.stringify(taskDefinition), diff --git a/Panels/Layer.js b/Panels/Layer.js index edb0ccba7..fc2b57572 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -164,6 +164,8 @@ function newLayer() { 'Product Definition->' + 'Sensor Bot->Indicator Bot->Trading Bot->' + 'Data Mine->' + + 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + + 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + 'Dataset Definition->' + 'Record Definition->Record Property->Formula->' + 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + From 327f5f826b9e172e43dff1a3e074bd083c835e14 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 31 Aug 2020 14:37:47 +0200 Subject: [PATCH 058/192] Folders at Data Products and Layers --- .../ChartingSpaceFunctions.js | 50 ++++++++++ .../FunctionLibraries/DataMineFunctions.js | 67 +++---------- .../FunctionLibraries/DataStorageFunctions.js | 65 +++++++++++++ DesignSpace/Workspace/Workspace.js | 21 ++++- Panels/Layer.js | 6 +- Utilities/Folders.js | 93 +++++++++++++++++++ 6 files changed, 241 insertions(+), 61 deletions(-) create mode 100644 DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js create mode 100644 DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js create mode 100644 Utilities/Folders.js diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js new file mode 100644 index 000000000..780a1d497 --- /dev/null +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -0,0 +1,50 @@ +function newChartingSpaceFunctions() { + thisObject = { + addAllDataMineLayers: addAllDataMineLayers + } + + return thisObject + + function addAllDataMineLayers(node, functionLibraryUiObjectsFromNodes) { + + /* Validations to see if we can do this or not. */ + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (node.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a reference parent node to execute this action.') + return + } + if (node.payload.referenceParent.payload === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a reference parent node to execute this action.') + return + } + + /* + We are going to go through the referenced branch and recreate the structure + we find there inside the layers manager. We will end up having at the end + all layers referencing the data products inside the referenced branch. + */ + let dataMine = node.payload.referenceParent + scanBotArray(dataMine.botProducts) + + function scanBotArray(botArray) { + for (let i = 0; i < botArray.length; i++) { + let bot = botArray[i] + let botLayers = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Bot Layers') + botLayers.name = bot.name + + asymetricalFolderStructureCloning( + bot, + botLayers, + 'dataProducts', + 'dataProductFolders', + 'layerFolders', + 'Layer', + 'Layer Folder', + undefined, + functionLibraryUiObjectsFromNodes + ) + } + } + } +} diff --git a/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js index bda6c8492..68f2ba42b 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js @@ -1,11 +1,11 @@ function newDataMineFunctions() { thisObject = { - addMissingOutputDatasets: addMissingOutputDatasets + addAllOutputDatasets: addAllOutputDatasets } return thisObject - function addMissingOutputDatasets(node, functionLibraryUiObjectsFromNodes) { + function addAllOutputDatasets(node, functionLibraryUiObjectsFromNodes) { /* Validations to see if we can do this or not. */ if (node.payload === undefined) { return } @@ -29,57 +29,16 @@ function newDataMineFunctions() { Output Dataset Folder, and for each Product Definition found we will create a Output Definition for each Dataset defined inside the Product Definition. */ - scanForProductDefinitions(node.payload.parentNode.payload.parentNode, node) - - function scanForProductDefinitions(originNode, destinationNode) { - if (originNode === undefined) { return } - if (destinationNode === undefined) { return } - - /* Now we go down through all the children of the origin node, recreating at the destination node the same children structure*/ - let nodeDefinition = getNodeDefinition(originNode) - if (nodeDefinition === undefined) { return } - - if (nodeDefinition.properties !== undefined) { - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.name) { - case 'products': { - let originNodePropertyArray = originNode[property.name] - for (let m = 0; m < originNodePropertyArray.length; m++) { - let originProduct = originNodePropertyArray[m] - for (let n = 0; n < originProduct.datasets.length; n++) { - let datasetDefinition = originProduct.datasets[n] - let outputDataset = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, 'Output Dataset') - outputDataset.payload.referenceParent = datasetDefinition - } - } - break - } - case 'productDefinitionFolders': { - let originNodePropertyArray = originNode[property.name] - let destinationNodePropertyArray = destinationNode['outputDatasetFolders'] - for (let m = 0; m < originNodePropertyArray.length; m++) { - let originFolder = originNodePropertyArray[m] - let found = false - let destinationFolder - for (let n = 0; n < destinationNodePropertyArray.length; n++) { - destinationFolder = destinationNodePropertyArray[n] - if (originFolder.name === destinationFolder.name) { - found = true - } - } - if (found === false) { - destinationFolder = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, 'Output Dataset Folder') - destinationFolder.name = originFolder.name - } - scanForProductDefinitions(originFolder, destinationFolder) - } - break - } - } - } - } - } + asymetricalFolderStructureCloning( + node.payload.parentNode.payload.parentNode, + node, + 'products', + 'productDefinitionFolders', + 'outputDatasetFolders', + 'Output Dataset', + 'Output Dataset Folder', + 'datasets', + functionLibraryUiObjectsFromNodes + ) } } diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js new file mode 100644 index 000000000..37b9b0acb --- /dev/null +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -0,0 +1,65 @@ +function newDataStorageFunctions() { + thisObject = { + addAllDataProducts: addAllDataProducts, + addAllDataMineProducts: addAllDataMineProducts + } + + return thisObject + + function addAllDataProducts(node, functionLibraryUiObjectsFromNodes) { + + /* Validations to see if we can do this or not. */ + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (node.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a reference parent node to execute this action.') + return + } + if (node.payload.referenceParent.payload === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a reference parent node to execute this action.') + return + } + + /* + Next, we are going to scan through all the bots of the Data Mine referenced, and for each bot we will + create a Bots Products node. Later we will scan all the Products Definitions of each bot, and for each one + we will create a Data Product. In case we find Product Definition Folders, we will recreate that structure + too, using in this case Data Product Folders. + */ + let dataMine = node.payload.referenceParent + scanBotArray(dataMine.sensorBots) + scanBotArray(dataMine.indicatorBots) + scanBotArray(dataMine.tradingBots) + + function scanBotArray(botArray) { + for (let i = 0; i < botArray.length; i++) { + let bot = botArray[i] + let botProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Bot Products') + botProducts.name = bot.name + + asymetricalFolderStructureCloning( + bot, + botProducts, + 'products', + 'productDefinitionFolders', + 'dataProductFolders', + 'Data Product', + 'Data Product Folder', + undefined, + functionLibraryUiObjectsFromNodes + ) + } + } + } + + function addAllDataMineProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + + if (rootNode.type === 'Data Mine') { + let dataMineProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Data Mine Products') + dataMineProducts.payload.referenceParent = rootNode + } + } + } +} diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index bfad80b57..4a1d06648 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -67,6 +67,8 @@ function newWorkspace() { let functionLibraryDependenciesFilter = newDependenciesFilter() let functionLibraryNodePath = newNodePath() let functionLibraryDataMineFunctions = newDataMineFunctions() + let functionLibraryDataStorageFunctions = newDataStorageFunctions() + let functionLibraryChartingSpaceFunctions = newChartingSpaceFunctions() thisObject.nodeChildren = newNodeChildren() @@ -613,9 +615,24 @@ function newWorkspace() { functionLibraryCCXTFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) } break - case 'Add Missing Output Datasets': + case 'Add All Output Datasets': { - functionLibraryDataMineFunctions.addMissingOutputDatasets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) + functionLibraryDataMineFunctions.addAllOutputDatasets(payload.node, functionLibraryUiObjectsFromNodes) + } + break + case 'Add All Data Products': + { + functionLibraryDataStorageFunctions.addAllDataProducts(payload.node, functionLibraryUiObjectsFromNodes) + } + break + case 'Add All Data Mine Products': + { + functionLibraryDataStorageFunctions.addAllDataMineProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add All Data Mine Layers': + { + functionLibraryChartingSpaceFunctions.addAllDataMineLayers(payload.node, functionLibraryUiObjectsFromNodes) } break case 'Send Webhook Test Message': diff --git a/Panels/Layer.js b/Panels/Layer.js index fc2b57572..eb04637e3 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -163,9 +163,7 @@ function newLayer() { 'Exchange Markets->Crypto Exchange->' + 'Product Definition->' + 'Sensor Bot->Indicator Bot->Trading Bot->' + - 'Data Mine->' + - 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + - 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + + 'Data Mine->' + 'Dataset Definition->' + 'Record Definition->Record Property->Formula->' + 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + @@ -193,8 +191,6 @@ function newLayer() { if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset === undefined) { return } if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent === undefined) { return } if (thisObject.definition.referenceParent.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent.parentNode.parentNode === undefined) { return } if (thisObject.definition.referenceParent.parentNode.parentNode === undefined) { return } if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode === undefined) { return } if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return } diff --git a/Utilities/Folders.js b/Utilities/Folders.js new file mode 100644 index 000000000..686f1af77 --- /dev/null +++ b/Utilities/Folders.js @@ -0,0 +1,93 @@ + + +function asymetricalFolderStructureCloning( + originNode, + destinationNode, + originObjectsArrayPropertyName, + originFoldersArrayPropertyName, + destinationFoldersArrayPropertyName, + clonedObjectType, + destinationFolderType, + originObjectArrayPropertyName, + functionLibraryUiObjectsFromNodes +) { + /* + This function will scan one branch of the workspace, and recreate + a similar structure in some other place, based on the parameters + sent to the function is what types of nodes are going to be mapped + into which other types. + */ + if (originNode === undefined) { return } + if (destinationNode === undefined) { return } + + /* Now we go down through all the children of the origin node, recreating at the destination node the same children structure*/ + let nodeDefinition = getNodeDefinition(originNode) + if (nodeDefinition === undefined) { return } + + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.name) { + case originObjectsArrayPropertyName: { + let originNodePropertyArray = originNode[property.name] + for (let m = 0; m < originNodePropertyArray.length; m++) { + let originObject = originNodePropertyArray[m] + if (originObjectArrayPropertyName === undefined) { + /* + In this first Use Case, we are going to connect each orgin object clone + to its origin object counter part. + */ + let clonedObject = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, clonedObjectType) + clonedObject.payload.referenceParent = originObject + } else { + /* + In this second Use Case, we are going to connect an inner object that is + inside the origin object at an array. We recognize we have to do this + because we did receive this array proeprty name. + */ + let originObjectArray = originObject[originObjectArrayPropertyName] + for (let n = 0; n < originObjectArray.length; n++) { + let originObjectArrayItem = originObjectArray[n] + let clonedObject = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, clonedObjectType) + clonedObject.payload.referenceParent = originObjectArrayItem + } + } + } + break + } + case originFoldersArrayPropertyName: { + let originNodePropertyArray = originNode[property.name] + let destinationNodePropertyArray = destinationNode[destinationFoldersArrayPropertyName] + for (let m = 0; m < originNodePropertyArray.length; m++) { + let originFolder = originNodePropertyArray[m] + let found = false + let destinationFolder + for (let n = 0; n < destinationNodePropertyArray.length; n++) { + destinationFolder = destinationNodePropertyArray[n] + if (originFolder.name === destinationFolder.name) { + found = true + } + } + if (found === false) { + destinationFolder = functionLibraryUiObjectsFromNodes.addUIObject(destinationNode, destinationFolderType) + destinationFolder.name = originFolder.name + } + asymetricalFolderStructureCloning( + originFolder, + destinationFolder, + originObjectsArrayPropertyName, + originFoldersArrayPropertyName, + destinationFoldersArrayPropertyName, + clonedObjectType, + destinationFolderType, + originObjectArrayPropertyName, + functionLibraryUiObjectsFromNodes + ) + } + break + } + } + } + } +} \ No newline at end of file From 37df768bb3244ca1e8a36638477ca83cf0136460 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 31 Aug 2020 19:06:27 +0200 Subject: [PATCH 059/192] Layers with folders --- ChartingSpace/TimeMachine.js | 5 +- .../FunctionLibraries/ProtocolNode.js | 12 ++ Panels/Layer.js | 117 +++++++++++------- Panels/LayersPanel.js | 5 +- Utilities/Branches.js | 92 ++++++++++++++ Utilities/Folders.js | 2 +- 6 files changed, 184 insertions(+), 49 deletions(-) create mode 100644 Utilities/Branches.js diff --git a/ChartingSpace/TimeMachine.js b/ChartingSpace/TimeMachine.js index 9257df6a8..b9fa5471f 100644 --- a/ChartingSpace/TimeMachine.js +++ b/ChartingSpace/TimeMachine.js @@ -672,8 +672,9 @@ function newTimeMachine() { for (let i = 0; i < thisObject.timelineCharts.length; i++) { let timelinechart = thisObject.timelineCharts[i] if (timelinechart.layersManager !== undefined) { - for (let j = 0; j < timelinechart.layersManager.layers.length; j++) { - let layer = timelinechart.layersManager.layers[j] + let layers = timelinechart.layersManager.layers + for (let j = 0; j < layers.length; j++) { + let layer = layers[j] exchangeMarket = { exchangeName: layer.exchange.name, diff --git a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js index 7284030f1..d339a10e8 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -78,6 +78,8 @@ function newProtocolNode() { let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type) if (newLightingPath !== undefined) { object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) + } else { + let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type) } } if (node.payload.referenceParent !== undefined) { @@ -121,6 +123,16 @@ function newProtocolNode() { let currentNodePosition = lightingPath.indexOf('->' + currentNodeType + '->') let nextNodePosition = lightingPath.indexOf('->' + nextNodeType + '->') + /* + In some situations, the current and next node are of the same type. + When that happens, we need to search for the second instance of that type + at the lighting path. + */ + if (currentNodeType === nextNodeType) { + let tempLightingPath = lightingPath.substring(currentNodePosition + currentNodeType.length, lightingPath.length + 1) + nextNodePosition = tempLightingPath.indexOf('->' + nextNodeType + '->') + } + let newLightingPath = lightingPath.substring(nextNodePosition, lightingPath.length + 1) if (nextNodePosition > currentNodePosition) { diff --git a/Panels/Layer.js b/Panels/Layer.js index eb04637e3..f054d6a62 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -153,7 +153,11 @@ function newLayer() { let functionLibraryProtocolNode = newProtocolNode() let lightingPath = '->Layer->' + - 'Data Product->Single Market Data->Exchange Data Products->' + + 'Data Product->' + + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + + 'Bot Products->Data Mine Products->' + + 'Single Market Data->Exchange Data Products->' + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + @@ -162,6 +166,8 @@ function newLayer() { 'Market Quoted Asset->Asset->' + 'Exchange Markets->Crypto Exchange->' + 'Product Definition->' + + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Sensor Bot->Indicator Bot->Trading Bot->' + 'Data Mine->' + 'Dataset Definition->' + @@ -180,51 +186,80 @@ function newLayer() { 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Warnings->Nodes Infos->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) + /* Without this I can not continue, because I can not even show error. */ + if (thisObject.payload === undefined) { + console.log(MODULE_NAME + ' ' + 'thisObject.payload === undefined') + return + } + if (thisObject.payload.uiObject === undefined) { + console.log(MODULE_NAME + ' ' + 'thisObject.payload.uiObject === undefined') + return + } + if (thisObject.payload.node === undefined) { + console.log(MODULE_NAME + ' ' + 'thisObject.payload.node === undefined') + return + } + /* Here we validate that we have all the needed information */ - if (thisObject.definition.referenceParent === undefined) { return } // Data Product - if (thisObject.definition.referenceParent.parentNode === undefined) { return } // Single Market Data - if (thisObject.definition.referenceParent.parentNode.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode === undefined) { return } + if (findNodeInNodeBranch(thisObject.definition, 'Data Product') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Data Product not Found') + return + } + if (findNodeInNodeBranch(thisObject.definition, 'Product Definition') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') + return + } + if (findNodeInNodeBranch(thisObject.definition, 'Data Mine') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Data Mine not Found') + return + } + if (findNodeInNodeBranch(thisObject.definition, 'Market') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market not Found') + return + } + + thisObject.exchange = findNodeInNodeBranch(thisObject.definition, 'Crypto Exchange') + if (thisObject.exchange === undefined) { + thisObject.payload.uiObject.setErrorMessage('Crypto Exchange not Found') + return + } + + thisObject.baseAsset = findNodeInNodeBranch(thisObject.definition, 'Market Base Asset') + if (thisObject.baseAsset !== undefined) { + thisObject.baseAsset = thisObject.baseAsset.referenceParent + } + if (thisObject.baseAsset === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market Base Asset not Found') + return + } + + thisObject.quotedAsset = findNodeInNodeBranch(thisObject.definition, 'Market Quoted Asset') + if (thisObject.quotedAsset !== undefined) { + thisObject.quotedAsset = thisObject.quotedAsset.referenceParent + } + if (thisObject.quotedAsset === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') + return + } + + thisObject.plotterModule = findNodeInNodeBranch(thisObject.definition, 'Plotter Module') + if (thisObject.plotterModule === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') + return + } + + thisObject.networkNode = findNodeInNodeBranch(thisObject.definition, 'Network Node') + if (thisObject.networkNode === undefined) { + thisObject.payload.uiObject.setErrorMessage('Network Node not Found') + return + } /* Lets listen to our own events to react when we have a Mouse Click */ onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) /* Get ready to draw this layer */ - thisObject.baseAsset = thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent - thisObject.quotedAsset = thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent thisObject.market = thisObject.baseAsset.config.codeName + '/' + thisObject.quotedAsset.config.codeName - thisObject.exchange = thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode - /* Some basic validations. */ - if (thisObject.definition.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.type + ' ' + thisObject.definition.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - if (thisObject.definition.referenceParent.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.type + ' ' + thisObject.definition.referenceParent.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - if (thisObject.definition.referenceParent.referenceParent.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.referenceParent.type + ' ' + thisObject.definition.referenceParent.referenceParent.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - thisObject.plotterModule = thisObject.definition.referenceParent.referenceParent.referenceParent thisObject.exchangeIcon = getIcon(thisObject.exchange) if (thisObject.plotterModule.config.icon !== undefined) { @@ -234,12 +269,6 @@ function newLayer() { thisObject.baseAssetIcon = getIcon(thisObject.baseAsset) thisObject.quotedAssetIcon = getIcon(thisObject.quotedAsset) - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.type === 'Data Storage') { - thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode - } else { - thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode - } - function getIcon(node) { let nodeDefinition = getNodeDefinition(node) let iconName diff --git a/Panels/LayersPanel.js b/Panels/LayersPanel.js index fc8438d73..beb42bad5 100644 --- a/Panels/LayersPanel.js +++ b/Panels/LayersPanel.js @@ -375,8 +375,9 @@ function newLayersPanel() { function syncWithDesignerLayers() { if (thisObject.payload.node === undefined) { return } let layerManager = thisObject.payload.node - for (let p = 0; p < layerManager.layers.length; p++) { - let layerNode = layerManager.layers[p] + let layers = nodeBranchToArray(layerManager, 'Layer') + for (let p = 0; p < layers.length; p++) { + let layerNode = layers[p] let found = removeFromLocalLayers(layerNode.id) if (found !== true) { diff --git a/Utilities/Branches.js b/Utilities/Branches.js new file mode 100644 index 000000000..b82686545 --- /dev/null +++ b/Utilities/Branches.js @@ -0,0 +1,92 @@ +function nodeBranchToArray(node, nodeType) { + /* + This function scans a node branch for a certain node type and + return an array of with all the nodes of that type found. + */ + let resultArray = [] + scanNodeBranch(node, nodeType) + return resultArray + + function scanNodeBranch(startingNode) { + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + if (startingNode.type === nodeType) { + resultArray.push(startingNode) + return + } + + if (nodeDefinition.properties === undefined) { return } + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + scanNodeBranch(startingNode[property.name]) + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + for (let m = 0; m < startingNodePropertyArray.length; m++) { + scanNodeBranch(startingNodePropertyArray[m]) + } + break + } + } + } + } +} + +function findNodeInNodeBranch(node, nodeType) { + /* + This function scans a node branch for a certain node type and + returns the first instance found. + */ + let nodeFound + scanNodeBranch(node, nodeType) + return nodeFound + + function scanNodeBranch(startingNode) { + if (startingNode === undefined) { return } + if (nodeFound !== undefined) { return } + + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + if (startingNode.type === nodeType) { + nodeFound = startingNode + return + } + + /* We scan through this node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + scanNodeBranch(startingNode[property.name]) + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + scanNodeBranch(startingNodePropertyArray[m]) + } + } + break + } + } + } + } + /* We scan parents nodes. */ + if (startingNode.parentNode !== undefined) { + scanNodeBranch(startingNode.parentNode) + } + /* We scan reference parents too. */ + if (startingNode.referenceParent !== undefined) { + scanNodeBranch(startingNode.referenceParent) + } + } +} \ No newline at end of file diff --git a/Utilities/Folders.js b/Utilities/Folders.js index 686f1af77..38cc08666 100644 --- a/Utilities/Folders.js +++ b/Utilities/Folders.js @@ -90,4 +90,4 @@ function asymetricalFolderStructureCloning( } } } -} \ No newline at end of file +} From 30bfc4e3b188e41132972c50c6457bca43e2faa2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 31 Aug 2020 20:04:34 +0200 Subject: [PATCH 060/192] Plotters working with Folders at layers --- ChartingSpace/PlottersManager.js | 36 ++++++------- .../FunctionLibraries/TaskFunctions.js | 1 - Panels/Layer.js | 52 +++++++++++++------ 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index 5338823ad..db9f03754 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -125,17 +125,17 @@ function newPlottersManager() { } } - let baseAsset = layer.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent.config.codeName - let quotedAsset = layer.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let baseAsset = layer.baseAsset.config.codeName + let quotedAsset = layer.quotedAsset.config.codeName let market = { baseAsset: baseAsset, quotedAsset: quotedAsset } - let productDefinition = layer.definition.referenceParent.referenceParent - let bot = layer.definition.referenceParent.referenceParent.parentNode - let dataMine = layer.definition.referenceParent.referenceParent.parentNode.parentNode - let exchange = layer.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode - let plotterModule = layer.definition.referenceParent.referenceParent.referenceParent + let productDefinition = layer.productDefinition + let bot = layer.bot + let dataMine = layer.dataMine + let exchange = layer.exchange + let plotterModule = layer.plotterModule let session let tradingSystem let tradingEngine @@ -144,19 +144,17 @@ function newPlottersManager() { A layer can be referencing a Data Product in two different branches of the Network hiriatchy. In one of those braches we can get the Session node, at the other we Cannot. */ - if (layer.definition.referenceParent.parentNode.parentNode !== undefined) { - if (layer.definition.referenceParent.parentNode.parentNode.type === 'Session Reference') { - if (layer.definition.referenceParent.parentNode.parentNode.referenceParent !== undefined) { - session = layer.definition.referenceParent.parentNode.parentNode.referenceParent + let sessionReference = findNodeInNodeBranch(layer.definition, 'Session Reference') - /* From the session we might be able to reach the Trading System or the Trading Engine */ - if (session.tradingSystemReference !== undefined) { - tradingSystem = session.tradingSystemReference.referenceParent - } - if (session.tradingEngineReference !== undefined) { - tradingEngine = session.tradingEngineReference.referenceParent - } - } + if (sessionReference !== undefined) { + session = sessionReference.referenceParent + + /* From the session we might be able to reach the Trading System or the Trading Engine */ + if (session.tradingSystemReference !== undefined) { + tradingSystem = session.tradingSystemReference.referenceParent + } + if (session.tradingEngineReference !== undefined) { + tradingEngine = session.tradingEngineReference.referenceParent } } diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 2eb918bdc..0db5b5ed0 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -39,7 +39,6 @@ function newTaskFunctions() { 'Process Definition->' + 'Process Output->' + 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + - 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + 'Output Dataset->Dataset Definition->Product Definition->' + 'Process Dependencies->' + 'Status Dependency->Status Report->Process Definition->' + diff --git a/Panels/Layer.js b/Panels/Layer.js index f054d6a62..5a382c213 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -15,6 +15,9 @@ function newLayer() { quotedAsset: undefined, market: undefined, exchange: undefined, + bot: undefined, + productDefinition: undefined, + dataMine: undefined, plotterModule: undefined, exchangeIcon: undefined, plotterTypeIcon: undefined, @@ -130,6 +133,9 @@ function newLayer() { thisObject.baseAssetIcon = undefined thisObject.quotedAssetIcon = undefined thisObject.networkNode = undefined + thisObject.bot = undefined + thisObject.productDefinition = undefined + thisObject.dataMine = undefined } function initialize(callBackFunction) { @@ -155,7 +161,6 @@ function newLayer() { '->Layer->' + 'Data Product->' + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + - 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Bot Products->Data Mine Products->' + 'Single Market Data->Exchange Data Products->' + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + @@ -167,9 +172,8 @@ function newLayer() { 'Exchange Markets->Crypto Exchange->' + 'Product Definition->' + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + - 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Sensor Bot->Indicator Bot->Trading Bot->' + - 'Data Mine->' + + 'Data Mine->' + 'Dataset Definition->' + 'Record Definition->Record Property->Formula->' + 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + @@ -205,24 +209,40 @@ function newLayer() { thisObject.payload.uiObject.setErrorMessage('Data Product not Found') return } - if (findNodeInNodeBranch(thisObject.definition, 'Product Definition') === undefined) { - thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') - return - } - if (findNodeInNodeBranch(thisObject.definition, 'Data Mine') === undefined) { - thisObject.payload.uiObject.setErrorMessage('Data Mine not Found') - return - } if (findNodeInNodeBranch(thisObject.definition, 'Market') === undefined) { thisObject.payload.uiObject.setErrorMessage('Market not Found') return - } + } + + thisObject.productDefinition = findNodeInNodeBranch(thisObject.definition, 'Product Definition') + if (thisObject.productDefinition === undefined) { + thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') + return + } + + thisObject.bot = findNodeInNodeBranch(thisObject.definition, 'Sensor Bot') + if (thisObject.bot === undefined) { + thisObject.bot = findNodeInNodeBranch(thisObject.definition, 'Indicator Bot') + } + if (thisObject.bot === undefined) { + thisObject.bot = findNodeInNodeBranch(thisObject.definition, 'Trading Bot') + } + if (thisObject.bot === undefined) { + thisObject.payload.uiObject.setErrorMessage('Bot not Found') + return + } + + thisObject.dataMine = findNodeInNodeBranch(thisObject.definition, 'Data Mine') + if (thisObject.dataMine === undefined) { + thisObject.payload.uiObject.setErrorMessage('Data Mine not Found') + return + } thisObject.exchange = findNodeInNodeBranch(thisObject.definition, 'Crypto Exchange') if (thisObject.exchange === undefined) { thisObject.payload.uiObject.setErrorMessage('Crypto Exchange not Found') return - } + } thisObject.baseAsset = findNodeInNodeBranch(thisObject.definition, 'Market Base Asset') if (thisObject.baseAsset !== undefined) { @@ -240,19 +260,19 @@ function newLayer() { if (thisObject.quotedAsset === undefined) { thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') return - } + } thisObject.plotterModule = findNodeInNodeBranch(thisObject.definition, 'Plotter Module') if (thisObject.plotterModule === undefined) { thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') return - } + } thisObject.networkNode = findNodeInNodeBranch(thisObject.definition, 'Network Node') if (thisObject.networkNode === undefined) { thisObject.payload.uiObject.setErrorMessage('Network Node not Found') return - } + } /* Lets listen to our own events to react when we have a Mouse Click */ onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) From edc20a1a0ad28f7aa05d30a2b6221a7527a4033e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 1 Sep 2020 10:40:04 +0200 Subject: [PATCH 061/192] Update EventsServerClient.js --- EventsServerClient.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/EventsServerClient.js b/EventsServerClient.js index 8d3c871f2..e76d3f545 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -199,8 +199,14 @@ function newEventsServerClient(networkNode) { } } } else { - networkNode.payload.uiObject.setStatus('Connected to Superalgos Backend via WebSockets.') - retryCommandsPhysics() + if (networkNode !== undefined) { + if (networkNode.payload !== undefined) { + if (networkNode.payload.uiObject !== undefined) { + networkNode.payload.uiObject.setStatus('Connected to Superalgos Backend via WebSockets.') + retryCommandsPhysics() + } + } + } } DEBUG.variable4 = 'Commands Waiting For Confirmation from WS Server: ' + commandsWaitingConfirmation.size From 4239ef1a4064ace4f89bfa95048f8f2007af01cb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 1 Sep 2020 12:48:59 +0200 Subject: [PATCH 062/192] Data Mining Running Again --- ChartingSpace/PlottersManager.js | 2 +- .../FunctionLibraries/TaskFunctions.js | 5 +- Panels/Layer.js | 24 ++++----- Utilities/Branches.js | 54 ------------------- Utilities/Meshes.js | 53 ++++++++++++++++++ 5 files changed, 70 insertions(+), 68 deletions(-) create mode 100644 Utilities/Meshes.js diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index db9f03754..0a0092364 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -144,7 +144,7 @@ function newPlottersManager() { A layer can be referencing a Data Product in two different branches of the Network hiriatchy. In one of those braches we can get the Session node, at the other we Cannot. */ - let sessionReference = findNodeInNodeBranch(layer.definition, 'Session Reference') + let sessionReference = findNodeInNodeMesh(layer.definition, 'Session Reference') if (sessionReference !== undefined) { session = sessionReference.referenceParent diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 0db5b5ed0..a6c7001f4 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -62,7 +62,10 @@ function newTaskFunctions() { let networkLightingPath = '->Network->Network Node->' + 'Data Storage->Session Independent Data->Exchange Data Products->' + - 'Single Market Data->Data Product->Product Definition->' + + 'Single Market Data->' + + 'Data Mine Products->Bot Products->' + + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + + 'Data Product->Product Definition->' + 'Data Mining->Testing Environment->Production Environment->' + 'Exchange Tasks->Crypto Exchange->' + 'Task Manager->Task->' + diff --git a/Panels/Layer.js b/Panels/Layer.js index 5a382c213..dc6d2c20c 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -205,46 +205,46 @@ function newLayer() { } /* Here we validate that we have all the needed information */ - if (findNodeInNodeBranch(thisObject.definition, 'Data Product') === undefined) { + if (findNodeInNodeMesh(thisObject.definition, 'Data Product') === undefined) { thisObject.payload.uiObject.setErrorMessage('Data Product not Found') return } - if (findNodeInNodeBranch(thisObject.definition, 'Market') === undefined) { + if (findNodeInNodeMesh(thisObject.definition, 'Market') === undefined) { thisObject.payload.uiObject.setErrorMessage('Market not Found') return } - thisObject.productDefinition = findNodeInNodeBranch(thisObject.definition, 'Product Definition') + thisObject.productDefinition = findNodeInNodeMesh(thisObject.definition, 'Product Definition') if (thisObject.productDefinition === undefined) { thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') return } - thisObject.bot = findNodeInNodeBranch(thisObject.definition, 'Sensor Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Sensor Bot') if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeBranch(thisObject.definition, 'Indicator Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot') } if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeBranch(thisObject.definition, 'Trading Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot') } if (thisObject.bot === undefined) { thisObject.payload.uiObject.setErrorMessage('Bot not Found') return } - thisObject.dataMine = findNodeInNodeBranch(thisObject.definition, 'Data Mine') + thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Data Mine') if (thisObject.dataMine === undefined) { thisObject.payload.uiObject.setErrorMessage('Data Mine not Found') return } - thisObject.exchange = findNodeInNodeBranch(thisObject.definition, 'Crypto Exchange') + thisObject.exchange = findNodeInNodeMesh(thisObject.definition, 'Crypto Exchange') if (thisObject.exchange === undefined) { thisObject.payload.uiObject.setErrorMessage('Crypto Exchange not Found') return } - thisObject.baseAsset = findNodeInNodeBranch(thisObject.definition, 'Market Base Asset') + thisObject.baseAsset = findNodeInNodeMesh(thisObject.definition, 'Market Base Asset') if (thisObject.baseAsset !== undefined) { thisObject.baseAsset = thisObject.baseAsset.referenceParent } @@ -253,7 +253,7 @@ function newLayer() { return } - thisObject.quotedAsset = findNodeInNodeBranch(thisObject.definition, 'Market Quoted Asset') + thisObject.quotedAsset = findNodeInNodeMesh(thisObject.definition, 'Market Quoted Asset') if (thisObject.quotedAsset !== undefined) { thisObject.quotedAsset = thisObject.quotedAsset.referenceParent } @@ -262,13 +262,13 @@ function newLayer() { return } - thisObject.plotterModule = findNodeInNodeBranch(thisObject.definition, 'Plotter Module') + thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module') if (thisObject.plotterModule === undefined) { thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') return } - thisObject.networkNode = findNodeInNodeBranch(thisObject.definition, 'Network Node') + thisObject.networkNode = findNodeInNodeMesh(thisObject.definition, 'Network Node') if (thisObject.networkNode === undefined) { thisObject.payload.uiObject.setErrorMessage('Network Node not Found') return diff --git a/Utilities/Branches.js b/Utilities/Branches.js index b82686545..71123093d 100644 --- a/Utilities/Branches.js +++ b/Utilities/Branches.js @@ -36,57 +36,3 @@ function nodeBranchToArray(node, nodeType) { } } } - -function findNodeInNodeBranch(node, nodeType) { - /* - This function scans a node branch for a certain node type and - returns the first instance found. - */ - let nodeFound - scanNodeBranch(node, nodeType) - return nodeFound - - function scanNodeBranch(startingNode) { - if (startingNode === undefined) { return } - if (nodeFound !== undefined) { return } - - let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) - if (nodeDefinition === undefined) { return } - - if (startingNode.type === nodeType) { - nodeFound = startingNode - return - } - - /* We scan through this node children */ - if (nodeDefinition.properties !== undefined) { - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] - - switch (property.type) { - case 'node': { - scanNodeBranch(startingNode[property.name]) - } - break - case 'array': { - let startingNodePropertyArray = startingNode[property.name] - if (startingNodePropertyArray !== undefined) { - for (let m = 0; m < startingNodePropertyArray.length; m++) { - scanNodeBranch(startingNodePropertyArray[m]) - } - } - break - } - } - } - } - /* We scan parents nodes. */ - if (startingNode.parentNode !== undefined) { - scanNodeBranch(startingNode.parentNode) - } - /* We scan reference parents too. */ - if (startingNode.referenceParent !== undefined) { - scanNodeBranch(startingNode.referenceParent) - } - } -} \ No newline at end of file diff --git a/Utilities/Meshes.js b/Utilities/Meshes.js new file mode 100644 index 000000000..42d53bea1 --- /dev/null +++ b/Utilities/Meshes.js @@ -0,0 +1,53 @@ +function findNodeInNodeMesh(node, nodeType) { + /* + This function scans a node mesh for a certain node type and + returns the first instance found. + */ + let nodeFound + scanNodeMesh(node, nodeType) + return nodeFound + + function scanNodeMesh(startingNode) { + if (startingNode === undefined) { return } + if (nodeFound !== undefined) { return } + + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + if (startingNode.type === nodeType) { + nodeFound = startingNode + return + } + + /* We scan through this node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + scanNodeMesh(startingNode[property.name]) + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + scanNodeMesh(startingNodePropertyArray[m]) + } + } + break + } + } + } + } + /* We scan parents nodes. */ + if (startingNode.parentNode !== undefined) { + scanNodeMesh(startingNode.parentNode) + } + /* We scan reference parents too. */ + if (startingNode.referenceParent !== undefined) { + scanNodeMesh(startingNode.referenceParent) + } + } +} \ No newline at end of file From b83f1f55cddc463b4d9040ecbea975c7d69783d0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 1 Sep 2020 14:31:49 +0200 Subject: [PATCH 063/192] Update TaskFunctions.js --- DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index a6c7001f4..7ce23ca32 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -54,6 +54,7 @@ function newTaskFunctions() { 'Execution Finished Event->' + 'Execution Started Event->Execution Finished Event->Process Definition->' + 'Sensor Bot->' + + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Indicator Bot->' + 'Trading Bot->' + 'Data Mine->' From 9cc1378fe66bc82ba9106aa7e77762b3a7c92d5d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 1 Sep 2020 20:59:49 +0200 Subject: [PATCH 064/192] Bug fixes --- FloatingSpace/UiObject.js | 7 +++---- Plotting/RecordValues.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 3b7ab2109..7255f1655 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1245,22 +1245,21 @@ function newUiObject() { } function drawMiddleground() { - if (thisObject.isOnFocus === false) { - drawBodyAndPicture() + if (thisObject.isOnFocus === false) { drawErrorMessage() drawWarningMessage() drawInfoMessage() drawValue() drawPercentage() drawStatus() - drawText() thisObject.uiObjectTitle.draw() + drawText() } } function drawForeground() { if (thisObject.isOnFocus === false) { - + drawBodyAndPicture() if (isDragging === false) { thisObject.menu.drawForeground() } diff --git a/Plotting/RecordValues.js b/Plotting/RecordValues.js index 073268fd0..118bcda60 100644 --- a/Plotting/RecordValues.js +++ b/Plotting/RecordValues.js @@ -42,7 +42,7 @@ function newRecordValues() { The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values. */ let productRootNode = productRoot[index] - scanProperties(productRootNode, index) + scanProperties(productDefinition, productRootNode, index) } } else { /* From 457cfed81669d74ab64e93e67601cc82bc0d1141 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 2 Sep 2020 13:16:55 +0200 Subject: [PATCH 065/192] Look and Feel --- FloatingSpace/CircularMenuItem.js | 2 +- FloatingSpace/UiObject.js | 2 +- FloatingSpace/UiObjectConstructor.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 420211e7b..8a1849d4a 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -187,7 +187,7 @@ function newCircularMenuItem() { } } } else { - radiusGrowthFactor = 4 + radiusGrowthFactor = 3.2 } thisObject.container.frame.position.x = diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 7255f1655..8f1c99445 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -417,7 +417,7 @@ function newUiObject() { } } if (totalRunning > 0) { - setValue(totalRunning + ' / ' + children.length + ' Running') + setStatus(totalRunning + ' / ' + children.length + ' Running') thisObject.isRunning = true } else { thisObject.isRunning = false diff --git a/FloatingSpace/UiObjectConstructor.js b/FloatingSpace/UiObjectConstructor.js index 77695128b..218b544d6 100644 --- a/FloatingSpace/UiObjectConstructor.js +++ b/FloatingSpace/UiObjectConstructor.js @@ -488,7 +488,7 @@ function newUiObjectConstructor() { const FRICTION = 0.95 const INITIAL_FRICTION = 0.97 const INITIAL_FONT_SIZE = 12 * 1.5 - const INITIAL_RADIOUS = 100 + const INITIAL_RADIOUS = 70 const INITIAL_IMAGE_SIZE = 80 * 1.2 const INITIAL_HIERARCHY_RING = 20 From ead6abde79608a02060eabf9408af9266c3bd3eb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 2 Sep 2020 18:24:53 +0200 Subject: [PATCH 066/192] Update UiObject.js --- FloatingSpace/UiObject.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 8f1c99445..f15923f03 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1245,7 +1245,7 @@ function newUiObject() { } function drawMiddleground() { - if (thisObject.isOnFocus === false) { + if (thisObject.isOnFocus === false) { drawErrorMessage() drawWarningMessage() drawInfoMessage() @@ -1660,7 +1660,20 @@ function newUiObject() { labelPoint = { x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, - y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + y: position.y + } + + /* We will try to put this value according to the angle to the parent node*/ + if (thisObject.payload !== undefined) { + if (thisObject.payload.angle !== undefined) { + labelPoint.x = labelPoint.x + radius * 7 / 3 * Math.cos(toRadians(thisObject.payload.angle)) + labelPoint.y = labelPoint.y + radius * 7 / 3 * Math.sin(toRadians(thisObject.payload.angle)) + } else { + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, + y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + } + } } browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY From 5fc32f9afde42bcb9a74c6c785cd9d6816309dfa Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 2 Sep 2020 18:47:38 +0200 Subject: [PATCH 067/192] Values --- FloatingSpace/CircularProgressBar.js | 1 + FloatingSpace/UiObject.js | 27 ++++++++++++--------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/FloatingSpace/CircularProgressBar.js b/FloatingSpace/CircularProgressBar.js index 348411ea0..4b3d26888 100644 --- a/FloatingSpace/CircularProgressBar.js +++ b/FloatingSpace/CircularProgressBar.js @@ -68,6 +68,7 @@ function newCircularProgressBar() { if (thisObject.payload.uiObject === undefined) { return } opacityCounters[message.event.seconds] = 2000 if (message.event.processingDate !== undefined) { + thisObject.payload.uiObject.valueAtAngle = false thisObject.payload.uiObject.setValue(message.event.processingDate, 2000) } if (message.event.percentage !== undefined) { diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index f15923f03..fd3cf1fa0 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -26,6 +26,7 @@ function newUiObject() { hasError: undefined, hasWarning: undefined, hasInfo: undefined, + valueAtAngle: true, run: run, stop: stop, heartBeat: heartBeat, @@ -1658,21 +1659,17 @@ function newUiObject() { fontSize = fontSize * 2 / 3 } - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, - y: position.y - } - - /* We will try to put this value according to the angle to the parent node*/ - if (thisObject.payload !== undefined) { - if (thisObject.payload.angle !== undefined) { - labelPoint.x = labelPoint.x + radius * 7 / 3 * Math.cos(toRadians(thisObject.payload.angle)) - labelPoint.y = labelPoint.y + radius * 7 / 3 * Math.sin(toRadians(thisObject.payload.angle)) - } else { - labelPoint = { - x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, - y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 - } + if (thisObject.valueAtAngle === true && thisObject.payload.angle !== undefined) { + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, + y: position.y + } + labelPoint.x = labelPoint.x + radius * 7 / 3 * Math.cos(toRadians(thisObject.payload.angle)) + labelPoint.y = labelPoint.y + radius * 7 / 3 * Math.sin(toRadians(thisObject.payload.angle)) + } else { + labelPoint = { + x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 10, + y: position.y + radius * 7 / 5 + fontSize * FONT_ASPECT_RATIO + 15 } } From 51c584f437bc9845cf6b21d02f5669772238c0f4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 Sep 2020 11:46:35 +0200 Subject: [PATCH 068/192] Update UiObject.js --- FloatingSpace/UiObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index fd3cf1fa0..ced01680d 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -617,7 +617,7 @@ function newUiObject() { let distance = nearby[0] let floatingObject = nearby[1] let nearbyNode = floatingObject.payload.node - if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { + if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0 || compatibleTypes === "->*Any Node*->" ) { if (foundCompatible === false) { if (distance < thisObject.payload.floatingObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { nearbyNode.payload.uiObject.getReadyToReferenceAttach() From ddc3dcbf870946f9316e2a50e5f4485517bfca17 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 Sep 2020 11:55:25 +0200 Subject: [PATCH 069/192] cleaning --- FloatingSpace/UiObject.js | 2 +- Spaces/DesignSpace.js | 16 +--------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index ced01680d..f3b1885dd 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1925,7 +1925,7 @@ function newUiObject() { /* Hierarchy Head Ring */ if (nodeDefinition.isHierarchyHead === true) { - VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 3.8 + VISIBLE_RADIUS = thisObject.payload.floatingObject.currentHierarchyRing * 2.6 if (canvas.floatingSpace.inMapMode === true) { VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS) } diff --git a/Spaces/DesignSpace.js b/Spaces/DesignSpace.js index c745e4fb9..4fb1e1a3f 100644 --- a/Spaces/DesignSpace.js +++ b/Spaces/DesignSpace.js @@ -2,7 +2,6 @@ function newDesignSpace() { const MODULE_NAME = 'Designe Space' let thisObject = { - sidePanel: undefined, container: undefined, iconCollection: undefined, iconByUiObjectType: undefined, @@ -331,24 +330,11 @@ function newDesignSpace() { } function getContainer(point) { - let container - - if (thisObject.sidePanel !== undefined) { - container = thisObject.sidePanel.getContainer(point) - if (container !== undefined) { - container.space = 'Design Space' - return container - } - } - - return + } function draw() { if (canWeDraw === false) { return } - if (thisObject.sidePanel !== undefined) { - thisObject.sidePanel.draw() - } if (thisObject.workspace !== undefined) { thisObject.workspace.draw() } From edc03ee58bd86f66ed1ffc04130748042b0829a6 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 Sep 2020 13:27:17 +0200 Subject: [PATCH 070/192] Cleaning --- Canvas.js | 49 ++++++++++++- SideSpace/SidePanelTab.js | 113 ++++++++++++++++++++++++----- Spaces/DesignSpace.js | 2 +- Spaces/DocSpace.js | 148 ++++++++++++++++++++++++++++++++++++++ Spaces/SideSpace.js | 2 +- Spaces/TopSpace.js | 2 +- SplashScreen.js | 2 +- 7 files changed, 295 insertions(+), 23 deletions(-) create mode 100644 Spaces/DocSpace.js diff --git a/Canvas.js b/Canvas.js index d07cb3823..a31958ad1 100644 --- a/Canvas.js +++ b/Canvas.js @@ -32,6 +32,7 @@ function newCanvas() { eventHandler: undefined, topSpace: undefined, sideSpace: undefined, + docSpace: undefined, chartingSpace: undefined, floatingSpace: undefined, panelsSpace: undefined, @@ -61,6 +62,7 @@ function newCanvas() { function finalize() { try { + thisObject.docSpace.finalize() thisObject.sideSpace.finalize() thisObject.chartingSpace.finalize() thisObject.floatingSpace.finalize() @@ -122,6 +124,9 @@ function newCanvas() { thisObject.sideSpace = newSideSpace() thisObject.sideSpace.initialize() + thisObject.docSpace = newDocSpace() + thisObject.docSpace.initialize() + thisObject.splashScreen = newSplashScreen() let animation = newAnimation() @@ -136,6 +141,7 @@ function newCanvas() { animation.addCallBackFunction('Design Space Physics', thisObject.designSpace.physics) animation.addCallBackFunction('Panels Space Physics', thisObject.panelsSpace.physics) animation.addCallBackFunction('Side Space Physics', thisObject.sideSpace.physics) + animation.addCallBackFunction('Doc Space Physics', thisObject.docSpace.physics) /* Spcaces Drawing */ animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw) @@ -145,6 +151,7 @@ function newCanvas() { animation.addCallBackFunction('Design Space Draw', thisObject.designSpace.draw) animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw) animation.addCallBackFunction('Side Space Draw', thisObject.sideSpace.draw) + animation.addCallBackFunction('Doc Space Draw', thisObject.docSpace.draw) animation.addCallBackFunction('Splash Screen Draw', thisObject.splashScreen.draw) animation.start() } catch (err) { @@ -565,6 +572,20 @@ function newCanvas() { let container + /* We check if the mouse is over an element of the Doc Space / */ + container = thisObject.docSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + if (container !== undefined && container.isDraggeable === false) { + return + } + /* We check if the mouse is over an element of the Side Space / */ container = thisObject.sideSpace.getContainer(point) @@ -694,6 +715,14 @@ function newCanvas() { let container + /* We check if the mouse is over an element of the Doc Space / */ + container = thisObject.docSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + /* We check if the mouse is over an element of the Side Space / */ container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) @@ -836,7 +865,17 @@ function newCanvas() { let container - /* We check if the mouse is over an element of the Designe Space / */ + /* We check if the mouse is over an element of the Doc Space / */ + if (thisObject.docSpace !== undefined) { + container = thisObject.docSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + + /* We check if the mouse is over an element of the Side Space / */ if (thisObject.sideSpace !== undefined) { container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) @@ -944,6 +983,14 @@ function newCanvas() { event.mousePosition = point let container + /* Doc Space */ + container = canvas.docSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + /* Side Space */ container = canvas.sideSpace.getContainer({ x: point.x, y: point.y }) diff --git a/SideSpace/SidePanelTab.js b/SideSpace/SidePanelTab.js index 2d1a2c161..2f162d215 100644 --- a/SideSpace/SidePanelTab.js +++ b/SideSpace/SidePanelTab.js @@ -1,7 +1,8 @@ function newSidePanelTab() { const MODULE_NAME = 'Side Panel Tab' let thisObject = { - pointerDirection: 'left', + screenside: undefined, + pointerDirection: undefined, container: undefined, resize: resize, physics: physics, @@ -12,6 +13,7 @@ function newSidePanelTab() { const TAB_WIDTH = 25 const TAB_HEIGHT = 60 + const ANIMATION_STEP = 100 let isInitialized = false let animation = 'none' @@ -26,7 +28,18 @@ function newSidePanelTab() { return thisObject - function initialize() { + function initialize(screenside) { + thisObject.screenside = screenside + switch (thisObject.screenside) { + case 'left': { + thisObject.pointerDirection = 'left' + break + } + case 'right': { + thisObject.pointerDirection = 'right' + break + } + } thisObject.container.frame.width = TAB_WIDTH thisObject.container.frame.height = TAB_HEIGHT @@ -38,18 +51,43 @@ function newSidePanelTab() { } function resize() { - thisObject.container.frame.position.x = 0 + thisObject.container.parentContainer.frame.width + switch (thisObject.screenside) { + case 'left': { + thisObject.container.frame.position.x = 0 + thisObject.container.parentContainer.frame.width + break + } + case 'right': { + thisObject.container.frame.position.x = 0 - TAB_WIDTH + break + } + } + thisObject.container.frame.position.y = 69 setClosed() } function onMouseClick(event) { - if (thisObject.pointerDirection === 'left') { - animation = 'opening' - thisObject.container.eventHandler.raiseEvent('opening') - } else { - animation = 'closing' - thisObject.container.eventHandler.raiseEvent('closing') + switch (thisObject.screenside) { + case 'left': { + if (thisObject.pointerDirection === 'left') { + animation = 'opening' + thisObject.container.eventHandler.raiseEvent('opening') + } else { + animation = 'closing' + thisObject.container.eventHandler.raiseEvent('closing') + } + break + } + case 'right': { + if (thisObject.pointerDirection === 'left') { + animation = 'closing' + thisObject.container.eventHandler.raiseEvent('closing') + } else { + animation = 'opening' + thisObject.container.eventHandler.raiseEvent('opening') + } + break + } } } @@ -74,11 +112,20 @@ function newSidePanelTab() { } function animate() { - const STEP = 50 if (animation === 'opening') { - xOffset = xOffset + STEP - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + xOffset = xOffset + ANIMATION_STEP + switch (thisObject.screenside) { + case 'left': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + break + } + case 'right': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON - xOffset + break + } + } + if (xOffset >= thisObject.container.parentContainer.frame.width) { setOpened() thisObject.container.eventHandler.raiseEvent('opened') @@ -86,8 +133,18 @@ function newSidePanelTab() { } if (animation === 'closing') { - xOffset = xOffset - STEP - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + xOffset = xOffset - ANIMATION_STEP + switch (thisObject.screenside) { + case 'left': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + break + } + case 'right': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON - xOffset + break + } + } + if (xOffset <= 0) { setClosed() thisObject.container.eventHandler.raiseEvent('closed') @@ -98,16 +155,36 @@ function newSidePanelTab() { function setOpened() { animation = 'none' xOffset = thisObject.container.parentContainer.frame.width - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset thisObject.container.parentContainer.status = 'visible' - thisObject.pointerDirection = 'right' + switch (thisObject.screenside) { + case 'left': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset + thisObject.pointerDirection = 'right' + break + } + case 'right': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON - xOffset + thisObject.pointerDirection = 'left' + break + } + } } function setClosed() { animation = 'none' xOffset = 0 - thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON thisObject.container.parentContainer.status = 'hidden' - thisObject.pointerDirection = 'left' + switch (thisObject.screenside) { + case 'left': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + thisObject.pointerDirection = 'left' + break + } + case 'right': { + thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + thisObject.pointerDirection = 'right' + break + } + } } function arrow() { diff --git a/Spaces/DesignSpace.js b/Spaces/DesignSpace.js index 4fb1e1a3f..a9566741f 100644 --- a/Spaces/DesignSpace.js +++ b/Spaces/DesignSpace.js @@ -312,7 +312,7 @@ function newDesignSpace() { function onImageLoad() { image.canDrawIcon = true } - image.src = window.canvasApp.urlPrefix + PATH + name + '.png' + image.src = PATH + name + '.png' thisObject.iconCollection.set(name, image) } } diff --git a/Spaces/DocSpace.js b/Spaces/DocSpace.js new file mode 100644 index 000000000..586f1b861 --- /dev/null +++ b/Spaces/DocSpace.js @@ -0,0 +1,148 @@ +function newDocSpace() { + const MODULE_NAME = 'Doc Space' + let thisObject = { + sidePanelTab: undefined, + container: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize + } + + let isInitialized = false + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.status = 'hidden' + + resize() + + let openingEventSubscriptionId + let closedEventSubscriptionId + let browserResizedEventSubscriptionId + return thisObject + + function initialize() { + thisObject.sidePanelTab = newSidePanelTab() + thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) + thisObject.sidePanelTab.initialize('right') + + browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + + isInitialized = true + } + + function finalize() { + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) + } + + function resize() { + thisObject.container.frame.width = SIDE_PANEL_WIDTH * 2 + thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT + thisObject.container.frame.position.x = browserCanvas.width + thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT + + if (thisObject.sidePanelTab !== undefined) { + thisObject.sidePanelTab.resize() + } + } + + function getContainer(point, purpose) { + let container + + container = thisObject.sidePanelTab.getContainer(point, purpose) + if (container !== undefined) { return container } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function physics() { + thisObject.sidePanelTab.physics() + } + + function draw() { + if (canWeDraw === false) { return } + if (isInitialized === false) { return } + borders() + thisObject.sidePanelTab.draw() + } + + function borders() { + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: thisObject.container.frame.width, + y: 0 + } + + point3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + point4 = { + x: 0, + y: thisObject.container.frame.height + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + point4 = thisObject.container.frame.frameThisPoint(point4) + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() + + let opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' + browserCanvasContext.fill() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.lineWidth = 0.3 + browserCanvasContext.stroke() + + /* Shadow */ + + if (thisObject.container.status !== 'hidden') { + for (let i = 0; i <= 30; i++) { + opacity = 1 - (i / 300) - 0.95 + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point2.x + i, point2.y) + browserCanvasContext.lineTo(point3.x + i, point3.y) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() + } + } + } +} diff --git a/Spaces/SideSpace.js b/Spaces/SideSpace.js index 145edec11..b44409b0a 100644 --- a/Spaces/SideSpace.js +++ b/Spaces/SideSpace.js @@ -32,7 +32,7 @@ function newSideSpace() { function initialize() { thisObject.sidePanelTab = newSidePanelTab() thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) - thisObject.sidePanelTab.initialize() + thisObject.sidePanelTab.initialize('left') browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) diff --git a/Spaces/TopSpace.js b/Spaces/TopSpace.js index 1e511a780..b387d011e 100644 --- a/Spaces/TopSpace.js +++ b/Spaces/TopSpace.js @@ -35,7 +35,7 @@ function newTopSpace() { function onImageLoad() { image.canDraw = true } - image.src = window.canvasApp.urlPrefix + PATH + name + '.png' + image.src = PATH + name + '.png' } } diff --git a/SplashScreen.js b/SplashScreen.js index ca8662ced..688318ed0 100644 --- a/SplashScreen.js +++ b/SplashScreen.js @@ -43,7 +43,7 @@ function newSplashScreen() { function onImageLoad() { canDrawLogo = true } - logo.src = window.canvasApp.urlPrefix + 'Images/superalgos-logo.png' + logo.src = 'Images/superalgos-logo.png' canvas.eventHandler.listenToEvent('Browser Resized', resize) isInitialized = true From 9aa7bb91817a843ffad36079738bf29ab40d809d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 Sep 2020 14:30:19 +0200 Subject: [PATCH 071/192] Intgrading the docs --- DesignSpace/Workspace/Workspace.js | 3 +-- SideSpace/SidePanelTab.js | 12 ++++++++++- Spaces/DocSpace.js | 32 +++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 4a1d06648..875e0214c 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -685,8 +685,7 @@ function newWorkspace() { let definition = getNodeDefinition(payload.node) if (definition !== undefined) { if (definition.docURL !== undefined) { - let newTab = window.open(definition.docURL, '_blank') - newTab.focus() + canvas.docSpace.navigateTo(definition.docURL) } } } diff --git a/SideSpace/SidePanelTab.js b/SideSpace/SidePanelTab.js index 2f162d215..ac331dae0 100644 --- a/SideSpace/SidePanelTab.js +++ b/SideSpace/SidePanelTab.js @@ -4,6 +4,8 @@ function newSidePanelTab() { screenside: undefined, pointerDirection: undefined, container: undefined, + open: open, + close: close, resize: resize, physics: physics, draw: draw, @@ -61,11 +63,19 @@ function newSidePanelTab() { break } } - + thisObject.container.frame.position.y = 69 setClosed() } + function open() { + animation = 'opening' + } + + function close() { + animation = 'closing' + } + function onMouseClick(event) { switch (thisObject.screenside) { case 'left': { diff --git a/Spaces/DocSpace.js b/Spaces/DocSpace.js index 586f1b861..b00cdfff8 100644 --- a/Spaces/DocSpace.js +++ b/Spaces/DocSpace.js @@ -3,6 +3,7 @@ function newDocSpace() { let thisObject = { sidePanelTab: undefined, container: undefined, + navigateTo: navigateTo, physics: physics, draw: draw, getContainer: getContainer, @@ -43,8 +44,14 @@ function newDocSpace() { thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) } + function navigateTo(url) { + let docIFrame = document.getElementById('docIFrame') + docIFrame.src = url + thisObject.sidePanelTab.open() + } + function resize() { - thisObject.container.frame.width = SIDE_PANEL_WIDTH * 2 + thisObject.container.frame.width = 900 thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT thisObject.container.frame.position.x = browserCanvas.width thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT @@ -69,6 +76,29 @@ function newDocSpace() { function physics() { thisObject.sidePanelTab.physics() + docAppDivPhysics() + iFramePhysics() + + function docAppDivPhysics() { + let docAppDiv = document.getElementById('docApp') + docAppDivPosition = { + x: 0, + y: 0 + } + docAppDivPosition = thisObject.container.frame.frameThisPoint(docAppDivPosition) + docAppDiv.style = ' overflow-x: hidden; ' + + 'position:fixed; top:' + docAppDivPosition.y + 'px; ' + + 'left:' + docAppDivPosition.x + 'px; z-index:1; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + } + + function iFramePhysics() { + let docIFrame = document.getElementById('docIFrame') + docIFrame.style = 'overflow-x: hidden; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + } } function draw() { From 89149e3817a5192e01f9608f9eefaa2225718f29 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 Sep 2020 16:48:26 +0200 Subject: [PATCH 072/192] Update SidePanelTab.js --- SideSpace/SidePanelTab.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/SideSpace/SidePanelTab.js b/SideSpace/SidePanelTab.js index ac331dae0..b774ef9f8 100644 --- a/SideSpace/SidePanelTab.js +++ b/SideSpace/SidePanelTab.js @@ -43,9 +43,7 @@ function newSidePanelTab() { } } thisObject.container.frame.width = TAB_WIDTH - thisObject.container.frame.height = TAB_HEIGHT - - ORIGINAL_PARENT_POSITON = thisObject.container.parentContainer.frame.position.x + thisObject.container.frame.height = TAB_HEIGHT thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) resize() @@ -63,8 +61,9 @@ function newSidePanelTab() { break } } - + thisObject.container.frame.position.y = 69 + ORIGINAL_PARENT_POSITON = thisObject.container.parentContainer.frame.position.x setClosed() } From 80f11db3bf4f568a6767a0f6efefdb334e9d54b7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 Sep 2020 19:08:44 +0200 Subject: [PATCH 073/192] Polishing --- FloatingSpace/UiObjectConstructor.js | 10 +++++----- Spaces/DocSpace.js | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/FloatingSpace/UiObjectConstructor.js b/FloatingSpace/UiObjectConstructor.js index 218b544d6..4443ea708 100644 --- a/FloatingSpace/UiObjectConstructor.js +++ b/FloatingSpace/UiObjectConstructor.js @@ -565,7 +565,7 @@ function newUiObjectConstructor() { floatingObject.friction = INITIAL_FRICTION floatingObject.initializeMass(300) - floatingObject.initializeRadius(INITIAL_RADIOUS - 5) + floatingObject.initializeRadius(INITIAL_RADIOUS - 2) floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 10) floatingObject.initializeFontSize(INITIAL_FONT_SIZE) @@ -581,7 +581,7 @@ function newUiObjectConstructor() { floatingObject.friction = INITIAL_FRICTION floatingObject.initializeMass(150) - floatingObject.initializeRadius(INITIAL_RADIOUS - 10) + floatingObject.initializeRadius(INITIAL_RADIOUS - 4) floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 20) floatingObject.initializeFontSize(INITIAL_FONT_SIZE) @@ -597,7 +597,7 @@ function newUiObjectConstructor() { floatingObject.friction = INITIAL_FRICTION floatingObject.initializeMass(75) - floatingObject.initializeRadius(INITIAL_RADIOUS - 15) + floatingObject.initializeRadius(INITIAL_RADIOUS - 6) floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 30) floatingObject.initializeFontSize(INITIAL_FONT_SIZE) @@ -613,7 +613,7 @@ function newUiObjectConstructor() { floatingObject.friction = INITIAL_FRICTION floatingObject.initializeMass(50) - floatingObject.initializeRadius(INITIAL_RADIOUS - 20) + floatingObject.initializeRadius(INITIAL_RADIOUS - 8) floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 40) floatingObject.initializeFontSize(INITIAL_FONT_SIZE) @@ -625,7 +625,7 @@ function newUiObjectConstructor() { floatingObject.friction = INITIAL_FRICTION floatingObject.initializeMass(25) - floatingObject.initializeRadius(INITIAL_RADIOUS - 25) + floatingObject.initializeRadius(INITIAL_RADIOUS - 10) floatingObject.initializeHierarchyRing(INITIAL_HIERARCHY_RING) floatingObject.initializeImageSize(INITIAL_IMAGE_SIZE - 50) floatingObject.initializeFontSize(INITIAL_FONT_SIZE) diff --git a/Spaces/DocSpace.js b/Spaces/DocSpace.js index b00cdfff8..31d43701b 100644 --- a/Spaces/DocSpace.js +++ b/Spaces/DocSpace.js @@ -51,7 +51,7 @@ function newDocSpace() { } function resize() { - thisObject.container.frame.width = 900 + thisObject.container.frame.width = 1200 thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT thisObject.container.frame.position.x = browserCanvas.width thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT @@ -86,7 +86,7 @@ function newDocSpace() { y: 0 } docAppDivPosition = thisObject.container.frame.frameThisPoint(docAppDivPosition) - docAppDiv.style = ' overflow-x: hidden; ' + + docAppDiv.style = ' ' + 'position:fixed; top:' + docAppDivPosition.y + 'px; ' + 'left:' + docAppDivPosition.x + 'px; z-index:1; ' + 'width: ' + thisObject.container.frame.width + 'px;' + @@ -95,7 +95,7 @@ function newDocSpace() { function iFramePhysics() { let docIFrame = document.getElementById('docIFrame') - docIFrame.style = 'overflow-x: hidden; ' + + docIFrame.style = ' ' + 'width: ' + thisObject.container.frame.width + 'px;' + 'height: ' + thisObject.container.frame.height + 'px' } From 818aa8599a492bf483dac89d4f60db61b4d61542 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 4 Sep 2020 10:40:21 +0200 Subject: [PATCH 074/192] Update UiObject.js --- FloatingSpace/UiObject.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index f3b1885dd..d67d14733 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1551,23 +1551,23 @@ function newUiObject() { function drawErrorMessage() { if (thisObject.hasError === false) { return } - drawMessage(errorMessage) + drawMessage(errorMessage, UI_COLOR.RUSTED_RED) } function drawWarningMessage() { if (thisObject.hasError === true) { return } if (thisObject.hasWarning !== true) { return } - drawMessage(warningMessage) + drawMessage(warningMessage, UI_COLOR.TITANIUM_YELLOW) } function drawInfoMessage() { if (thisObject.hasError === true) { return } if (thisObject.hasWarning === true) { return } if (thisObject.hasInfo !== true) { return } - drawMessage(infoMessage) + drawMessage(infoMessage, UI_COLOR.TURQUOISE) } - function drawMessage(message) { + function drawMessage(message, textColor) { if (canvas.floatingSpace.inMapMode === true) { return @@ -1603,11 +1603,12 @@ function newUiObject() { labelPoint = { x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 2 / 5 + fontSize * FONT_ASPECT_RATIO + 15 + y: position.y + radius * 2 / 5 + fontSize * FONT_ASPECT_RATIO + 25 } browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)' + + browserCanvasContext.fillStyle = 'rgba(' + textColor + ', 1)' browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } } From 5c282291271a17de46e8a781995033aa8e98c44b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 4 Sep 2020 17:47:46 +0200 Subject: [PATCH 075/192] Tutorials --- .../FunctionLibraries/TutorialFunctions.js | 24 +++++++++++++++++++ DesignSpace/Workspace/Workspace.js | 6 +++++ 2 files changed, 30 insertions(+) create mode 100644 DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js diff --git a/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js new file mode 100644 index 000000000..49abd5e01 --- /dev/null +++ b/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js @@ -0,0 +1,24 @@ +function newTutorialFunctions() { + thisObject = { + play: play + } + const HEIGHT = 800 + const WIDTH = 600 + const MARGIN = 300 + return thisObject + + function play(node) { + let docAppDiv = document.getElementById('tutorialStepDiv') + tutorialPosition = { + x: MARGIN, + y: (browserCanvas.height - HEIGHT) / 2 + } + + docAppDiv.style = ' ' + + 'position:fixed; top:' + tutorialPosition.y + 'px; ' + + 'left:' + tutorialPosition.x + 'px; ' + + 'width: ' + WIDTH + 'px;' + + 'height: ' + HEIGHT + 'px;' + + 'z-index:1;' + } +} diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 875e0214c..2fb7c7976 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -69,6 +69,7 @@ function newWorkspace() { let functionLibraryDataMineFunctions = newDataMineFunctions() let functionLibraryDataStorageFunctions = newDataStorageFunctions() let functionLibraryChartingSpaceFunctions = newChartingSpaceFunctions() + let functionLibraryTutorialFunctions = newTutorialFunctions() thisObject.nodeChildren = newNodeChildren() @@ -635,6 +636,11 @@ function newWorkspace() { functionLibraryChartingSpaceFunctions.addAllDataMineLayers(payload.node, functionLibraryUiObjectsFromNodes) } break + case 'Play Tutorial': + { + functionLibraryTutorialFunctions.play(payload.node) + } + break case 'Send Webhook Test Message': { functionLibraryWebhookFunctions.sendTestMessage(payload.node, callBackFunction) From 3e68bea2f2621fa3eb6d180cbbee1e46b948ae42 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 5 Sep 2020 11:49:24 +0200 Subject: [PATCH 076/192] positioning --- DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js | 2 +- FloatingSpace/UiObject.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js index 49abd5e01..4281e8355 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js @@ -3,7 +3,7 @@ function newTutorialFunctions() { play: play } const HEIGHT = 800 - const WIDTH = 600 + const WIDTH = 500 const MARGIN = 300 return thisObject diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index d67d14733..2481e1e6d 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -1603,7 +1603,7 @@ function newUiObject() { labelPoint = { x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 2 / 5 + fontSize * FONT_ASPECT_RATIO + 25 + y: position.y + radius * 2 / 5 + fontSize * FONT_ASPECT_RATIO + 10 } browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY From 602076832c6e87bcc78421141a0c445f43ae9b22 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 5 Sep 2020 14:26:37 +0200 Subject: [PATCH 077/192] Tutorial part 2 --- Canvas.js | 47 +++++++ DesignSpace/Workspace/Workspace.js | 32 ++++- Spaces/TutorialSpace.js | 196 +++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 Spaces/TutorialSpace.js diff --git a/Canvas.js b/Canvas.js index a31958ad1..367429a5e 100644 --- a/Canvas.js +++ b/Canvas.js @@ -33,6 +33,7 @@ function newCanvas() { topSpace: undefined, sideSpace: undefined, docSpace: undefined, + tutorialSpace: undefined, chartingSpace: undefined, floatingSpace: undefined, panelsSpace: undefined, @@ -62,6 +63,7 @@ function newCanvas() { function finalize() { try { + thisObject.tutorialSpace.finalize() thisObject.docSpace.finalize() thisObject.sideSpace.finalize() thisObject.chartingSpace.finalize() @@ -127,6 +129,9 @@ function newCanvas() { thisObject.docSpace = newDocSpace() thisObject.docSpace.initialize() + thisObject.tutorialSpace = newTutorialSpace() + thisObject.tutorialSpace.initialize() + thisObject.splashScreen = newSplashScreen() let animation = newAnimation() @@ -142,6 +147,7 @@ function newCanvas() { animation.addCallBackFunction('Panels Space Physics', thisObject.panelsSpace.physics) animation.addCallBackFunction('Side Space Physics', thisObject.sideSpace.physics) animation.addCallBackFunction('Doc Space Physics', thisObject.docSpace.physics) + animation.addCallBackFunction('Tutorial Space Physics', thisObject.tutorialSpace.physics) /* Spcaces Drawing */ animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw) @@ -152,6 +158,7 @@ function newCanvas() { animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw) animation.addCallBackFunction('Side Space Draw', thisObject.sideSpace.draw) animation.addCallBackFunction('Doc Space Draw', thisObject.docSpace.draw) + animation.addCallBackFunction('Tutorial Space Draw', thisObject.tutorialSpace.draw) animation.addCallBackFunction('Splash Screen Draw', thisObject.splashScreen.draw) animation.start() } catch (err) { @@ -572,6 +579,20 @@ function newCanvas() { let container + /* We check if the mouse is over an element of the Doc Space / */ + container = thisObject.tutorialSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + if (container !== undefined && container.isDraggeable === false) { + return + } + /* We check if the mouse is over an element of the Doc Space / */ container = thisObject.docSpace.getContainer(point) @@ -715,6 +736,14 @@ function newCanvas() { let container + /* We check if the mouse is over an element of the Tutorial Space / */ + container = thisObject.tutorialSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + /* We check if the mouse is over an element of the Doc Space / */ container = thisObject.docSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) @@ -865,6 +894,16 @@ function newCanvas() { let container + /* We check if the mouse is over an element of the Tutorial Space / */ + if (thisObject.tutorialSpace !== undefined) { + container = thisObject.tutorialSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + /* We check if the mouse is over an element of the Doc Space / */ if (thisObject.docSpace !== undefined) { container = thisObject.docSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) @@ -983,6 +1022,14 @@ function newCanvas() { event.mousePosition = point let container + /* Doc Space */ + container = canvas.tutorialSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + /* Doc Space */ container = canvas.docSpace.getContainer({ x: point.x, y: point.y }) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 2fb7c7976..a408c2184 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -638,7 +638,37 @@ function newWorkspace() { break case 'Play Tutorial': { - functionLibraryTutorialFunctions.play(payload.node) + canvas.tutorialSpace.playTutorial(payload.node) + } + break + case 'Play Tutorial Topic': + { + canvas.tutorialSpace.playTutorialTopic(payload.node) + } + break + case 'Play Tutorial Step': + { + canvas.tutorialSpace.playTutorialStep(payload.node) + } + break + case 'Resume Tutorial': + { + canvas.tutorialSpace.resumeTutorial(payload.node) + } + break + case 'Resume Tutorial Topic': + { + canvas.tutorialSpace.resumeTutorialTopic(payload.node) + } + break + case 'Resume Tutorial Step': + { + canvas.tutorialSpace.resumeTutorialStep(payload.node) + } + break + case 'Reset Tutorial Progress': + { + canvas.tutorialSpace.resetTutorialProgress(payload.node) } break case 'Send Webhook Test Message': diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js new file mode 100644 index 000000000..143888223 --- /dev/null +++ b/Spaces/TutorialSpace.js @@ -0,0 +1,196 @@ +function newTutorialSpace() { + const MODULE_NAME = 'Tutorial Space' + let thisObject = { + playTutorial: playTutorial, + resumeTutorial: resumeTutorial, + stopTutorial: stopTutorial, + playTutorialTopic: playTutorialTopic, + resumeTutorialTopic: resumeTutorialTopic, + stopTutorialTopic: stopTutorialTopic, + playTutorialStep: playTutorialStep, + resumeTutorialStep: resumeTutorialStep, + stopTutorialStep: stopTutorialStep, + skipTutorialTopic: skipTutorialTopic, + skipTutorialStep: skipTutorialStep, + tutorialDone: tutorialDone, + tutorialTopicDone: tutorialTopicDone, + tutorialStepDone: tutorialStepDone, + resetTutorialProgress: resetTutorialProgress, + container: undefined, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize + } + + let isInitialized = false + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.status = 'hidden' + + resize() + + let browserResizedEventSubscriptionId + + let currentTutorialNode + let currentTutorialTopicNode + let currentTutorialStepNode + let currentStatus = 'Stopped' + + let docAppDiv = document.getElementById('tutorialStepDiv') + + return thisObject + + function initialize() { + browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + isInitialized = true + } + + function finalize() { + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) + + currentTutorialNode = undefined + currentTutorialTopicNode = undefined + currentTutorialStepNode = undefined + + docAppDiv = undefined + } + + function resize() { + thisObject.container.frame.width = 0 + thisObject.container.frame.height = 0 + } + + function getContainer(point, purpose) { + let container + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function physics() { + + switch (currentStatus) { + case 'Stopped': { + makeInvisible() + break + } + case 'Playing Tutorial': { + makeVsible() + break + } + } + + function makeInvisible() { + const HEIGHT = 0 + const WIDTH = 0 + + tutorialPosition = { + x: 100000, + y: 100000 + } + + docAppDiv.style = ' ' + + 'position:fixed; top:' + tutorialPosition.y + 'px; ' + + 'left:' + tutorialPosition.x + 'px; ' + + 'width: ' + WIDTH + 'px;' + + 'height: ' + HEIGHT + 'px;' + + 'z-index:1;' + } + + function makeVsible() { + const HEIGHT = 800 + const WIDTH = 500 + const MARGIN = 300 + + tutorialPosition = { + x: MARGIN, + y: (browserCanvas.height - HEIGHT) / 2 + } + + docAppDiv.style = ' ' + + 'position:fixed; top:' + tutorialPosition.y + 'px; ' + + 'left:' + tutorialPosition.x + 'px; ' + + 'width: ' + WIDTH + 'px;' + + 'height: ' + HEIGHT + 'px;' + + 'z-index:1;' + } + } + + function playTutorial(node) { + currentTutorialNode = node + currentStatus = 'Playing Tutorial' + } + + function resumeTutorial(node) { + + } + + function stopTutorial() { + currentTutorialNode = undefined + currentTutorialTopicNode = undefined + currentTutorialStepNode = undefined + currentStatus = 'Stopped' + } + + function playTutorialTopic(node) { + + } + + function resumeTutorialTopic(node) { + + } + + function stopTutorialTopic() { + + } + + function playTutorialStep(node) { + + } + + function resumeTutorialStep(node) { + + } + + function stopTutorialStep() { + + } + + function skipTutorialTopic() { + + } + + function skipTutorialStep() { + + } + + function tutorialDone() { + + } + + function tutorialTopicDone() { + + } + + function tutorialStepDone() { + + } + + function resetTutorialProgress() { + + } + + function draw() { + if (isInitialized === false) { return } + } +} From 7b96fa671729e14a261817dd062e396fc36be39e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 5 Sep 2020 18:38:04 +0200 Subject: [PATCH 078/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 140 +++++++++++++++++++++++++++++++--------- 1 file changed, 109 insertions(+), 31 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 143888223..547419a96 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -1,18 +1,15 @@ function newTutorialSpace() { const MODULE_NAME = 'Tutorial Space' let thisObject = { + stop: stop, + skip: skip, + done: done, playTutorial: playTutorial, resumeTutorial: resumeTutorial, - stopTutorial: stopTutorial, playTutorialTopic: playTutorialTopic, resumeTutorialTopic: resumeTutorialTopic, - stopTutorialTopic: stopTutorialTopic, playTutorialStep: playTutorialStep, resumeTutorialStep: resumeTutorialStep, - stopTutorialStep: stopTutorialStep, - skipTutorialTopic: skipTutorialTopic, - skipTutorialStep: skipTutorialStep, - tutorialDone: tutorialDone, tutorialTopicDone: tutorialTopicDone, tutorialStepDone: tutorialStepDone, resetTutorialProgress: resetTutorialProgress, @@ -41,9 +38,11 @@ function newTutorialSpace() { let currentTutorialNode let currentTutorialTopicNode let currentTutorialStepNode + let currentNode let currentStatus = 'Stopped' - let docAppDiv = document.getElementById('tutorialStepDiv') + let tutorialDiv = document.getElementById('tutorialDiv') + let tutorialFormDiv = document.getElementById('tutorialFormDiv') return thisObject @@ -58,8 +57,9 @@ function newTutorialSpace() { currentTutorialNode = undefined currentTutorialTopicNode = undefined currentTutorialStepNode = undefined + currentNode = undefined - docAppDiv = undefined + tutorialDiv = undefined } function resize() { @@ -93,41 +93,60 @@ function newTutorialSpace() { function makeInvisible() { const HEIGHT = 0 const WIDTH = 0 + const FORM_HEIGHT = 0 tutorialPosition = { x: 100000, y: 100000 } - docAppDiv.style = ' ' + + tutorialDiv.style = ' ' + 'position:fixed; top:' + tutorialPosition.y + 'px; ' + 'left:' + tutorialPosition.x + 'px; ' + 'width: ' + WIDTH + 'px;' + 'height: ' + HEIGHT + 'px;' + 'z-index:1;' + + tutorialFormDiv.style = ' ' + + 'position:fixed; top:' + (tutorialPosition.y) + 'px; ' + + 'left:' + tutorialPosition.x + 'px; ' + + 'width: ' + WIDTH + 'px;' + + 'height: ' + FORM_HEIGHT + 'px;' + + 'z-index:1;' } function makeVsible() { const HEIGHT = 800 const WIDTH = 500 const MARGIN = 300 + const FORM_HEIGHT = 80 tutorialPosition = { x: MARGIN, y: (browserCanvas.height - HEIGHT) / 2 } - docAppDiv.style = ' ' + + tutorialDiv.style = ' ' + 'position:fixed; top:' + tutorialPosition.y + 'px; ' + 'left:' + tutorialPosition.x + 'px; ' + 'width: ' + WIDTH + 'px;' + 'height: ' + HEIGHT + 'px;' + 'z-index:1;' + + buildHTML() + + tutorialFormDiv.style = ' ' + + 'position:fixed; top:' + (tutorialPosition.y + HEIGHT - FORM_HEIGHT) + 'px; ' + + 'left:' + tutorialPosition.x + 'px; ' + + 'width: ' + WIDTH + 'px;' + + 'height: ' + FORM_HEIGHT + 'px;' + + 'z-index:1;' } } function playTutorial(node) { currentTutorialNode = node + currentNode = node currentStatus = 'Playing Tutorial' } @@ -135,13 +154,22 @@ function newTutorialSpace() { } - function stopTutorial() { + function stop() { currentTutorialNode = undefined currentTutorialTopicNode = undefined currentTutorialStepNode = undefined currentStatus = 'Stopped' } + + function skip() { + + } + + function done() { + + } + function playTutorialTopic(node) { } @@ -150,10 +178,6 @@ function newTutorialSpace() { } - function stopTutorialTopic() { - - } - function playTutorialStep(node) { } @@ -162,22 +186,6 @@ function newTutorialSpace() { } - function stopTutorialStep() { - - } - - function skipTutorialTopic() { - - } - - function skipTutorialStep() { - - } - - function tutorialDone() { - - } - function tutorialTopicDone() { } @@ -190,6 +198,76 @@ function newTutorialSpace() { } + function buildHTML() { + + let nodeConfig = JSON.parse(currentNode.config) + let html = '' + if (nodeConfig.title !== undefined && nodeConfig.title !== '') { + html = html + '

' + nodeConfig.title + '

' + } + html = html + '
' + if (nodeConfig.summary !== undefined && nodeConfig.summary !== '') { + html = html + '
' + nodeConfig.summary + '
' + } + if (nodeConfig.subTitle !== undefined && nodeConfig.subTitle !== '') { + html = html + '

' + nodeConfig.subTitle + '

' + } + if (nodeConfig.definition !== undefined && nodeConfig.definition !== '') { + html = html + '' + html = html + '' + html = html + '' + html = html + '' + html = html + '' + html = html + '
' + if (nodeConfig.image !== undefined && nodeConfig.image !== '') { + html = html + '' + } + html = html + '' + html = html + '' + nodeConfig.definition + '' + html = html + '
' + } + if (nodeConfig.bulletListIntro !== undefined && nodeConfig.bulletListIntro !== '') { + html = html + '

' + nodeConfig.bulletListIntro + '

' + } + if (nodeConfig.bulletArray !== undefined) { + html = html + '
    ' + for (let i = 0; i < nodeConfig.bulletArray.length; i++) { + let bullet = nodeConfig.bulletArray[i] + html = html + '
  • ' + html = html + '

    ' + bullet[0] + ': ' + bullet[1] + '

    ' + html = html + '
  • ' + } + html = html + '
' + } + if (nodeConfig.paragraph1 !== undefined && nodeConfig.paragraph1 !== '') { + html = html + '

' + nodeConfig.paragraph1 + '

' + } + if (nodeConfig.callOut !== undefined && nodeConfig.callOut !== '') { + html = html + '
' + nodeConfig.callOut + '
' + } + if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { + html = html + '

' + nodeConfig.paragraph2 + '

' + } + if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { + html = html + '

' + nodeConfig.paragraph2 + '

' + } + if (nodeConfig.note !== undefined && nodeConfig.note !== '') { + html = html + '' + } + if (nodeConfig.tip !== undefined && nodeConfig.tip !== '') { + html = html + '' + } + if (nodeConfig.important !== undefined && nodeConfig.important !== '') { + html = html + '' + } + if (nodeConfig.warning !== undefined && nodeConfig.warning !== '') { + html = html + '' + } + html = html + '
' + + tutorialDiv.innerHTML = html + } + function draw() { if (isInitialized === false) { return } } From 8cb9df12b03aba8b4409c6306a9723ce48105077 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 6 Sep 2020 12:48:01 +0200 Subject: [PATCH 079/192] Done working --- .../FunctionLibraries/TutorialFunctions.js | 19 ---- Spaces/TutorialSpace.js | 89 +++++++++++++++++-- 2 files changed, 83 insertions(+), 25 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js index 4281e8355..f89c89f07 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TutorialFunctions.js @@ -1,24 +1,5 @@ function newTutorialFunctions() { thisObject = { - play: play } - const HEIGHT = 800 - const WIDTH = 500 - const MARGIN = 300 return thisObject - - function play(node) { - let docAppDiv = document.getElementById('tutorialStepDiv') - tutorialPosition = { - x: MARGIN, - y: (browserCanvas.height - HEIGHT) / 2 - } - - docAppDiv.style = ' ' + - 'position:fixed; top:' + tutorialPosition.y + 'px; ' + - 'left:' + tutorialPosition.x + 'px; ' + - 'width: ' + WIDTH + 'px;' + - 'height: ' + HEIGHT + 'px;' + - 'z-index:1;' - } } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 547419a96..937473278 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -88,6 +88,14 @@ function newTutorialSpace() { makeVsible() break } + case 'Playing Topic': { + makeVsible() + break + } + case 'Playing Step': { + makeVsible() + break + } } function makeInvisible() { @@ -116,8 +124,8 @@ function newTutorialSpace() { } function makeVsible() { - const HEIGHT = 800 - const WIDTH = 500 + const HEIGHT = 650 + const WIDTH = 400 const MARGIN = 300 const FORM_HEIGHT = 80 @@ -167,11 +175,14 @@ function newTutorialSpace() { } function done() { - + /* If we are standing at the Tutorial Node, we do this. */ + advance() } function playTutorialTopic(node) { - + currentTopicNode = node + currentNode = node + currentStatus = 'Playing Topic' } function resumeTutorialTopic(node) { @@ -179,7 +190,9 @@ function newTutorialSpace() { } function playTutorialStep(node) { - + currentStepNode = node + currentNode = node + currentStatus = 'Playing Step' } function resumeTutorialStep(node) { @@ -198,6 +211,70 @@ function newTutorialSpace() { } + function advance() { + let found + let advanced + + switch (currentStatus) { + case 'Playing Tutorial': { + found = true + findNextNode(currentTutorialNode) + break + } + case 'Playing Topic': { + found = false + findNextNode(currentTutorialNode) + break + } + case 'Playing Step': { + found = false + findNextNode(currentTutorialNode) + break + } + } + + if (advanced === undefined) { + stop() + } + + function findNextNode(node) { + + for (let i = 0; i < node.tutorialSteps.length; i++) { + + let tutorialStep = node.tutorialSteps[i] + if (found === true) { + currentNode = tutorialStep + currentStatus = 'Playing Step' + advanced = true + return + } + if (tutorialStep.id === currentNode.id) { + found = true + } + } + + for (let i = 0; i < node.tutorialTopics.length; i++) { + + if (advanced === true) { + return + } + + let tutorialTopic = node.tutorialTopics[i] + if (found === true) { + currentNode = tutorialTopic + currentStatus = 'Playing Topic' + advanced = true + return + } + if (tutorialTopic.id === currentNode.id) { + found = true + } + + findNextNode(tutorialTopic, found) + } + } + } + function buildHTML() { let nodeConfig = JSON.parse(currentNode.config) @@ -217,7 +294,7 @@ function newTutorialSpace() { html = html + '' html = html + '' if (nodeConfig.image !== undefined && nodeConfig.image !== '') { - html = html + '' + html = html + '' } html = html + '' html = html + '' From 5d679211d3b7778b667dc9f78f1f0a043d36d7cc Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 6 Sep 2020 13:55:32 +0200 Subject: [PATCH 080/192] Referencing Works --- FloatingSpace/FloatingObject.js | 16 +++++++ FloatingSpace/UiObject.js | 2 +- Spaces/TutorialSpace.js | 74 ++++++++++++++++++++++++++------- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index a89979978..76901b340 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -29,6 +29,7 @@ function newFloatingObject() { isParentCollapsed: false, frozenManually: false, collapsedManually: false, + unCollapseParent: unCollapseParent, getPinStatus: getPinStatus, getFreezeStatus: getFreezeStatus, getCollapseStatus: getCollapseStatus, @@ -151,6 +152,21 @@ function newFloatingObject() { return thisObject.isCollapsed } + function unCollapseParent() { + if (thisObject.payload !== undefined) { + if (thisObject.payload.parentNode !== undefined) { + if (thisObject.payload.parentNode.payload !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject !== undefined) { + if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true) { + thisObject.payload.parentNode.payload.floatingObject.isCollapsed = false + thisObject.payload.parentNode.payload.floatingObject.unCollapseParent() + } + } + } + } + } + } + function getAngleToParent() { return thisObject.angleToParent } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 2481e1e6d..96f49cb53 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -791,7 +791,7 @@ function newUiObject() { if (thisObject.payload.parentNode.payload !== undefined) { if (thisObject.payload.parentNode.payload.floatingObject !== undefined) { if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) { - if (thisObject.payload.parentNode.payload.uiObject !== true) { + if (thisObject.payload.parentNode.payload.uiObject.hasError !== true) { thisObject.payload.parentNode.payload.uiObject.setErrorMessage('Error Inside this Branch') } } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 937473278..6e69331f7 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -35,9 +35,7 @@ function newTutorialSpace() { let browserResizedEventSubscriptionId - let currentTutorialNode - let currentTutorialTopicNode - let currentTutorialStepNode + let tutorialRootNode let currentNode let currentStatus = 'Stopped' @@ -54,9 +52,7 @@ function newTutorialSpace() { function finalize() { canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) - currentTutorialNode = undefined - currentTutorialTopicNode = undefined - currentTutorialStepNode = undefined + tutorialRootNode = undefined currentNode = undefined tutorialDiv = undefined @@ -78,10 +74,12 @@ function newTutorialSpace() { } function physics() { + if (currentNode === undefined) { return } switch (currentStatus) { case 'Stopped': { makeInvisible() + currentNode = undefined break } case 'Playing Tutorial': { @@ -98,6 +96,24 @@ function newTutorialSpace() { } } + /* + If there is a reference parent defined, we will highlight it + and move the designer so that that node be at the center of the screen. + */ + + if (currentNode !== undefined) { + if (currentNode.payload !== undefined) { + if (currentNode.payload.referenceParent !== undefined) { + if (currentNode.payload.referenceParent.payload !== undefined) { + if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { + canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) + currentNode.payload.referenceParent.payload.uiObject.highlight() + } + } + } + } + } + function makeInvisible() { const HEIGHT = 0 const WIDTH = 0 @@ -153,7 +169,7 @@ function newTutorialSpace() { } function playTutorial(node) { - currentTutorialNode = node + tutorialRootNode = node currentNode = node currentStatus = 'Playing Tutorial' } @@ -163,9 +179,7 @@ function newTutorialSpace() { } function stop() { - currentTutorialNode = undefined - currentTutorialTopicNode = undefined - currentTutorialStepNode = undefined + tutorialRootNode = undefined currentStatus = 'Stopped' } @@ -183,6 +197,7 @@ function newTutorialSpace() { currentTopicNode = node currentNode = node currentStatus = 'Playing Topic' + findTutorialNode(node) } function resumeTutorialTopic(node) { @@ -193,6 +208,7 @@ function newTutorialSpace() { currentStepNode = node currentNode = node currentStatus = 'Playing Step' + findTutorialNode(node) } function resumeTutorialStep(node) { @@ -211,6 +227,19 @@ function newTutorialSpace() { } + function findTutorialNode(node) { + /* + We will consider the tutorialRootNode the head of the hirierchy + */ + tutorialRootNode = node + + if (node.payload !== undefined) { + if (node.payload.parentNode !== undefined) { + findTutorialNode(node.payload.parentNode) + } + } + } + function advance() { let found let advanced @@ -218,29 +247,44 @@ function newTutorialSpace() { switch (currentStatus) { case 'Playing Tutorial': { found = true - findNextNode(currentTutorialNode) + findNextNode(tutorialRootNode) break } case 'Playing Topic': { found = false - findNextNode(currentTutorialNode) + findNextNode(tutorialRootNode) break } case 'Playing Step': { found = false - findNextNode(currentTutorialNode) + findNextNode(tutorialRootNode) break } } + /* + If we can not find a next node, then we stop the tutorial. + */ if (advanced === undefined) { stop() + return + } + + /* + If there is a reference parent defined, we will uncollape the brach where it belongs. + */ + if (currentNode.payload.referenceParent !== undefined) { + if (currentNode.payload.referenceParent.payload !== undefined) { + if (currentNode.payload.referenceParent.payload.floatingObject !== undefined) { + currentNode.payload.referenceParent.payload.floatingObject.unCollapseParent() + } + } } function findNextNode(node) { - + for (let i = 0; i < node.tutorialSteps.length; i++) { - + let tutorialStep = node.tutorialSteps[i] if (found === true) { currentNode = tutorialStep From 18e8a0047b51d49def6e49a878c043eb4fc729e6 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 6 Sep 2020 14:33:57 +0200 Subject: [PATCH 081/192] Images Working --- Spaces/TutorialSpace.js | 50 ++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 6e69331f7..5b37c077e 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -41,6 +41,9 @@ function newTutorialSpace() { let tutorialDiv = document.getElementById('tutorialDiv') let tutorialFormDiv = document.getElementById('tutorialFormDiv') + let htmlImage = document.createElement("IMG") + let currentImageName = 'Never Set' + let newImageName = 'Never Set' return thisObject @@ -56,6 +59,8 @@ function newTutorialSpace() { currentNode = undefined tutorialDiv = undefined + tutorialFormDiv = undefined + image = undefined } function resize() { @@ -96,18 +101,37 @@ function newTutorialSpace() { } } - /* - If there is a reference parent defined, we will highlight it - and move the designer so that that node be at the center of the screen. - */ + checkImage() + checkReference() + return - if (currentNode !== undefined) { - if (currentNode.payload !== undefined) { - if (currentNode.payload.referenceParent !== undefined) { - if (currentNode.payload.referenceParent.payload !== undefined) { - if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { - canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) - currentNode.payload.referenceParent.payload.uiObject.highlight() + function checkImage() { + let tutorialImageDiv = document.getElementById('tutorialImageDiv') + if (tutorialImageDiv !== null && tutorialImageDiv !== undefined) { + tutorialImageDiv.appendChild(htmlImage) + } + + if (currentImageName === newImageName) {return} + currentImageName = newImageName + htmlImage.src = 'Images/Icons/style-01/' + currentImageName + '.png' + htmlImage.width = "100" + htmlImage.height = "100" + } + + function checkReference() { + /* + If there is a reference parent defined, we will highlight it + and move the designer so that that node be at the center of the screen. + */ + + if (currentNode !== undefined) { + if (currentNode.payload !== undefined) { + if (currentNode.payload.referenceParent !== undefined) { + if (currentNode.payload.referenceParent.payload !== undefined) { + if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { + canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) + currentNode.payload.referenceParent.payload.uiObject.highlight() + } } } } @@ -183,7 +207,6 @@ function newTutorialSpace() { currentStatus = 'Stopped' } - function skip() { } @@ -338,7 +361,8 @@ function newTutorialSpace() { html = html + '' html = html + '' if (nodeConfig.image !== undefined && nodeConfig.image !== '') { - html = html + '' + html = html + '
' + newImageName = nodeConfig.image } html = html + '' html = html + '' From 1c1b138aa54aa8b2c73c199805d587eceb51611a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 6 Sep 2020 19:35:18 +0200 Subject: [PATCH 082/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 68 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 5b37c077e..a87e4b96a 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -42,8 +42,12 @@ function newTutorialSpace() { let tutorialDiv = document.getElementById('tutorialDiv') let tutorialFormDiv = document.getElementById('tutorialFormDiv') let htmlImage = document.createElement("IMG") - let currentImageName = 'Never Set' + let currentImageName = 'Never Set' let newImageName = 'Never Set' + let currentConfig + let newConfig + let newDocumentationURL + let currentDocumentationURL return thisObject @@ -102,6 +106,7 @@ function newTutorialSpace() { } checkImage() + checkDocumentation() checkReference() return @@ -110,14 +115,27 @@ function newTutorialSpace() { if (tutorialImageDiv !== null && tutorialImageDiv !== undefined) { tutorialImageDiv.appendChild(htmlImage) } - - if (currentImageName === newImageName) {return} + + if (currentImageName === newImageName) { return } currentImageName = newImageName htmlImage.src = 'Images/Icons/style-01/' + currentImageName + '.png' htmlImage.width = "100" htmlImage.height = "100" } + function checkDocumentation() { + if (currentNode === undefined) {return} + let config = JSON.parse(currentNode.config) + let newDocumentationURL = config.documentationURL + if (newDocumentationURL === undefined || newDocumentationURL === "") { + canvas.docSpace.sidePanelTab.close() + } + if (newDocumentationURL === currentDocumentationURL) { return } + + currentDocumentationURL = newDocumentationURL + canvas.docSpace.navigateTo(currentDocumentationURL) + } + function checkReference() { /* If there is a reference parent defined, we will highlight it @@ -169,11 +187,37 @@ function newTutorialSpace() { const MARGIN = 300 const FORM_HEIGHT = 80 - tutorialPosition = { - x: MARGIN, - y: (browserCanvas.height - HEIGHT) / 2 + let nodeConfig = JSON.parse(currentNode.config) + switch (nodeConfig.position) { + case 'Left': { + tutorialPosition = { + x: MARGIN, + y: (browserCanvas.height - HEIGHT) / 2 + } + break + } + case 'Center': { + tutorialPosition = { + x: browserCanvas.width / 2 - WIDTH / 2, + y: (browserCanvas.height - HEIGHT) / 2 + } + break + } + case 'Right': { + tutorialPosition = { + x: browserCanvas.width - WIDTH - MARGIN, + y: (browserCanvas.height - HEIGHT) / 2 + } + break + } + default: { + tutorialPosition = { + x: browserCanvas.width / 2 - WIDTH / 2, + y: (browserCanvas.height - HEIGHT) / 2 + } + break + } } - tutorialDiv.style = ' ' + 'position:fixed; top:' + tutorialPosition.y + 'px; ' + 'left:' + tutorialPosition.x + 'px; ' + @@ -344,6 +388,10 @@ function newTutorialSpace() { function buildHTML() { + newConfig = currentNode.config + if (newConfig === currentConfig) { return } + currentConfig = newConfig + let nodeConfig = JSON.parse(currentNode.config) let html = '' if (nodeConfig.title !== undefined && nodeConfig.title !== '') { @@ -388,7 +436,11 @@ function newTutorialSpace() { html = html + '

' + nodeConfig.paragraph1 + '

' } if (nodeConfig.callOut !== undefined && nodeConfig.callOut !== '') { - html = html + '
' + nodeConfig.callOut + '
' + html = html + '
' } if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { html = html + '

' + nodeConfig.paragraph2 + '

' From eee3be277d1af33a017c7d565f1eb56d9a9e51e0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 6 Sep 2020 20:17:47 +0200 Subject: [PATCH 083/192] Update UiObject.js --- FloatingSpace/UiObject.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 96f49cb53..0304da0a9 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -618,6 +618,11 @@ function newUiObject() { let floatingObject = nearby[1] let nearbyNode = floatingObject.payload.node if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0 || compatibleTypes === "->*Any Node*->" ) { + if (nodeDefinition.referenceAttachesTo.incompatibleTypes !== undefined) { + if (nodeDefinition.referenceAttachesTo.incompatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { + continue + } + } if (foundCompatible === false) { if (distance < thisObject.payload.floatingObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) { nearbyNode.payload.uiObject.getReadyToReferenceAttach() From 549b973217255a4180ca9473c04b3b2afe67fb4e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 Sep 2020 15:01:03 +0200 Subject: [PATCH 084/192] Tutorial version 2 --- .../FunctionLibraries/ProtocolNode.js | 6 + .../FunctionLibraries/UiObjectsFromNodes.js | 6 + Spaces/TutorialSpace.js | 103 ++++++++++++++---- Utilities/LoadSaveTutorial.js | 18 +++ 4 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 Utilities/LoadSaveTutorial.js diff --git a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js index d339a10e8..2e5803fa6 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -179,6 +179,12 @@ function newProtocolNode() { } } + if (node.payload.tutorial !== undefined) { + savedPayload.tutorial = { + status: node.payload.tutorial.status + } + } + if (includeReferencesInSavedPayload) { /* Next for the ones that have a reference parent, we include it */ if (node.payload.referenceParent !== undefined) { diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index f76a584d9..cc7b25ab2 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -576,6 +576,12 @@ function newUiObjectsFromNodes() { frame.radius = node.savedPayload.frame.radius saveFrame(payload, frame) } + if (node.savedPayload.tutorial !== undefined) { + let tutorial = { + status: node.savedPayload.tutorial.status + } + saveTutorial(payload, tutorial) + } } /* Now we mount the floating object where the UIOBject will be laying on top of */ diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index a87e4b96a..163b7f16b 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -10,8 +10,6 @@ function newTutorialSpace() { resumeTutorialTopic: resumeTutorialTopic, playTutorialStep: playTutorialStep, resumeTutorialStep: resumeTutorialStep, - tutorialTopicDone: tutorialTopicDone, - tutorialStepDone: tutorialStepDone, resetTutorialProgress: resetTutorialProgress, container: undefined, physics: physics, @@ -48,6 +46,7 @@ function newTutorialSpace() { let newConfig let newDocumentationURL let currentDocumentationURL + let resumeModeActivated // In this mode, we skip all the node which status is 'Done' return thisObject @@ -240,10 +239,15 @@ function newTutorialSpace() { tutorialRootNode = node currentNode = node currentStatus = 'Playing Tutorial' + resumeModeActivated = false } function resumeTutorial(node) { - + tutorialRootNode = node + currentNode = node + currentStatus = 'Playing Tutorial' + resumeModeActivated = true + advance() } function stop() { @@ -252,11 +256,18 @@ function newTutorialSpace() { } function skip() { - + let tutorial = { + status:'Skipped' + } + saveTutorial(currentNode.payload, tutorial) + advance() } function done() { - /* If we are standing at the Tutorial Node, we do this. */ + let tutorial = { + status:'Done' + } + saveTutorial(currentNode.payload, tutorial) advance() } @@ -264,34 +275,56 @@ function newTutorialSpace() { currentTopicNode = node currentNode = node currentStatus = 'Playing Topic' + resumeModeActivated = false findTutorialNode(node) } function resumeTutorialTopic(node) { - + currentTopicNode = node + currentNode = node + currentStatus = 'Playing Topic' + resumeModeActivated = true + findTutorialNode(node) } function playTutorialStep(node) { currentStepNode = node currentNode = node currentStatus = 'Playing Step' + resumeModeActivated = false findTutorialNode(node) } function resumeTutorialStep(node) { - + currentStepNode = node + currentNode = node + currentStatus = 'Playing Step' + resumeModeActivated = true + findTutorialNode(node) } - function tutorialTopicDone() { + function resetTutorialProgress(node) { + resetNextNode(node) - } + function resetNextNode(node) { - function tutorialStepDone() { - - } - - function resetTutorialProgress() { + for (let i = 0; i < node.tutorialSteps.length; i++) { + let tutorialStep = node.tutorialSteps[i] + let tutorial = { + status:'Reset' + } + saveTutorial(tutorialStep.payload, tutorial) + } + for (let i = 0; i < node.tutorialTopics.length; i++) { + let tutorialTopic = node.tutorialTopics[i] + let tutorial = { + status:'Reset' + } + saveTutorial(tutorialTopic.payload, tutorial) + resetNextNode(tutorialTopic) + } + } } function findTutorialNode(node) { @@ -354,10 +387,23 @@ function newTutorialSpace() { let tutorialStep = node.tutorialSteps[i] if (found === true) { - currentNode = tutorialStep - currentStatus = 'Playing Step' - advanced = true - return + if (resumeModeActivated !== true) { + currentNode = tutorialStep + currentStatus = 'Playing Step' + advanced = true + return + } else { + let tutorial = { + status: undefined + } + loadTutorial(tutorialStep.payload, tutorial) + if (tutorial.status !== 'Done') { + currentNode = tutorialStep + currentStatus = 'Playing Step' + advanced = true + return + } + } } if (tutorialStep.id === currentNode.id) { found = true @@ -372,10 +418,23 @@ function newTutorialSpace() { let tutorialTopic = node.tutorialTopics[i] if (found === true) { - currentNode = tutorialTopic - currentStatus = 'Playing Topic' - advanced = true - return + if (resumeModeActivated !== true) { + currentNode = tutorialTopic + currentStatus = 'Playing Topic' + advanced = true + return + } else { + let tutorial = { + status: undefined + } + loadTutorial(tutorialTopic.payload, tutorial) + if (tutorial.status !== 'Done') { + currentNode = tutorialTopic + currentStatus = 'Playing Topic' + advanced = true + return + } + } } if (tutorialTopic.id === currentNode.id) { found = true diff --git a/Utilities/LoadSaveTutorial.js b/Utilities/LoadSaveTutorial.js new file mode 100644 index 000000000..402a3ddf0 --- /dev/null +++ b/Utilities/LoadSaveTutorial.js @@ -0,0 +1,18 @@ +function saveTutorial(payload, tutorial) { + payload.tutorial = { + status: tutorial.status + } +} + +function loadTutorial(payload, tutorial) { + if (payload.tutorial !== undefined) { + tutorial.status = payload.tutorial.status + return + } + if (payload.node.savedPayload !== undefined) { + if (payload.node.savedPayload.tutorial !== undefined) { + tutorial.status = payload.node.savedPayload.tutorial.status + payload.node.savedPayload.tutorial = undefined + } + } +} From 2af6d7f8c11451b998499130c07a5f585ad19ad3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 Sep 2020 17:44:35 +0200 Subject: [PATCH 085/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 163b7f16b..384dcf5b9 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -39,6 +39,9 @@ function newTutorialSpace() { let tutorialDiv = document.getElementById('tutorialDiv') let tutorialFormDiv = document.getElementById('tutorialFormDiv') + let htmlGif = document.createElement("IMG") + let currentGifName = 'Never Set' + let newGifName = 'Never Set' let htmlImage = document.createElement("IMG") let currentImageName = 'Never Set' let newImageName = 'Never Set' @@ -64,6 +67,7 @@ function newTutorialSpace() { tutorialDiv = undefined tutorialFormDiv = undefined image = undefined + gif = undefined } function resize() { @@ -104,11 +108,25 @@ function newTutorialSpace() { } } + checkGif() checkImage() checkDocumentation() checkReference() return + function checkGif() { + let tutorialGifDiv = document.getElementById('tutorialGifDiv') + if (tutorialGifDiv !== null && tutorialGifDiv !== undefined) { + tutorialGifDiv.appendChild(htmlGif) + } + + if (currentGifName === newGifName) { return } + currentGifName = newGifName + htmlGif.src = 'Images/Tutorial/Gifs/' + currentGifName + '.gif' + htmlGif.width = "400" + //htmlGif.height = "100" + } + function checkImage() { let tutorialImageDiv = document.getElementById('tutorialImageDiv') if (tutorialImageDiv !== null && tutorialImageDiv !== undefined) { @@ -463,6 +481,10 @@ function newTutorialSpace() { if (nodeConfig.subTitle !== undefined && nodeConfig.subTitle !== '') { html = html + '

' + nodeConfig.subTitle + '

' } + if (nodeConfig.gif !== undefined && nodeConfig.gif !== '') { + html = html + '
' + newGifName = nodeConfig.gif + } if (nodeConfig.definition !== undefined && nodeConfig.definition !== '') { html = html + '' html = html + '' From 36231a33e46ba92bb6b619e7b5718c5141baaa34 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 Sep 2020 18:20:48 +0200 Subject: [PATCH 086/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 88 +++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 384dcf5b9..e21a2eebd 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -111,6 +111,7 @@ function newTutorialSpace() { checkGif() checkImage() checkDocumentation() + checkSlider() checkReference() return @@ -141,18 +142,63 @@ function newTutorialSpace() { } function checkDocumentation() { - if (currentNode === undefined) {return} + if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) let newDocumentationURL = config.documentationURL - if (newDocumentationURL === undefined || newDocumentationURL === "") { + if (newDocumentationURL === undefined) { + /* + The doc panel will remain as it is, and the user will be free to open or close it at will. + */ + return + } + if (newDocumentationURL === "") { + /* + This forces the tutorial to close the documentation panel and to keep it closed. + */ canvas.docSpace.sidePanelTab.close() + return } if (newDocumentationURL === currentDocumentationURL) { return } - + currentDocumentationURL = newDocumentationURL canvas.docSpace.navigateTo(currentDocumentationURL) } + function checkSlider() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if (config.slider === undefined) { + /* + The cockpit space will remain where it is. The user is free to move it. + */ + return + } + switch (config.slider) { + case "toTop": { + /* + This forces the tutorial to close the charting space and to keep it closed. + */ + canvas.cockpitSpace.toTop() + return + } + case "toMiddle": { + /* + This forces the tutorial to share the screen half with the designer and half + with the charting space and force it in that way. + */ + canvas.cockpitSpace.toMiddle() + return + } + case "toBottom": { + /* + This forces the tutorial to fully open the charting space and to keep it open. + */ + canvas.cockpitSpace.toBottom() + return + } + } + } + function checkReference() { /* If there is a reference parent defined, we will highlight it @@ -275,7 +321,7 @@ function newTutorialSpace() { function skip() { let tutorial = { - status:'Skipped' + status: 'Skipped' } saveTutorial(currentNode.payload, tutorial) advance() @@ -283,7 +329,7 @@ function newTutorialSpace() { function done() { let tutorial = { - status:'Done' + status: 'Done' } saveTutorial(currentNode.payload, tutorial) advance() @@ -329,7 +375,7 @@ function newTutorialSpace() { for (let i = 0; i < node.tutorialSteps.length; i++) { let tutorialStep = node.tutorialSteps[i] let tutorial = { - status:'Reset' + status: 'Reset' } saveTutorial(tutorialStep.payload, tutorial) } @@ -337,7 +383,7 @@ function newTutorialSpace() { for (let i = 0; i < node.tutorialTopics.length; i++) { let tutorialTopic = node.tutorialTopics[i] let tutorial = { - status:'Reset' + status: 'Reset' } saveTutorial(tutorialTopic.payload, tutorial) resetNextNode(tutorialTopic) @@ -472,14 +518,14 @@ function newTutorialSpace() { let nodeConfig = JSON.parse(currentNode.config) let html = '' if (nodeConfig.title !== undefined && nodeConfig.title !== '') { - html = html + '

' + nodeConfig.title + '

' + html = html + '

' + nodeConfig.title + '

' } html = html + '
' if (nodeConfig.summary !== undefined && nodeConfig.summary !== '') { - html = html + '
' + nodeConfig.summary + '
' + html = html + '
' + nodeConfig.summary + '
' } if (nodeConfig.subTitle !== undefined && nodeConfig.subTitle !== '') { - html = html + '

' + nodeConfig.subTitle + '

' + html = html + '

' + nodeConfig.subTitle + '

' } if (nodeConfig.gif !== undefined && nodeConfig.gif !== '') { html = html + '
' @@ -495,51 +541,51 @@ function newTutorialSpace() { } html = html + '' html = html + '
' html = html + '' html = html + '
' - html = html + '' + nodeConfig.definition + '' + html = html + '' + nodeConfig.definition + '' html = html + '
' } if (nodeConfig.bulletListIntro !== undefined && nodeConfig.bulletListIntro !== '') { - html = html + '

' + nodeConfig.bulletListIntro + '

' + html = html + '

' + nodeConfig.bulletListIntro + '

' } if (nodeConfig.bulletArray !== undefined) { html = html + '
    ' for (let i = 0; i < nodeConfig.bulletArray.length; i++) { let bullet = nodeConfig.bulletArray[i] html = html + '
  • ' - html = html + '

    ' + bullet[0] + ': ' + bullet[1] + '

    ' + html = html + '

    ' + bullet[0] + ': ' + bullet[1] + '

    ' html = html + '
  • ' } html = html + '
' } if (nodeConfig.paragraph1 !== undefined && nodeConfig.paragraph1 !== '') { - html = html + '

' + nodeConfig.paragraph1 + '

' + html = html + '

' + nodeConfig.paragraph1 + '

' } if (nodeConfig.callOut !== undefined && nodeConfig.callOut !== '') { - html = html + '
' + nodeConfig.callOut + '' + html = html + '
' + nodeConfig.callOut + '' if (nodeConfig.externalLink !== undefined) { html = html + '' + nodeConfig.externalLink[0] + '' } html = html + '
' } if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { - html = html + '

' + nodeConfig.paragraph2 + '

' + html = html + '

' + nodeConfig.paragraph2 + '

' } if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { - html = html + '

' + nodeConfig.paragraph2 + '

' + html = html + '

' + nodeConfig.paragraph2 + '

' } if (nodeConfig.note !== undefined && nodeConfig.note !== '') { - html = html + '' + html = html + '' } if (nodeConfig.tip !== undefined && nodeConfig.tip !== '') { - html = html + '' + html = html + '' } if (nodeConfig.important !== undefined && nodeConfig.important !== '') { - html = html + '' + html = html + '' } if (nodeConfig.warning !== undefined && nodeConfig.warning !== '') { - html = html + '' + html = html + '' } html = html + '
' From 2ebfbf142559c6e9222820a838aa3e564e86363d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 8 Sep 2020 10:13:16 +0200 Subject: [PATCH 087/192] Update UiObject.js --- FloatingSpace/UiObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 0304da0a9..d0e86f13c 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -795,7 +795,7 @@ function newUiObject() { if (thisObject.payload.parentNode !== undefined) { if (thisObject.payload.parentNode.payload !== undefined) { if (thisObject.payload.parentNode.payload.floatingObject !== undefined) { - if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) { + if (thisObject.payload.floatingObject.isCollapsed === true || thisObject.payload.floatingObject.isParentCollapsed === true) { if (thisObject.payload.parentNode.payload.uiObject.hasError !== true) { thisObject.payload.parentNode.payload.uiObject.setErrorMessage('Error Inside this Branch') } From 4bcd121ba3c0bc2d10584df787b659878bc01bba Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 8 Sep 2020 18:39:02 +0200 Subject: [PATCH 088/192] Update NodesValues.js --- Plotting/NodesValues.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Plotting/NodesValues.js b/Plotting/NodesValues.js index c7fabb5e1..2aca41d6c 100644 --- a/Plotting/NodesValues.js +++ b/Plotting/NodesValues.js @@ -41,6 +41,7 @@ function newNodesValues() { if (node.payload.uiObject === undefined) { return } if (value === true) { value = 'true' } if (value === false) { value = 'false' } + node.payload.uiObject.valueAtAngle = false node.payload.uiObject.setValue(value, 1) } } From 0798257b97f041fecac7b6bb0a805a67acf6d7b3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 9 Sep 2020 17:01:06 +0200 Subject: [PATCH 089/192] Update DesignSpace.js --- Spaces/DesignSpace.js | 335 +++++++----------------------------------- 1 file changed, 52 insertions(+), 283 deletions(-) diff --git a/Spaces/DesignSpace.js b/Spaces/DesignSpace.js index a9566741f..82edb996c 100644 --- a/Spaces/DesignSpace.js +++ b/Spaces/DesignSpace.js @@ -26,298 +26,68 @@ function newDesignSpace() { return thisObject function initialize() { - loadIconCollection() - buildIconByUiObjectTypeMap() + loadIconCollection(onIconsReady) - thisObject.workspace = newWorkspace() - thisObject.workspace.initialize() - } + function onIconsReady() { + buildIconByUiObjectTypeMap() + thisObject.workspace = newWorkspace() + thisObject.workspace.initialize() + } - function buildIconByUiObjectTypeMap() { - /* Take types-icons relationships defined at the schema */ - for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { - let nodeDefinition = APP_SCHEMA_ARRAY[i] - let iconName = nodeDefinition.icon - if (iconName !== undefined) { - let icon = thisObject.iconCollection.get(iconName) - thisObject.iconByUiObjectType.set(nodeDefinition.type, icon) + function buildIconByUiObjectTypeMap() { + /* Take types-icons relationships defined at the schema */ + for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { + let nodeDefinition = APP_SCHEMA_ARRAY[i] + let iconName = nodeDefinition.icon + if (iconName !== undefined) { + let icon = thisObject.iconCollection.get(iconName) + thisObject.iconByUiObjectType.set(nodeDefinition.type, icon) + } } } } - function loadIconCollection() { - const iconsNames = [ - 'analysis', - 'analysis-1', - 'approve', - 'attach', - 'attractive', - 'pyramid', - 'brainstorming', - 'broken-link', - 'chat', - 'chronometer', - 'compass', - 'competition', - 'content', - 'design-tool', - 'grid', - 'headphones', - 'html', - 'image', - 'layout', - 'loading', - 'login', - 'pantone', - 'paper-plane', - 'photo-camera', - 'piggy-bank', - 'pipette', - 'pixel', - 'placeholder', - 'planning', - 'promotion', - 'pyramid', - 'quality', - 'responsive', - 'schedule', - 'search', - 'security', - 'settings', - 'sitemap', - 'startup', - 'support', - 'tap', - 'menu-fix-pinned', - 'menu-fix-unpinned', - 'targeting', - 'task', - 'testing', - 'text', - 'timeline', - 'tools', - 'delete', - 'upload', - 'vector', - 'video-player', - 'menu-mobility-freeze', - 'menu-mobility-unfreeze', - 'menu-tree-minus', - 'menu-tree-plus', - 'menu-backup', - 'menu-share', - 'stop', - 'stage-open', - 'stage-close', - 'stage-trigger', - 'stage-trigger-trigger-on', - 'stage-trigger-trigger-off', - 'stage-trigger-take-position', - 'menu-tensor-fixed-angles', - 'menu-tensor-free-angles', - 'stage-open-position-size', - 'stage-open-take-profit', - 'stage-open-postion-rate', - 'session-live-trading', - 'session-paper-trading', - 'session-backtesting', - 'session-forward-testing', - 'network', - 'network-node', - 'bot-trading', - 'layer-manager', - 'process', - 'bot-indicator', - 'bot-sensor', - 'time-period', - 'data-mine', - 'procedure-loop', - 'calculations-procedure', - 'data-building-procedure', - 'procedure-initialization', - 'process-definition', - 'output-dataset', - 'data-dependency', - 'product-definition', - 'plotter-module', - 'status-dependency', - 'record-property', - 'record-definition', - 'plotter', - 'plotter-panel', - 'dataset-definition', - 'status-report', - 'execution-finished-event', - 'process-dependencies', - 'process-output', - 'social-bot', - 'execution-started-event', - 'shapes', - 'chart-point', - 'style', - 'chart-points', - 'shapes-polygon-vertex', - 'shapes-polygon-border', - 'shapes-polygon-body', - 'chart-point-formula', - 'style-condition', - 'shapes-polygon', - 'data-entry', - 'data-formula', - 'clone', - 'exchange-account-asset', - 'exchange-account-key', - 'user-keys', - 'user-assets', - 'asset', - 'exchange-accounts', - 'user-account', - 'market', - 'exchange-assets', - 'crypto-exchanges', - 'crypto-exchange', - 'exchange-markets', - 'charting-space', - 'time-line-chart', - 'time-frame-scale', - 'time-scale', - 'rate-scale', - 'time-machine', - 'data-product', - 'single-market-data', - 'data-storage', - 'dataset', - 'viewport', - 'bitfinex', - 'binance', - 'kucoin', - 'bittrex', - 'kraken', - 'poloniex', - 'upbit', - 'monero', - 'tether', - 'tron', - 'stellar', - 'qtum', - 'neo', - 'litecoin', - 'ethereum-classic', - 'ethereum', - 'eos', - 'dash', - 'cardano', - 'bitcoin-cash', - 'bitcoin', - 'binance-coin', - 'trend', - 'oscillator', - 'moving-average', - 'histogram', - 'band', - 'volume', - 'candles', - 'bitmex', - 'liquid', - 'hitbtc', - 'us-dollar', - 'distance-to-parent-200', - 'distance-to-parent-150', - 'distance-to-parent-100', - 'distance-to-parent-050', - 'distance-to-parent-025', - 'distance-to-parent-000', - 'angle-to-parent-360', - 'angle-to-parent-180', - 'angle-to-parent-090', - 'angle-to-parent-045', - 'angle-to-parent-000', - 'data-mining', - 'initial-definition', - 'next-phase-event', - 'testing-environment', - 'production-environment', - 'task-manager', - 'session-based-data', - 'session-independent-data', - 'session-reference', - 'dashboard', - 'toggle-auto-scale-manual', - 'toggle-auto-scale-auto-min-max', - 'toggle-auto-scale-auto-max', - 'toggle-auto-scale-auto-min', - 'toggle-panel-off', - 'toggle-auto-time-scale-auto-min', - 'toggle-auto-time-scale-auto-max', - 'toggle-auto-time-scale-auto-min-max', - 'toggle-auto-time-scale-manual', - 'mouse-pointer', - 'mouse-left-click', - 'mouse-right-click', - 'mouse-wheel-up', - 'mouse-wheel-down', - 'mouse-wheel-click', - 'key-alt', - 'key-shift', - 'key-ctrl', - 'hand-drag', - 'key-down', - 'key-left', - 'key-right', - 'key-up', - 'master-script', - 'scripts-library', - 'super-action', - 'super-scripts', - 'template-script', - 'template-structure', - 'template-target', - 'delink', - 'detach', - 'help', - 'key-a', - 'key-m', - 'key-r', - 'arrangement-horizontal-top', - 'arrangement-convex', - 'arrangement-horizontal-bottom', - 'arrangement-vertical-right', - 'arrangement-vertical-left', - 'arrangement-concave', - 'move-to-phase-event', - 'open-execution', - 'move-order', - 'market-order', - 'limit-order', - 'execution-algorithm', - 'cancel-order', - 'limit-sell-order', - 'close-execution', - 'market-sell-order', - 'limit-buy-order', - 'market-buy-order' - ] + function loadIconCollection(callBack) { - for (let i = 0; i < iconsNames.length; i++) { - let name = iconsNames[i] - loadImage(name) - } + callServer(undefined, 'ImagesNames', onResponse) - function loadImage(name) { - const PATH = 'Images/Icons/style-01/' - let image = new Image() - image.onload = onImageLoad - image.fileName = name - - function onImageLoad() { - image.canDrawIcon = true + function onResponse(err, data) { + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Failed to Fetch Image Names from the Backend') + return + } + + let imageNames = JSON.parse(data) + let imageLoadedCounter = 0 + + for (let i = 0; i < imageNames.length; i++) { + let name = imageNames[i] + loadImage(name) + } + + function loadImage(name) { + imageLoadedCounter++ + const PATH = 'Images/Icons/style-01/' + let image = new Image() + image.onload = onImageLoad + image.fileName = name + + function onImageLoad() { + image.canDrawIcon = true + } + image.src = PATH + name + let key = name.substring(0, name.length - 4) + thisObject.iconCollection.set(key, image) + + if (imageLoadedCounter === imageNames.length) { + callBack() + } } - image.src = PATH + name + '.png' - thisObject.iconCollection.set(name, image) } } function physics() { + if (thisObject.workspace === undefined) { return } thisObject.workspace.physics() } @@ -330,13 +100,12 @@ function newDesignSpace() { } function getContainer(point) { - + } function draw() { + if (thisObject.workspace === undefined) { return } if (canWeDraw === false) { return } - if (thisObject.workspace !== undefined) { - thisObject.workspace.draw() - } + thisObject.workspace.draw() } } From e43438db818f8a2ecf8369c97098d4284562e2bb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 9 Sep 2020 17:43:32 +0200 Subject: [PATCH 090/192] Update DesignSpace.js --- Spaces/DesignSpace.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Spaces/DesignSpace.js b/Spaces/DesignSpace.js index 82edb996c..d9dce27cd 100644 --- a/Spaces/DesignSpace.js +++ b/Spaces/DesignSpace.js @@ -39,8 +39,12 @@ function newDesignSpace() { for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { let nodeDefinition = APP_SCHEMA_ARRAY[i] let iconName = nodeDefinition.icon - if (iconName !== undefined) { - let icon = thisObject.iconCollection.get(iconName) + if (iconName === undefined) { + iconName = nodeDefinition.type.toLowerCase() + iconName = iconName.split(" ").join("-") + } + let icon = thisObject.iconCollection.get(iconName) + if (icon !== undefined) { thisObject.iconByUiObjectType.set(nodeDefinition.type, icon) } } From 3ad31e26d608773dbfe50dd3f66c2bfa4337baf5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 9 Sep 2020 19:09:02 +0200 Subject: [PATCH 091/192] Docs Improved --- DesignSpace/Workspace/Workspace.js | 9 +++++++++ Globals.js | 2 ++ Utilities/{HiriarchyMap.js => Hiriarchy.js} | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) rename Utilities/{HiriarchyMap.js => Hiriarchy.js} (82%) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index a408c2184..ecb4293a4 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -722,6 +722,15 @@ function newWorkspace() { if (definition !== undefined) { if (definition.docURL !== undefined) { canvas.docSpace.navigateTo(definition.docURL) + } else { + let headName = getHiriarchyHead(payload.node).type + headName = headName.toLowerCase() + headName = headName.split(" ").join("-") + let nodeName = payload.node.type + nodeName = nodeName.toLowerCase() + nodeName = nodeName.split(" ").join("-") + url = DOCUMENTATION_URL_PREFIX + "suite-hierarchy-" + headName + ".html#" + nodeName + canvas.docSpace.navigateTo(url) } } } diff --git a/Globals.js b/Globals.js index 88ede4643..dde37e5cb 100644 --- a/Globals.js +++ b/Globals.js @@ -28,6 +28,8 @@ const UI_FONT = { SECONDARY: "Source Code Pro" }; +const DOCUMENTATION_URL_PREFIX = 'https://julian-molina.github.io/Documentation/' + const MAC_AMOUNT_FACTOR = 5 const IS_MAC = navigator.platform.toUpperCase().indexOf('MAC') >= 0 diff --git a/Utilities/HiriarchyMap.js b/Utilities/Hiriarchy.js similarity index 82% rename from Utilities/HiriarchyMap.js rename to Utilities/Hiriarchy.js index 6b37803b6..1c4665a77 100644 --- a/Utilities/HiriarchyMap.js +++ b/Utilities/Hiriarchy.js @@ -45,3 +45,19 @@ function getHiriarchyMap(rootNode) { } } } + +function getHiriarchyHead(initialNode) { + let headNode + stepBackwards(initialNode) + return headNode + + function stepBackwards(node) { + if (node === undefined) {return} + if (node.payload === undefined) {return} + if (node.payload.parentNode === undefined) { + headNode = node + } else { + stepBackwards(node.payload.parentNode) + } + } +} From 601b50b682a3ec609928e935001b0dcb41831d3d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 9 Sep 2020 19:35:03 +0200 Subject: [PATCH 092/192] Update Workspace.js --- DesignSpace/Workspace/Workspace.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index ecb4293a4..2a4adabb2 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -726,10 +726,10 @@ function newWorkspace() { let headName = getHiriarchyHead(payload.node).type headName = headName.toLowerCase() headName = headName.split(" ").join("-") - let nodeName = payload.node.type + let nodeName = payload.node.type nodeName = nodeName.toLowerCase() nodeName = nodeName.split(" ").join("-") - url = DOCUMENTATION_URL_PREFIX + "suite-hierarchy-" + headName + ".html#" + nodeName + url = DOCUMENTATION_URL_PREFIX + "suite-hierarchy-" + headName + ".html#" + nodeName canvas.docSpace.navigateTo(url) } } From e3829418b1d8614c741041cfd01eee42062ee005 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 10 Sep 2020 21:44:45 +0200 Subject: [PATCH 093/192] Bug Fixed References --- .../FunctionLibraries/UiObjectsFromNodes.js | 23 +++++++++++++++---- EventsServerClient.js | 2 +- FloatingSpace/UiObjectConstructor.js | 20 ++++++++-------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index cc7b25ab2..372dbe01f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -32,7 +32,7 @@ function newUiObjectsFromNodes() { let blobService = newFileStorage() // if (node.config === undefined) { - node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Example-ETH-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' + node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' // } let config = JSON.parse(node.config) @@ -63,7 +63,7 @@ function newUiObjectsFromNodes() { } } receivedNode.isIncluded = true - node.rootNodes.push(receivedNode) + node.rootNodes.unshift(receivedNode) totalIncluded++ if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { addUserDefinedNodes() @@ -92,7 +92,7 @@ function newUiObjectsFromNodes() { } } receivedNode.isIncluded = true - node.rootNodes.push(receivedNode) + node.rootNodes.unshift(receivedNode) totalIncluded++ if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { addUserDefinedNodes() @@ -121,7 +121,7 @@ function newUiObjectsFromNodes() { } } receivedNode.isIncluded = true - node.rootNodes.push(receivedNode) + node.rootNodes.unshift(receivedNode) totalIncluded++ if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { addUserDefinedNodes() @@ -167,10 +167,16 @@ function newUiObjectsFromNodes() { function tryToConnectChildrenWithReferenceParents() { /* We reconstruct here the reference relationships. */ for (const [key, node] of mapOfNodes) { + if (node.id === "54854f90-d121-4365-8f40-9a26e7af1097") { + console.log('ACA') + } if (node.payload === undefined) { continue } if (node.payload.referenceParent !== undefined) { if (node.payload.referenceParent.cleaned === true) { node.payload.referenceParent = mapOfNodes.get(node.payload.referenceParent.id) + if (node.payload.referenceParent === undefined) { + console.log(node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') + } continue // We were referencing a deleted node, so we replace it potentially with a newly created one. } else { continue // In this case the reference is already good. @@ -179,6 +185,9 @@ function newUiObjectsFromNodes() { if (node.savedPayload !== undefined) { if (node.savedPayload.referenceParent !== undefined) { // these are children recreated node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) + if (node.payload.referenceParent === undefined) { + console.log(node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') + } } } } @@ -460,8 +469,13 @@ function newUiObjectsFromNodes() { if (node.id === undefined) { node.id = newUniqueId() } else { + /* + We need to avoid nodes having the same id. If we add nodes to a workspace that already exist with the same Id, + the nodes being added will get a new id at this moment. + */ let testNode = mapOfNodes.get(node.id) if (testNode !== undefined && testNode.cleaned !== true) { + console.log(testNode.name + ' already have the id of the node ' + node.name + ' being added.') node.id = newUniqueId() } } @@ -587,6 +601,7 @@ function newUiObjectsFromNodes() { /* Now we mount the floating object where the UIOBject will be laying on top of */ canvas.floatingSpace.uiObjectConstructor.createUiObject(userAddingNew, payload) + /* This is the point where we build a map with all nodes present at the workspace */ mapOfNodes.set(node.id, node) /* Check if there are tasks to run */ diff --git a/EventsServerClient.js b/EventsServerClient.js index e76d3f545..520d095a7 100644 --- a/EventsServerClient.js +++ b/EventsServerClient.js @@ -87,7 +87,7 @@ function newEventsServerClient(networkNode) { if (WEB_SOCKETS_CONNECTION.readyState === 1) { WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer) } else { - console.log('WebSocket message could not be sent because the connection was not ready. Will retry soon. Message = ' + JSON.stringify(command)) + //console.log('WebSocket message could not be sent because the connection was not ready. Will retry soon. Message = ' + JSON.stringify(command)) } } diff --git a/FloatingSpace/UiObjectConstructor.js b/FloatingSpace/UiObjectConstructor.js index 4443ea708..643fde2a0 100644 --- a/FloatingSpace/UiObjectConstructor.js +++ b/FloatingSpace/UiObjectConstructor.js @@ -229,8 +229,8 @@ function newUiObjectConstructor() { currentStatus: false, label: undefined, visible: true, - iconPathOn: 'menu-fix-pinned', - iconPathOff: 'menu-fix-unpinned', + iconPathOn: 'pinned', + iconPathOff: 'unpinned', rawRadius: 12, targetRadius: 0, currentRadius: 0, @@ -290,8 +290,8 @@ function newUiObjectConstructor() { currentStatus: true, label: undefined, visible: true, - iconPathOn: 'menu-mobility-unfreeze', - iconPathOff: 'menu-mobility-freeze', + iconPathOn: 'unfreeze', + iconPathOff: 'freeze', rawRadius: 12, targetRadius: 0, currentRadius: 0, @@ -306,8 +306,8 @@ function newUiObjectConstructor() { currentStatus: false, label: undefined, visible: true, - iconPathOn: 'menu-tree-plus', - iconPathOff: 'menu-tree-minus', + iconPathOn: 'expand', + iconPathOff: 'collapse', rawRadius: 12, targetRadius: 0, currentRadius: 0, @@ -320,8 +320,8 @@ function newUiObjectConstructor() { actionFunction: floatingObject.payload.onMenuItemClick, label: undefined, visible: true, - iconPathOn: 'menu-backup', - iconPathOff: 'menu-backup', + iconPathOn: 'backup', + iconPathOff: 'backup', rawRadius: 12, targetRadius: 0, currentRadius: 0, @@ -349,8 +349,8 @@ function newUiObjectConstructor() { actionFunction: floatingObject.payload.onMenuItemClick, label: undefined, visible: true, - iconPathOn: 'menu-share', - iconPathOff: 'menu-share', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 12, targetRadius: 0, currentRadius: 0, From 09cc8f2c0af6755b9ed333285846423000870680 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 10 Sep 2020 22:43:38 +0200 Subject: [PATCH 094/192] Update UiObjectsFromNodes.js --- DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 372dbe01f..aedd8baf5 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -32,7 +32,7 @@ function newUiObjectsFromNodes() { let blobService = newFileStorage() // if (node.config === undefined) { - node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' + node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Sparta-BBTB-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' // } let config = JSON.parse(node.config) From 38e2f8ebcd28d7bfe90fed42d6587b264920a165 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 11 Sep 2020 11:30:22 +0200 Subject: [PATCH 095/192] Update UiObjectsFromNodes.js --- .../FunctionLibraries/UiObjectsFromNodes.js | 49 +++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index aedd8baf5..b30ab2802 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -26,24 +26,33 @@ function newUiObjectsFromNodes() { tasksToRun = [] sessionsToRun = [] - addIncludedNodes() + getIncludedNames() + + function getIncludedNames() { - function addIncludedNodes() { + callServer(undefined, 'IncludedNames', onResponse) + + function onResponse(err, data) { + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Failed to Fetch Inclided Names from the Backend') + return + } + + let includedNames = JSON.parse(data) + addIncludedNodes(includedNames) + } + } + + function addIncludedNodes(includedNames) { let blobService = newFileStorage() - - // if (node.config === undefined) { - node.config = '{ \n"includeDataMines": ["Masters", "Sparta", "Masters-Trading"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Sparta-BBTB-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }' - // } - - let config = JSON.parse(node.config) - let includeDataMines = config.includeDataMines - let includeTradingSystems = config.includeTradingSystems - let includeSuperScripts = config.includeSuperScripts + let includedDataMines = includedNames.includedDataMines + let includedTradingSystems = includedNames.includedTradingSystems + let includedSuperScripts = includedNames.includedSuperScripts let totalIncluded = 0 - for (let i = 0; i < includeDataMines.length; i++) { - let name = includeDataMines[i] + for (let i = 0; i < includedDataMines.length; i++) { + let name = includedDataMines[i] blobService.getFileFromHost('DataMines' + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { @@ -65,14 +74,14 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length) { addUserDefinedNodes() } } } - for (let i = 0; i < includeTradingSystems.length; i++) { - let name = includeTradingSystems[i] + for (let i = 0; i < includedTradingSystems.length; i++) { + let name = includedTradingSystems[i] blobService.getFileFromHost('TradingSystems' + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { @@ -94,14 +103,14 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length) { addUserDefinedNodes() } } } - for (let i = 0; i < includeSuperScripts.length; i++) { - let name = includeSuperScripts[i] + for (let i = 0; i < includedSuperScripts.length; i++) { + let name = includedSuperScripts[i] blobService.getFileFromHost('SuperScripts' + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { @@ -123,7 +132,7 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includeDataMines.length + includeTradingSystems.length + includeSuperScripts.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length) { addUserDefinedNodes() } } From d7aa68dd40f0712fc8d028255d18526b89f5c16b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 11 Sep 2020 13:49:09 +0200 Subject: [PATCH 096/192] Data Dependencies --- .../FunctionLibraries/DataMineFunctions.js | 61 ++++++++++++++++++- DesignSpace/Workspace/Workspace.js | 10 +++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js index 68f2ba42b..13fae905b 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataMineFunctions.js @@ -1,6 +1,8 @@ function newDataMineFunctions() { thisObject = { - addAllOutputDatasets: addAllOutputDatasets + addAllOutputDatasets: addAllOutputDatasets, + addAllDataDependencies: addAllDataDependencies, + addAllDataMineDataDependencies: addAllDataMineDataDependencies } return thisObject @@ -41,4 +43,61 @@ function newDataMineFunctions() { functionLibraryUiObjectsFromNodes ) } + + function addAllDataDependencies(node, functionLibraryUiObjectsFromNodes) { + + /* Validations to see if we can do this or not. */ + if (node.payload === undefined) { return } + if (node.payload.uiObject === undefined) { return } + if (node.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a reference parent node to execute this action.') + return + } + if (node.payload.referenceParent.payload === undefined) { + node.payload.uiObject.setErrorMessage('You need to have a reference parent node to execute this action.') + return + } + + /* + Next, we are going to scan through all the bots of the Data Mine referenced, and for each bot we will + create a Bots Data Dependency node. Later we will scan all the Products Definitions of each bot, and for each + Dataset of each Product we will create a Data Dependency. In case we find Product Definition Folders, we will + recreate that structure too, using in this case Data Dependency Folders. + */ + let dataMine = node.payload.referenceParent + scanBotArray(dataMine.sensorBots) + scanBotArray(dataMine.indicatorBots) + scanBotArray(dataMine.tradingBots) + + function scanBotArray(botArray) { + for (let i = 0; i < botArray.length; i++) { + let bot = botArray[i] + let botProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Bot Data Dependencies') + botProducts.name = bot.name + + asymetricalFolderStructureCloning( + bot, + botProducts, + 'products', + 'productDefinitionFolders', + 'dataDependencyFolders', + 'Data Dependency', + 'Data Dependency Folder', + 'datasets', + functionLibraryUiObjectsFromNodes + ) + } + } + } + + function addAllDataMineDataDependencies(node, rootNodes, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + + if (rootNode.type === 'Data Mine') { + let dataMineDataDependencies = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Data Mine Data Dependencies') + dataMineDataDependencies.payload.referenceParent = rootNode + } + } + } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 2a4adabb2..04d9d72ab 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -631,6 +631,16 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addAllDataMineProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add All Data Dependencies': + { + functionLibraryDataMineFunctions.addAllDataDependencies(payload.node, functionLibraryUiObjectsFromNodes) + } + break + case 'Add All Data Mine Dependencies': + { + functionLibraryDataMineFunctions.addAllDataMineDataDependencies(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add All Data Mine Layers': { functionLibraryChartingSpaceFunctions.addAllDataMineLayers(payload.node, functionLibraryUiObjectsFromNodes) From 35229ac9cd1703a0e9d1fc0e2aa6def6c07710f3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 11 Sep 2020 15:20:10 +0200 Subject: [PATCH 097/192] Update TaskFunctions.js --- DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 7ce23ca32..8e070e9bf 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -42,6 +42,8 @@ function newTaskFunctions() { 'Output Dataset->Dataset Definition->Product Definition->' + 'Process Dependencies->' + 'Status Dependency->Status Report->Process Definition->' + + 'Data Mine Data Dependencies->Bot Data Dependencies->' + + 'Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->' + 'Data Dependency->Dataset Definition->Product Definition->' + 'Record Definition->Record Property->Formula->' + 'Data Building Procedure->' + From f13bf71addbbdc16e74e6f661df651410a45ce54 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 12 Sep 2020 09:54:16 +0200 Subject: [PATCH 098/192] Update UiObjectsFromNodes.js --- .../FunctionLibraries/UiObjectsFromNodes.js | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index b30ab2802..029fca001 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -27,18 +27,18 @@ function newUiObjectsFromNodes() { sessionsToRun = [] getIncludedNames() - + function getIncludedNames() { callServer(undefined, 'IncludedNames', onResponse) - + function onResponse(err, data) { if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { console.log('Failed to Fetch Inclided Names from the Backend') return } - - let includedNames = JSON.parse(data) + + let includedNames = JSON.parse(data) addIncludedNodes(includedNames) } } @@ -48,6 +48,7 @@ function newUiObjectsFromNodes() { let includedDataMines = includedNames.includedDataMines let includedTradingSystems = includedNames.includedTradingSystems let includedSuperScripts = includedNames.includedSuperScripts + let includedTradingEngines = includedNames.includedTradingEngines let totalIncluded = 0 @@ -74,7 +75,7 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { addUserDefinedNodes() } } @@ -85,7 +86,7 @@ function newUiObjectsFromNodes() { blobService.getFileFromHost('TradingSystems' + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') + console.log('Cannot load included Trading System ' + name + '. The workspace can not be loaded.') return } let receivedNode = JSON.parse(text) @@ -103,7 +104,7 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { addUserDefinedNodes() } } @@ -114,7 +115,7 @@ function newUiObjectsFromNodes() { blobService.getFileFromHost('SuperScripts' + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') + console.log('Cannot load included Super Script ' + name + '. The workspace can not be loaded.') return } let receivedNode = JSON.parse(text) @@ -132,7 +133,33 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { + addUserDefinedNodes() + } + } + } + + for (let i = 0; i < includedTradingEngines.length; i++) { + let name = includedTradingEngines[i] + blobService.getFileFromHost('TradingEngines' + '/' + name, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Cannot load included Trading Engine ' + name + '. The workspace can not be loaded.') + return + } + let receivedNode = JSON.parse(text) + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.type === 'Trading Engine') { + if (rootNode.name === name) { + rootNodes.splice(i, 1) + } + } + } + receivedNode.isIncluded = true + node.rootNodes.unshift(receivedNode) + totalIncluded++ + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { addUserDefinedNodes() } } From fd5d0b4da383c8bdee8ecff05ccdfd3b6d1e5abb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 12 Sep 2020 13:45:45 +0200 Subject: [PATCH 099/192] Cleaning --- FloatingSpace/UiObject.js | 164 +++++++++++++++++++------------------- Plotting/Plotter.js | 8 +- 2 files changed, 88 insertions(+), 84 deletions(-) diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index d0e86f13c..5595b7891 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -973,48 +973,96 @@ function newUiObject() { setupErrorEventListener(callBackFunction) setupWarningEventListener() setupInfoEventListener() - } - function setupRunningEventListener(callBackFunction) { - /* We will wait to hear the Running event in order to confirm the execution was really started */ - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning) - - onRunningCallBackFunction = callBackFunction - - function onResponse(message) { - eventSubscriptionIdOnRunning = message.eventSubscriptionId + function setupRunningEventListener(callBackFunction) { + /* We will wait to hear the Running event in order to confirm the execution was really started */ + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning) + + onRunningCallBackFunction = callBackFunction + + function onResponse(message) { + eventSubscriptionIdOnRunning = message.eventSubscriptionId + } + + function onRunning() { + if (thisObject.payload === undefined) { return } + + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') + + thisObject.isRunning = true + + if (callBackFunction !== undefined) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + onRunningCallBackFunctionWasCalled = true + } + } + + /* + While it is running, it can happen that it naturally stops or is stopped not from the UI but from other means. + In those cases, the stop function would never be called (from the UI). So what we will do is to call it from + here with and event, and passing our own callBackFunction. In case there is an external source stopping this, + this will produce an execution of the callback with our event, which will produce that the menu item is restored + to its default stage. + + If on the other side, it is executed from the UI, then we will be processing the Stopped event twice, which in + both cases will reset the menu item to its default state. + */ + + let event = { + type: 'Secondary Action Already Executed' + } + stop(callBackFunction, event) } - function onRunning() { - if (thisObject.payload === undefined) { return } - + function setupErrorEventListener(callBackFunction) { let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') - - thisObject.isRunning = true - - if (callBackFunction !== undefined) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - onRunningCallBackFunctionWasCalled = true + eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError) + + function onResponse(message) { + eventSubscriptionIdOnError = message.eventSubscriptionId + } + + function onError(message) { + + let uiObject = getTargetUiObject(message) + uiObject.setErrorMessage(message.event.errorMessage, 10) + + let event = { + type: 'Secondary Action Already Executed' + } + completeStop(callBackFunction, event) } } - - /* - While it is running, it can happen that it naturally stops or is stopped not from the UI but from other means. - In those cases, the stop function would never be called (from the UI). So what we will do is to call it from - here with and event, and passing our own callBackFunction. In case there is an external source stopping this, - this will produce an execution of the callback with our event, which will produce that the menu item is restored - to its default stage. - If on the other side, it is executed from the UI, then we will be processing the Stopped event twice, which in - both cases will reset the menu item to its default state. - */ - - let event = { - type: 'Secondary Action Already Executed' + function setupWarningEventListener() { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Warning', undefined, key, onResponse, onWarning) + + function onResponse(message) { + eventSubscriptionIdOnWarning = message.eventSubscriptionId + } + + function onWarning(message) { + let uiObject = getTargetUiObject(message) + uiObject.setWarningMessage(message.event.warningMessage, 10) + } + } + + function setupInfoEventListener() { + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id + eventsServerClient.listenToEvent(key, 'Info', undefined, key, onResponse, onInfo) + + function onResponse(message) { + eventSubscriptionIdOnInfo = message.eventSubscriptionId + } + + function onInfo(message) { + let uiObject = getTargetUiObject(message) + uiObject.setInfoMessage(message.event.infoMessage, 10) + } } - stop(callBackFunction, event) } function getTargetUiObject(message) { @@ -1032,54 +1080,6 @@ function newUiObject() { return uiObject } - function setupErrorEventListener(callBackFunction) { - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError) - - function onResponse(message) { - eventSubscriptionIdOnError = message.eventSubscriptionId - } - - function onError(message) { - - let uiObject = getTargetUiObject(message) - uiObject.setErrorMessage(message.event.errorMessage, 10) - - let event = { - type: 'Secondary Action Already Executed' - } - completeStop(callBackFunction, event) - } - } - - function setupWarningEventListener() { - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Warning', undefined, key, onResponse, onWarning) - - function onResponse(message) { - eventSubscriptionIdOnWarning = message.eventSubscriptionId - } - - function onWarning(message) { - let uiObject = getTargetUiObject(message) - uiObject.setWarningMessage(message.event.warningMessage, 10) - } - } - - function setupInfoEventListener() { - let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - eventsServerClient.listenToEvent(key, 'Info', undefined, key, onResponse, onInfo) - - function onResponse(message) { - eventSubscriptionIdOnInfo = message.eventSubscriptionId - } - - function onInfo(message) { - let uiObject = getTargetUiObject(message) - uiObject.setInfoMessage(message.event.infoMessage, 10) - } - } - function stop(callBackFunction, event) { /* We will wait to the event that the execution was terminated in order to call back the menu item */ let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index f2fdccf6c..96cb8c927 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -822,8 +822,12 @@ function newPlotter() { imagePosition.x = dataPoint.x imagePosition.y = dataPoint.y let imageToDraw = canvas.designSpace.iconCollection.get(imageName) - if (imageToDraw.canDrawIcon === true) { - browserCanvasContext.drawImage(imageToDraw, imagePosition.x - imageSize / 2 + offsetX, imagePosition.y - imageSize / 2 - offsetY, imageSize, imageSize) + if (imageToDraw !== undefined) { + if (imageToDraw.canDrawIcon === true) { + browserCanvasContext.drawImage(imageToDraw, imagePosition.x - imageSize / 2 + offsetX, imagePosition.y - imageSize / 2 - offsetY, imageSize, imageSize) + } + } else { + console.log('Can not plot image named '+ imageName + ' of product ' + productDefinition.name + ' because it does not exist.') } } From 17860ec9f9096a8f6de2ff409d576a9f95deeb56 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 12 Sep 2020 15:20:16 +0200 Subject: [PATCH 100/192] UI Performance Improvement --- FloatingSpace/CircularMenuItem.js | 20 ++++++++++---------- FloatingSpace/FloatingLayer.js | 24 ++++++++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 8a1849d4a..bf21cf958 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -275,7 +275,7 @@ function newCircularMenuItem() { function internalClick() { if (thisObject.shorcutNumber !== undefined) { let label = thisObject.payload.node.name + ' ' + labelToPrint - canvas.cockpitSpace.setStatus(label, 40, canvas.cockpitSpace.statusTypes.ALL_GOOD) + canvas.cockpitSpace.setStatus(label, 4, canvas.cockpitSpace.statusTypes.ALL_GOOD) } onMouseClick() @@ -299,16 +299,16 @@ function newCircularMenuItem() { /* The first click ask for confirmation. */ if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET) { - setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 200, STATUS_WAITING_CONFIRMATION) + setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 20, STATUS_WAITING_CONFIRMATION) return } /* A Click during confirmation executes the pre-defined action. */ if (temporaryStatus === STATUS_WAITING_CONFIRMATION || temporaryStatus === STATUS_PRIMARY_WORK_DONE) { executeAction() if (thisObject.workDoneLabel !== undefined) { - setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) + setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 5, STATUS_SECONDARY_WORK_DONE) } else { - setStatus('Done', UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) + setStatus('Done', UI_COLOR.PATINATED_TURQUOISE, 5, STATUS_SECONDARY_WORK_DONE) } return } @@ -342,7 +342,7 @@ function newCircularMenuItem() { if (event !== undefined) { if (event.type === 'Secondary Action Already Executed') { - setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 5, STATUS_SECONDARY_WORK_DONE) return } } @@ -351,11 +351,11 @@ function newCircularMenuItem() { if (thisObject.secondaryAction === undefined) { // This means there are no more possible actions. if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { if (thisObject.workDoneLabel !== undefined) { - setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_PRIMARY_WORK_DONE) + setStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 5, STATUS_PRIMARY_WORK_DONE) } } else { if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 50, STATUS_PRIMARY_WORK_FAILED) + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 5, STATUS_PRIMARY_WORK_FAILED) } } } else { @@ -366,7 +366,7 @@ function newCircularMenuItem() { } } else { if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 50, STATUS_PRIMARY_WORK_FAILED) + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 5, STATUS_PRIMARY_WORK_FAILED) } } } @@ -374,11 +374,11 @@ function newCircularMenuItem() { function onSecondaryCallBack(err) { if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { if (thisObject.secondaryWorkDoneLabel !== undefined) { - setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 50, STATUS_SECONDARY_WORK_DONE) + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 5, STATUS_SECONDARY_WORK_DONE) } } else { if (thisObject.secondaryWorkFailedLabel != undefined) { - setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 50, STATUS_SECONDARY_WORK_FAILED) + setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 5, STATUS_SECONDARY_WORK_FAILED) } } } diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index 95aec16f9..a17f10bf2 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -52,17 +52,18 @@ function newFloatingLayer() { let maxTargetRepulsionForce = 0.001 let currentHandle = 0 + let invisiblePhysicsIntervalId return thisObject function finalize() { + clearInterval(invisiblePhysicsIntervalId) invisibleFloatingObjects = [] visibleFloatingObjects = [] } function initialize() { - - /* We dont need to initialize anything right now. */ + invisiblePhysicsIntervalId = setInterval(invisiblePhysics, 1000) } function getContainer(point) { @@ -241,6 +242,17 @@ function newFloatingLayer() { /* */ /******************************************/ + function invisiblePhysics() { + /* + Note that the Physics for invisible objects is called with a fixed time interval, + since it does not need the high intensity physics called during the animation. + */ + for (let i = 0; i < invisibleFloatingObjects.length; i++) { + let floatingObject = invisibleFloatingObjects[i] + floatingObject.invisiblePhysics() + } + } + function physics() { /* The Physics engine is hooked at the animation loop, so it executes very very often. According to this Physics engine, each @@ -259,17 +271,9 @@ function newFloatingLayer() { try { makeVisible() makeInvisible() - invisiblePhysics() visiblePhysics() applyPhysics() - function invisiblePhysics() { - for (let i = 0; i < invisibleFloatingObjects.length; i++) { - let floatingObject = invisibleFloatingObjects[i] - floatingObject.invisiblePhysics() - } - } - function visiblePhysics() { for (let i = 0; i < visibleFloatingObjects.length; i++) { let floatingObject = visibleFloatingObjects[i] From 040b8a7f4f845cdd425a32c234de38213a03ccf5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 12 Sep 2020 20:33:02 +0200 Subject: [PATCH 101/192] Data Mining --- .../FunctionLibraries/TaskFunctions.js | 58 +++++++++++++++--- .../FunctionLibraries/UiObjectsFromNodes.js | 13 ++++ DesignSpace/Workspace/Workspace.js | 23 +++++-- FloatingSpace/CircularMenuItem.js | 2 +- Utilities/NodeChildren.js | 61 +++++++++++++++++++ 5 files changed, 144 insertions(+), 13 deletions(-) create mode 100644 Utilities/NodeChildren.js diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 8e070e9bf..6509cec62 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -6,8 +6,11 @@ function newTaskFunctions() { stopAllTasks: stopAllTasks, runAllTaskManagers: runAllTaskManagers, stopAllTaskManagers: stopAllTaskManagers, - runAllExchangeTasks: runAllExchangeTasks, - stopAllExchangeTasks: stopAllExchangeTasks + runAllExchangeDataTasks: runAllExchangeDataTasks, + stopAllExchangeDataTasks: stopAllExchangeDataTasks, + runAllExchangeTradingTasks: runAllExchangeTradingTasks, + stopAllExchangeTradingTasks: stopAllExchangeTradingTasks, + addMissingExchangeDataTasks: addMissingExchangeDataTasks } return thisObject @@ -42,8 +45,8 @@ function newTaskFunctions() { 'Output Dataset->Dataset Definition->Product Definition->' + 'Process Dependencies->' + 'Status Dependency->Status Report->Process Definition->' + - 'Data Mine Data Dependencies->Bot Data Dependencies->' + - 'Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->' + + 'Data Mine Data Dependencies->Bot Data Dependencies->' + + 'Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->Data Dependency Folder->' + 'Data Dependency->Dataset Definition->Product Definition->' + 'Record Definition->Record Property->Formula->' + 'Data Building Procedure->' + @@ -56,7 +59,7 @@ function newTaskFunctions() { 'Execution Finished Event->' + 'Execution Started Event->Execution Finished Event->Process Definition->' + 'Sensor Bot->' + - 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Indicator Bot->' + 'Trading Bot->' + 'Data Mine->' @@ -67,7 +70,7 @@ function newTaskFunctions() { 'Data Storage->Session Independent Data->Exchange Data Products->' + 'Single Market Data->' + 'Data Mine Products->Bot Products->' + - 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Data Product->Product Definition->' + 'Data Mining->Testing Environment->Production Environment->' + 'Exchange Tasks->Crypto Exchange->' + @@ -215,7 +218,7 @@ function newTaskFunctions() { menu.internalClick('Stop All Tasks') } } - function runAllExchangeTasks(parent, functionLibraryProtocolNode) { + function runAllExchangeDataTasks(parent, functionLibraryProtocolNode) { for (let i = 0; i < parent.exchangeTasks.length; i++) { let node = parent.exchangeTasks[i] let menu = node.payload.uiObject.menu @@ -225,7 +228,7 @@ function newTaskFunctions() { } } - function stopAllExchangeTasks(parent, functionLibraryProtocolNode) { + function stopAllExchangeDataTasks(parent, functionLibraryProtocolNode) { for (let i = 0; i < parent.exchangeTasks.length; i++) { let node = parent.exchangeTasks[i] let menu = node.payload.uiObject.menu @@ -234,4 +237,43 @@ function newTaskFunctions() { menu.internalClick('Stop All Task Managers') } } + + function runAllExchangeTradingTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.exchangeTasks.length; i++) { + let node = parent.exchangeTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Run All Task Managers') + menu.internalClick('Run All Task Managers') + } + } + + function stopAllExchangeTradingTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.exchangeTasks.length; i++) { + let node = parent.exchangeTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Task Managers') + menu.internalClick('Stop All Task Managers') + } + } + + function addMissingExchangeDataTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Crypto Ecosystem') { + cryptoEcosystem = rootNode + for (let j = 0; j < cryptoEcosystem.cryptoExchanges.length; j++) { + let cryptoExchanges = cryptoEcosystem.cryptoExchanges[j] + for (let k=0; k < cryptoExchanges.exchanges.length; k++) { + let cryptoExchange = cryptoExchanges.exchanges[j] + if (isMissingChildren(node, cryptoExchange, true) === true) { + let exchangeDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Exchange Data Tasks') + exchangeDataTasks.payload.referenceParent = cryptoExchange + } + } + } + } + } + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 029fca001..9f6094a2f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -26,6 +26,19 @@ function newUiObjectsFromNodes() { tasksToRun = [] sessionsToRun = [] + removeNullRootNodes() + + function removeNullRootNodes() { + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode === null) { + node.rootNodes.splice(i, 1) + removeNullRootNodes() + return + } + } + } + getIncludedNames() function getIncludedNames() { diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 04d9d72ab..5070a8370 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -591,14 +591,29 @@ function newWorkspace() { functionLibraryTaskFunctions.stopAllTaskManagers(payload.node, functionLibraryProtocolNode) } break - case 'Run All Exchange Tasks': + case 'Run All Exchange Data Tasks': { - functionLibraryTaskFunctions.runAllExchangeTasks(payload.node, functionLibraryProtocolNode) + functionLibraryTaskFunctions.runAllExchangeDataTasks(payload.node, functionLibraryProtocolNode) } break - case 'Stop All Exchange Tasks': + case 'Stop All Exchange Data Tasks': { - functionLibraryTaskFunctions.stopAllExchangeTasks(payload.node, functionLibraryProtocolNode) + functionLibraryTaskFunctions.stopAllExchangeDataTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Run All Exchange Trading Tasks': + { + functionLibraryTaskFunctions.runAllExchangeTradingTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Exchange Trading Tasks': + { + functionLibraryTaskFunctions.stopAllExchangeTradingTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Add Missing Exchange Data Tasks': + { + functionLibraryTaskFunctions.addMissingExchangeDataTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break case 'Add Missing Crypto Exchanges': diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index bf21cf958..0a632691f 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -299,7 +299,7 @@ function newCircularMenuItem() { /* The first click ask for confirmation. */ if (temporaryStatus === STATUS_NO_ACTION_TAKEN_YET) { - setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 20, STATUS_WAITING_CONFIRMATION) + setStatus(thisObject.confirmationLabel, UI_COLOR.GOLDEN_ORANGE, 100, STATUS_WAITING_CONFIRMATION) return } /* A Click during confirmation executes the pre-defined action. */ diff --git a/Utilities/NodeChildren.js b/Utilities/NodeChildren.js new file mode 100644 index 000000000..3af5b1643 --- /dev/null +++ b/Utilities/NodeChildren.js @@ -0,0 +1,61 @@ +function isMissingChildren(startingNode, checkNode, checkReferenceParent) { + /* + This functioin scan all the children of a node and returns true or false + depending if the checkNode is a missing children. + */ + if (startingNode === undefined) { return } + if (checkNode === undefined) { return } + + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + /* We scan through this node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + let child = startingNode[property.name] + if (checkReferenceParent !== true) { + if (child.id === checkNode.id) { + return false + } + } else { + if (child.payload !== undefined) { + if (child.payload.referenceParent !== undefined) { + if (child.payload.referenceParent.id === checkNode.id) { + return false + } + } + } + } + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + let arrayItem = startingNodePropertyArray[m] + if (checkReferenceParent !== true) { + if (arrayItem.id === checkNode.id) { + return false + } + } else { + if (arrayItem.payload !== undefined) { + if (arrayItem.payload.referenceParent !== undefined) { + if (arrayItem.payload.referenceParent.id === checkNode.id) { + return false + } + } + } + } + } + } + break + } + } + } + return true + } +} \ No newline at end of file From fd5879e04f97a81d553408e6712096e84d60eb27 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 08:58:11 +0200 Subject: [PATCH 102/192] Market Data Tasks --- ChartingSpace/PlottersManager.js | 5 +++- .../FunctionLibraries/TaskFunctions.js | 24 ++++++++++++++++--- DesignSpace/Workspace/Workspace.js | 5 ++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index 0a0092364..09abb9b7a 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -148,7 +148,10 @@ function newPlottersManager() { if (sessionReference !== undefined) { session = sessionReference.referenceParent - + if (session === undefined) { + logger.write('[ERROR] initializePlotter -> Sessioin is Undefined at Session Reference -> Plotter will not be loaded. ') + return + } /* From the session we might be able to reach the Trading System or the Trading Engine */ if (session.tradingSystemReference !== undefined) { tradingSystem = session.tradingSystemReference.referenceParent diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 6509cec62..8bedc60b3 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -10,7 +10,8 @@ function newTaskFunctions() { stopAllExchangeDataTasks: stopAllExchangeDataTasks, runAllExchangeTradingTasks: runAllExchangeTradingTasks, stopAllExchangeTradingTasks: stopAllExchangeTradingTasks, - addMissingExchangeDataTasks: addMissingExchangeDataTasks + addMissingExchangeDataTasks: addMissingExchangeDataTasks, + addMissingMarketDataTasks: addMissingMarketDataTasks } return thisObject @@ -265,8 +266,8 @@ function newTaskFunctions() { cryptoEcosystem = rootNode for (let j = 0; j < cryptoEcosystem.cryptoExchanges.length; j++) { let cryptoExchanges = cryptoEcosystem.cryptoExchanges[j] - for (let k=0; k < cryptoExchanges.exchanges.length; k++) { - let cryptoExchange = cryptoExchanges.exchanges[j] + for (let k = 0; k < cryptoExchanges.exchanges.length; k++) { + let cryptoExchange = cryptoExchanges.exchanges[k] if (isMissingChildren(node, cryptoExchange, true) === true) { let exchangeDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Exchange Data Tasks') exchangeDataTasks.payload.referenceParent = cryptoExchange @@ -276,4 +277,21 @@ function newTaskFunctions() { } } } + + function addMissingMarketDataTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + if (node.payload === undefined) { return } + if (node.payload.referenceParent === undefined) { return } + if (node.payload.referenceParent.exchangeMarkets === undefined) { return } + + let markets = node.payload.referenceParent.exchangeMarkets.markets + + for (let i = 0; i < markets.length; i++) { + let market = markets[i] + + if (isMissingChildren(node, market, true) === true) { + let marketDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Market Data Tasks') + marketDataTasks.payload.referenceParent = market + } + } + } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 5070a8370..a9d80f2d9 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -616,6 +616,11 @@ function newWorkspace() { functionLibraryTaskFunctions.addMissingExchangeDataTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add Missing Market Data Tasks': + { + functionLibraryTaskFunctions.addMissingMarketDataTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add Missing Crypto Exchanges': { functionLibraryCCXTFunctions.addMissingExchanges(payload.node, functionLibraryUiObjectsFromNodes) From 169675c19af66e326fa9ec4ca4fba442fa255b75 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 10:21:18 +0200 Subject: [PATCH 103/192] Trading Mining --- .../FunctionLibraries/TaskFunctions.js | 86 ++++++++++++++++++- .../FunctionLibraries/UiObjectsFromNodes.js | 38 +++++++- DesignSpace/Workspace/Workspace.js | 10 +++ 3 files changed, 126 insertions(+), 8 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 8bedc60b3..e8d0b5139 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -11,7 +11,9 @@ function newTaskFunctions() { runAllExchangeTradingTasks: runAllExchangeTradingTasks, stopAllExchangeTradingTasks: stopAllExchangeTradingTasks, addMissingExchangeDataTasks: addMissingExchangeDataTasks, - addMissingMarketDataTasks: addMissingMarketDataTasks + addMissingMarketDataTasks: addMissingMarketDataTasks, + addMissingDataMineTasks: addMissingDataMineTasks, + addAllTasks: addAllTasks } return thisObject @@ -35,7 +37,7 @@ function newTaskFunctions() { 'Indicator Bot Instance->Time Frames Filter->' + 'Trading Bot Instance->' + 'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' + - 'Market Reference->Execution Started Event->' + + 'Execution Started Event->' + 'Key Reference->Exchange Account Key->' + 'Market->Exchange Markets->Crypto Exchange->' + 'Market Base Asset->Market Quoted Asset->Asset->' + @@ -79,7 +81,7 @@ function newTaskFunctions() { 'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' + 'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' + 'Paper Trading Session->Forward Testing Session->Backtesting Session->Live Trading Session->' + - 'Market Reference->Market->' + + 'Market->' + 'Process Definition->' let networkDefinition = functionLibraryProtocolNode.getProtocolNode(networkNode.payload.parentNode, false, true, true, false, false, networkLightingPath) @@ -263,7 +265,7 @@ function newTaskFunctions() { for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] if (rootNode.type === 'Crypto Ecosystem') { - cryptoEcosystem = rootNode + let cryptoEcosystem = rootNode for (let j = 0; j < cryptoEcosystem.cryptoExchanges.length; j++) { let cryptoExchanges = cryptoEcosystem.cryptoExchanges[j] for (let k = 0; k < cryptoExchanges.exchanges.length; k++) { @@ -294,4 +296,80 @@ function newTaskFunctions() { } } } + + function addMissingDataMineTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Data Mine') { + let dataMine = rootNode + + if (isMissingChildren(node, dataMine, true) === true) { + let dataMineTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Data Mine Tasks') + dataMineTasks.payload.referenceParent = dataMine + } + } + } + } + + function addAllTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + if (node.payload === undefined) { return } + if (node.payload.referenceParent === undefined) { return } + + let dataMine = node.payload.referenceParent + + let taskManager = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Task Manager') + + addTasksForBotArray(dataMine.sensorBots) + addTasksForBotArray(dataMine.indicatorBots) + + function addTasksForBotArray(botsArray) { + for (let i = 0; i < botsArray.length; i++) { + let bot = botsArray[i] + + let task = functionLibraryUiObjectsFromNodes.addUIObject(taskManager, 'Task') + task.name = bot.name + + let botInstance + switch (bot.type) { + case 'Sensor Bot': { + botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Sensor Bot Instance') + botInstance.name = bot.name + break + } + case 'Indicator Bot': { + botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Indicator Bot Instance') + botInstance.name = bot.name + break + } + case 'Trading Bot': { + botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Trading Bot Instance') + botInstance.name = bot.name + break + } + } + + for (let j = 0; j < bot.processes.length; j++) { + let process = bot.processes[j] + let processInstance + switch (bot.type) { + case 'Sensor Bot': { + processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Sensor Process Instance') + processInstance.payload.referenceParent = process + break + } + case 'Indicator Bot': { + processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Indicator Process Instance') + processInstance.payload.referenceParent = process + break + } + case 'Trading Bot': { + processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Trading Process Instance') + processInstance.payload.referenceParent = process + break + } + } + } + } + } + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 9f6094a2f..417c88a7e 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -59,6 +59,7 @@ function newUiObjectsFromNodes() { function addIncludedNodes(includedNames) { let blobService = newFileStorage() let includedDataMines = includedNames.includedDataMines + let includedTradingMines = includedNames.includedTradingMines let includedTradingSystems = includedNames.includedTradingSystems let includedSuperScripts = includedNames.includedSuperScripts let includedTradingEngines = includedNames.includedTradingEngines @@ -88,7 +89,36 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { + addUserDefinedNodes() + } + } + } + + for (let i = 0; i < includedTradingMines.length; i++) { + let name = includedTradingMines[i] + blobService.getFileFromHost('TradingMines' + '/' + name, onFileReceived, true) + function onFileReceived(err, text, response) { + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Cannot load included Trading Mine ' + name + '. The workspace can not be loaded.') + return + } + let receivedNode = JSON.parse(text) + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.type === 'Trading Mine') { + if (rootNode.config !== undefined) { + let config = JSON.parse(rootNode.config) + if (config.name === name) { + rootNodes.splice(i, 1) + } + } + } + } + receivedNode.isIncluded = true + node.rootNodes.unshift(receivedNode) + totalIncluded++ + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { addUserDefinedNodes() } } @@ -117,7 +147,7 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { addUserDefinedNodes() } } @@ -146,7 +176,7 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { addUserDefinedNodes() } } @@ -172,7 +202,7 @@ function newUiObjectsFromNodes() { receivedNode.isIncluded = true node.rootNodes.unshift(receivedNode) totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length) { + if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { addUserDefinedNodes() } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index a9d80f2d9..a9e26aa43 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -621,6 +621,16 @@ function newWorkspace() { functionLibraryTaskFunctions.addMissingMarketDataTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add Missing Data Mine Tasks': + { + functionLibraryTaskFunctions.addMissingDataMineTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add All Tasks': + { + functionLibraryTaskFunctions.addAllTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add Missing Crypto Exchanges': { functionLibraryCCXTFunctions.addMissingExchanges(payload.node, functionLibraryUiObjectsFromNodes) From f9fb1b1e22253c850fbad2bb5449efbe09f7ef66 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 12:07:23 +0200 Subject: [PATCH 104/192] Trading Tasks --- .../FunctionLibraries/TaskFunctions.js | 75 +++++++++++++++++-- DesignSpace/Workspace/Workspace.js | 15 ++++ 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index e8d0b5139..543838efc 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -13,6 +13,9 @@ function newTaskFunctions() { addMissingExchangeDataTasks: addMissingExchangeDataTasks, addMissingMarketDataTasks: addMissingMarketDataTasks, addMissingDataMineTasks: addMissingDataMineTasks, + addMissingExchangeTradingTasks: addMissingExchangeTradingTasks, + addMissingMarketTradingTasks: addMissingMarketTradingTasks, + addMissingTradingMineTasks: addMissingTradingMineTasks, addAllTasks: addAllTasks } @@ -262,6 +265,14 @@ function newTaskFunctions() { } function addMissingExchangeDataTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingExchangeTasks(node, rootNodes, 'Exchange Data Tasks', functionLibraryUiObjectsFromNodes) + } + + function addMissingExchangeTradingTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingExchangeTasks(node, rootNodes, 'Exchange Trading Tasks', functionLibraryUiObjectsFromNodes) + } + + function addMissingExchangeTasks(node, rootNodes, newNodeType, functionLibraryUiObjectsFromNodes) { for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] if (rootNode.type === 'Crypto Ecosystem') { @@ -271,7 +282,7 @@ function newTaskFunctions() { for (let k = 0; k < cryptoExchanges.exchanges.length; k++) { let cryptoExchange = cryptoExchanges.exchanges[k] if (isMissingChildren(node, cryptoExchange, true) === true) { - let exchangeDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Exchange Data Tasks') + let exchangeDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) exchangeDataTasks.payload.referenceParent = cryptoExchange } } @@ -281,6 +292,14 @@ function newTaskFunctions() { } function addMissingMarketDataTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingMarketTasks(node, rootNodes, 'Market Data Tasks', functionLibraryUiObjectsFromNodes) + } + + function addMissingMarketTradingTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingMarketTasks(node, rootNodes, 'Market Trading Tasks', functionLibraryUiObjectsFromNodes) + } + + function addMissingMarketTasks(node, rootNodes, newNodeType, functionLibraryUiObjectsFromNodes) { if (node.payload === undefined) { return } if (node.payload.referenceParent === undefined) { return } if (node.payload.referenceParent.exchangeMarkets === undefined) { return } @@ -291,20 +310,28 @@ function newTaskFunctions() { let market = markets[i] if (isMissingChildren(node, market, true) === true) { - let marketDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Market Data Tasks') + let marketDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) marketDataTasks.payload.referenceParent = market } } } function addMissingDataMineTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingMineTasks(node, rootNodes, 'Data Mine', 'Data Mine Tasks', functionLibraryUiObjectsFromNodes) + } + + function addMissingTradingMineTasks(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingMineTasks(node, rootNodes, 'Trading Mine', 'Trading Mine Tasks', functionLibraryUiObjectsFromNodes) + } + + function addMissingMineTasks(node, rootNodes, rootNodeType, newNodeType, functionLibraryUiObjectsFromNodes) { for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] - if (rootNode.type === 'Data Mine') { + if (rootNode.type === rootNodeType) { let dataMine = rootNode if (isMissingChildren(node, dataMine, true) === true) { - let dataMineTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Data Mine Tasks') + let dataMineTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) dataMineTasks.payload.referenceParent = dataMine } } @@ -319,10 +346,13 @@ function newTaskFunctions() { let taskManager = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Task Manager') - addTasksForBotArray(dataMine.sensorBots) - addTasksForBotArray(dataMine.indicatorBots) + addTasksForBotArray(dataMine.sensorBots) + addTasksForBotArray(dataMine.indicatorBots) + addTasksForBotArray(dataMine.tradingBots) function addTasksForBotArray(botsArray) { + if (botsArray === undefined) { return } + for (let i = 0; i < botsArray.length; i++) { let bot = botsArray[i] @@ -365,7 +395,40 @@ function newTaskFunctions() { case 'Trading Bot': { processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Trading Process Instance') processInstance.payload.referenceParent = process + + if (node.payload.parentNode === undefined) { return } + if (node.payload.parentNode.payload === undefined) { return } + if (node.payload.parentNode.payload.parentNode === undefined) { return } + if (node.payload.parentNode.payload.parentNode.payload === undefined) { return } + if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } + + let environment = node.payload.parentNode.payload.parentNode.payload.parentNode + let session + + switch (environment.type) { + case 'Testing Environment': { + addSession('Backtesting Session') + break + } + case 'Production Environment': { + addSession('Live Trading Session') + break + } + } break + + function addSession(sessionType) { + session = functionLibraryUiObjectsFromNodes.addUIObject(processInstance, sessionType) + session.name = task.name + ' ' + session.type + + for (let m = 0; m < rootNodes.length; m++) { + let rootNode = rootNodes[m] + if (rootNode.type === 'Trading Engine' && rootNode.isIncluded === true) { + let tradingEngine = rootNode + session.tradingEngineReference.payload.referenceParent = tradingEngine + } + } + } } } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index a9e26aa43..96db27f11 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -626,6 +626,21 @@ function newWorkspace() { functionLibraryTaskFunctions.addMissingDataMineTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add Missing Exchange Trading Tasks': + { + functionLibraryTaskFunctions.addMissingExchangeTradingTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Market Trading Tasks': + { + functionLibraryTaskFunctions.addMissingMarketTradingTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Trading Mine Tasks': + { + functionLibraryTaskFunctions.addMissingTradingMineTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add All Tasks': { functionLibraryTaskFunctions.addAllTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) From 8624a7ba4a2133d0629a3e773990cd703203d87d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 12:29:43 +0200 Subject: [PATCH 105/192] Trading Mine --- .../FunctionLibraries/SessionFunctions.js | 18 ++++++++-- .../FunctionLibraries/TaskFunctions.js | 36 +++++++++++++------ DesignSpace/Workspace/Workspace.js | 12 +++---- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index e46ed99af..c1f96d72f 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -148,17 +148,29 @@ function newSessionFunctions() { return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + let taskManager = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + + if (taskManager.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside Mine Tasks.') + return + } + + if (taskManager.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Session needs to be inside Market Tasks.') + return + } + + if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Session needs to be inside Exchange Tasks.') return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Session needs to be inside a Testing or Production Environment.') return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Session needs to be inside a Network Node.') return } diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 543838efc..c19f3c3e7 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -42,6 +42,10 @@ function newTaskFunctions() { 'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' + 'Execution Started Event->' + 'Key Reference->Exchange Account Key->' + + 'Task Manager->' + + 'Data Mine Tasks->Trading Mine Tasks->' + 'Market Data Tasks->Market Trading Tasks->' + + 'Exchange Data Tasks->Exchange Trading Tasks->' + 'Market->Exchange Markets->Crypto Exchange->' + 'Market Base Asset->Market Quoted Asset->Asset->' + 'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' + @@ -68,7 +72,7 @@ function newTaskFunctions() { 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Indicator Bot->' + 'Trading Bot->' + - 'Data Mine->' + 'Data Mine->Trading Mine->' let taskDefinition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, taskLightingPath) @@ -79,7 +83,9 @@ function newTaskFunctions() { 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Data Product->Product Definition->' + 'Data Mining->Testing Environment->Production Environment->' + - 'Exchange Tasks->Crypto Exchange->' + + 'Exchange Data Tasks->Exchange Mining Tasks->Crypto Exchange->' + + 'Market Data Tasks->Market Mining Tasks->' + + 'Data Mine Tasks->Trading Mine Tasks->' 'Task Manager->Task->' + 'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' + 'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' + @@ -148,26 +154,33 @@ function newTaskFunctions() { return } - if (node.payload.parentNode.payload.parentNode === undefined) { + let taskManager = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + + if (taskManager.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside Mine Tasks.') + return + } + + if (taskManager.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside Market Tasks.') + return + } + + if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Task needs to be inside Exchange Tasks.') return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment or a Data Mining node.') + if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment.') return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Task needs to be inside a Network Node.') return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Network.') - return - } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode if (loadPropertyFromNodeConfig(networkNode.payload, 'host') === undefined) { node.payload.uiObject.setErrorMessage('Network Node needs to have a valid Host property at its config.') @@ -224,6 +237,7 @@ function newTaskFunctions() { menu.internalClick('Stop All Tasks') } } + function runAllExchangeDataTasks(parent, functionLibraryProtocolNode) { for (let i = 0; i < parent.exchangeTasks.length; i++) { let node = parent.exchangeTasks[i] diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 96db27f11..79366ca7f 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -345,16 +345,16 @@ function newWorkspace() { for (let j = 0; j < rootNode.networkNodes.length; j++) { let networkNode = rootNode.networkNodes[j] if (networkNode.dataMining !== undefined && networkNode.dataMining.payload !== undefined) { - networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') - networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Data Tasks') + networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Data Tasks') } if (networkNode.testingEnvironment !== undefined && networkNode.testingEnvironment.payload !== undefined) { - networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') - networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Trading Tasks') + networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Trading Tasks') } if (networkNode.productionEnvironment !== undefined && networkNode.productionEnvironment.payload !== undefined) { - networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') - networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks') + networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Trading Tasks') + networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Trading Tasks') } } } From b6c536d817f50d4ea8cd83570b04edc386354957 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 14:57:32 +0200 Subject: [PATCH 106/192] Update TaskFunctions.js --- .../FunctionLibraries/TaskFunctions.js | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index c19f3c3e7..192efe0fa 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -22,12 +22,14 @@ function newTaskFunctions() { return thisObject function runTask(node, functionLibraryProtocolNode, isDebugging, callBackFunction) { - if (validations(node) !== true) { + + let networkNode = validations(node) + if (networkNode === undefined) { + /* This means that the validations failed. */ callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) return } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) for (let i = 0; i < node.bot.processes.length; i++) { @@ -43,7 +45,7 @@ function newTaskFunctions() { 'Execution Started Event->' + 'Key Reference->Exchange Account Key->' + 'Task Manager->' + - 'Data Mine Tasks->Trading Mine Tasks->' + 'Data Mine Tasks->Trading Mine Tasks->' + 'Market Data Tasks->Market Trading Tasks->' + 'Exchange Data Tasks->Exchange Trading Tasks->' + 'Market->Exchange Markets->Crypto Exchange->' + @@ -83,9 +85,9 @@ function newTaskFunctions() { 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Data Product->Product Definition->' + 'Data Mining->Testing Environment->Production Environment->' + - 'Exchange Data Tasks->Exchange Mining Tasks->Crypto Exchange->' + - 'Market Data Tasks->Market Mining Tasks->' + - 'Data Mine Tasks->Trading Mine Tasks->' + 'Exchange Data Tasks->Exchange Trading Tasks->Crypto Exchange->' + + 'Market Data Tasks->Market Trading Tasks->Market->' + + 'Data Mine Tasks->Trading Mine Tasks->' + 'Task Manager->Task->' + 'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' + 'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' + @@ -114,12 +116,12 @@ function newTaskFunctions() { } function stopTask(node, functionLibraryProtocolNode, callBackFunction) { - if (validations(node) !== true) { + let networkNode = validations(node) + if (networkNode === undefined) { + /* This means that the validations failed. */ callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) return } - - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) let event = { @@ -154,7 +156,7 @@ function newTaskFunctions() { return } - let taskManager = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let taskManager = node.payload.parentNode if (taskManager.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Task needs to be inside Mine Tasks.') @@ -172,7 +174,7 @@ function newTaskFunctions() { } if (taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { - node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment.') + node.payload.uiObject.setErrorMessage('Task needs to be inside a Data Mining, Testing or Production Environment.') return } @@ -181,7 +183,7 @@ function newTaskFunctions() { return } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let networkNode = taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode if (loadPropertyFromNodeConfig(networkNode.payload, 'host') === undefined) { node.payload.uiObject.setErrorMessage('Network Node needs to have a valid Host property at its config.') return @@ -197,7 +199,7 @@ function newTaskFunctions() { return } - return true + return networkNode } function runAllTasks(taskManager, functionLibraryProtocolNode) { From 1d839a280c9b3563111137f2ee58f1a0992afdd2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 15:24:18 +0200 Subject: [PATCH 107/192] Bugs Fixed --- .../FunctionLibraries/TaskFunctions.js | 118 ++++++++++++++++-- DesignSpace/Workspace/Workspace.js | 40 ++++++ 2 files changed, 145 insertions(+), 13 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 192efe0fa..122e49b0e 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -6,10 +6,22 @@ function newTaskFunctions() { stopAllTasks: stopAllTasks, runAllTaskManagers: runAllTaskManagers, stopAllTaskManagers: stopAllTaskManagers, + runAllExchangeDataTasks: runAllExchangeDataTasks, stopAllExchangeDataTasks: stopAllExchangeDataTasks, runAllExchangeTradingTasks: runAllExchangeTradingTasks, stopAllExchangeTradingTasks: stopAllExchangeTradingTasks, + + runAllMarketDataTasks: runAllMarketDataTasks, + stopAllMarketDataTasks: stopAllMarketDataTasks, + runAllMarketTradingTasks: runAllMarketTradingTasks, + stopAllMarketTradingTasks: stopAllMarketTradingTasks, + + runAllDataMineTasks: runAllDataMineTasks, + stopAllDataMineTasks: stopAllDataMineTasks, + runAllTradingMineTasks: runAllTradingMineTasks, + stopAllTradingMineTasks: stopAllTradingMineTasks, + addMissingExchangeDataTasks: addMissingExchangeDataTasks, addMissingMarketDataTasks: addMissingMarketDataTasks, addMissingDataMineTasks: addMissingDataMineTasks, @@ -241,28 +253,88 @@ function newTaskFunctions() { } function runAllExchangeDataTasks(parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.exchangeTasks.length; i++) { - let node = parent.exchangeTasks[i] + for (let i = 0; i < parent.exchangeDataTasks.length; i++) { + let node = parent.exchangeDataTasks[i] let menu = node.payload.uiObject.menu - menu.internalClick('Run All Task Managers') - menu.internalClick('Run All Task Managers') + menu.internalClick('Run All Market Data Tasks') + menu.internalClick('Run All Market Data Tasks') } } function stopAllExchangeDataTasks(parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.exchangeTasks.length; i++) { - let node = parent.exchangeTasks[i] + for (let i = 0; i < parent.exchangeDataTasks.length; i++) { + let node = parent.exchangeDataTasks[i] let menu = node.payload.uiObject.menu - menu.internalClick('Stop All Task Managers') - menu.internalClick('Stop All Task Managers') + menu.internalClick('Stop All Market Data Tasks') + menu.internalClick('Stop All Market Data Tasks') } } function runAllExchangeTradingTasks(parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.exchangeTasks.length; i++) { - let node = parent.exchangeTasks[i] + for (let i = 0; i < parent.exchangeTradingTasks.length; i++) { + let node = parent.exchangeTradingTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Run All Market Trading Tasks') + menu.internalClick('Run All Market Trading Tasks') + } + } + + function stopAllExchangeTradingTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.exchangeTradingTasks.length; i++) { + let node = parent.exchangeTradingTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Market Trading Tasks') + menu.internalClick('Stop All Market Trading Tasks') + } + } + + function runAllMarketDataTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.marketDataTasks.length; i++) { + let node = parent.marketDataTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Run All Data Mine Tasks') + menu.internalClick('Run All Data Mine Tasks') + } + } + + function stopAllMarketDataTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.marketDataTasks.length; i++) { + let node = parent.marketDataTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Data Mine Tasks') + menu.internalClick('Stop All Data Mine Tasks') + } + } + + function runAllMarketTradingTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.marketTradingTasks.length; i++) { + let node = parent.marketTradingTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Run All Trading Mine Tasks') + menu.internalClick('Run All Trading Mine Tasks') + } + } + + function stopAllMarketTradingTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.marketTradingTasks.length; i++) { + let node = parent.marketTradingTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Trading Mine Tasks') + menu.internalClick('Stop All Trading Mine Tasks') + } + } + + function runAllDataMineTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.dataMineTasks.length; i++) { + let node = parent.dataMineTasks[i] let menu = node.payload.uiObject.menu menu.internalClick('Run All Task Managers') @@ -270,9 +342,29 @@ function newTaskFunctions() { } } - function stopAllExchangeTradingTasks(parent, functionLibraryProtocolNode) { - for (let i = 0; i < parent.exchangeTasks.length; i++) { - let node = parent.exchangeTasks[i] + function stopAllDataMineTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.dataMineTasks.length; i++) { + let node = parent.dataMineTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Stop All Task Managers') + menu.internalClick('Stop All Task Managers') + } + } + + function runAllTradingMineTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.tradingMineTasks.length; i++) { + let node = parent.tradingMineTasks[i] + let menu = node.payload.uiObject.menu + + menu.internalClick('Run All Task Managers') + menu.internalClick('Run All Task Managers') + } + } + + function stopAllTradingMineTasks(parent, functionLibraryProtocolNode) { + for (let i = 0; i < parent.tradingMineTasks.length; i++) { + let node = parent.tradingMineTasks[i] let menu = node.payload.uiObject.menu menu.internalClick('Stop All Task Managers') diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 79366ca7f..9291f2c88 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -611,6 +611,46 @@ function newWorkspace() { functionLibraryTaskFunctions.stopAllExchangeTradingTasks(payload.node, functionLibraryProtocolNode) } break + case 'Run All Market Data Tasks': + { + functionLibraryTaskFunctions.runAllMarketDataTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Market Data Tasks': + { + functionLibraryTaskFunctions.stopAllMarketDataTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Run All Market Trading Tasks': + { + functionLibraryTaskFunctions.runAllMarketTradingTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Market Trading Tasks': + { + functionLibraryTaskFunctions.stopAllMarketTradingTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Run All Data Mine Tasks': + { + functionLibraryTaskFunctions.runAllDataMineTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Data Mine Tasks': + { + functionLibraryTaskFunctions.stopAllDataMineTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Run All Trading Mine Tasks': + { + functionLibraryTaskFunctions.runAllTradingMineTasks(payload.node, functionLibraryProtocolNode) + } + break + case 'Stop All Trading Mine Tasks': + { + functionLibraryTaskFunctions.stopAllTradingMineTasks(payload.node, functionLibraryProtocolNode) + } + break case 'Add Missing Exchange Data Tasks': { functionLibraryTaskFunctions.addMissingExchangeDataTasks(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) From 7d3210eb5728a91bc4a677fa4b2067d2e396b299 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 15:44:21 +0200 Subject: [PATCH 108/192] Update SessionFunctions.js --- .../FunctionLibraries/SessionFunctions.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index c1f96d72f..a80f00fcb 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -7,12 +7,13 @@ function newSessionFunctions() { return thisObject function runSession(node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, resume, callBackFunction) { - if (validations(node) !== true) { + let networkNode = validations(node) + if (networkNode === undefined) { + /* This means that the validations failed. */ callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) return } - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) node.payload.uiObject.run(eventsServerClient, callBackFunction) @@ -113,12 +114,13 @@ function newSessionFunctions() { } function stopSession(node, functionLibraryProtocolNode, callBackFunction) { - if (validations(node) !== true) { + let networkNode = validations(node) + if (networkNode === undefined) { + /* This means that the validations failed. */ callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) return } - - let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) let key = node.name + '-' + node.type + '-' + node.id @@ -175,6 +177,8 @@ function newSessionFunctions() { return } + let networkNode = taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode + if (node.payload.parentNode.payload.uiObject.isRunning !== true) { node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running.') return @@ -199,6 +203,6 @@ function newSessionFunctions() { node.payload.uiObject.setErrorMessage('Trading Engine Reference needs to reference a Trading Engine.') return } - return true + return networkNode } } From 91582d1715a97f8437186be9d685962fdb0877fd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 18:47:22 +0200 Subject: [PATCH 109/192] Update Layer.js --- Panels/Layer.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Panels/Layer.js b/Panels/Layer.js index dc6d2c20c..57a6107ae 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -173,7 +173,7 @@ function newLayer() { 'Product Definition->' + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Sensor Bot->Indicator Bot->Trading Bot->' + - 'Data Mine->' + + 'Data Mine->Trading Mine->' + 'Dataset Definition->' + 'Record Definition->Record Property->Formula->' + 'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' + @@ -222,10 +222,10 @@ function newLayer() { thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Sensor Bot') if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot') } if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot') } if (thisObject.bot === undefined) { thisObject.payload.uiObject.setErrorMessage('Bot not Found') @@ -234,8 +234,11 @@ function newLayer() { thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Data Mine') if (thisObject.dataMine === undefined) { - thisObject.payload.uiObject.setErrorMessage('Data Mine not Found') - return + thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Trading Mine') + if (thisObject.dataMine === undefined) { + thisObject.payload.uiObject.setErrorMessage('Data Mine or Trading Mine not Found') + return + } } thisObject.exchange = findNodeInNodeMesh(thisObject.definition, 'Crypto Exchange') From c7bc3ea93b84861c68ae2420a28de60d1fdae450 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 19:30:53 +0200 Subject: [PATCH 110/192] Session Reference --- ChartingSpace/PlottersManager.js | 2 +- .../FunctionLibraries/DataStorageFunctions.js | 30 +++++++++- DesignSpace/Workspace/Workspace.js | 5 ++ Panels/Layer.js | 26 ++++---- Utilities/Branches.js | 4 ++ Utilities/Hiriarchy.js | 7 ++- Utilities/Meshes.js | 60 ++++++++++++------- 7 files changed, 95 insertions(+), 39 deletions(-) diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index 09abb9b7a..476169fd4 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -144,7 +144,7 @@ function newPlottersManager() { A layer can be referencing a Data Product in two different branches of the Network hiriatchy. In one of those braches we can get the Session node, at the other we Cannot. */ - let sessionReference = findNodeInNodeMesh(layer.definition, 'Session Reference') + let sessionReference = findNodeInNodeMesh(layer.definition, 'Session Reference', false, true, true, true) if (sessionReference !== undefined) { session = sessionReference.referenceParent diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index 37b9b0acb..d2257e0c4 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -1,7 +1,8 @@ function newDataStorageFunctions() { thisObject = { addAllDataProducts: addAllDataProducts, - addAllDataMineProducts: addAllDataMineProducts + addAllDataMineProducts: addAllDataMineProducts, + addMissingSessionReferences: addMissingSessionReferences } return thisObject @@ -55,11 +56,36 @@ function newDataStorageFunctions() { function addAllDataMineProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] - + if (rootNode.type === 'Data Mine') { let dataMineProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Data Mine Products') dataMineProducts.payload.referenceParent = rootNode } } } + + function addMissingSessionReferences(node, rootNodes, functionLibraryUiObjectsFromNodes) { + let networkNode = findNodeInNodeMesh(node, 'Network Node', true, false, true, false) + if (networkNode === undefined) {return} + + let backtestingSessionsArray = nodeBranchToArray(networkNode, 'Backtesting Session') + let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Fordward Testing Session') + let paperTradingSessionsArray = nodeBranchToArray(networkNode, 'Paper Trading Session') + let liveTradingSessionsArray = nodeBranchToArray(networkNode, 'Live Trading Session') + + addMissingSession(backtestingSessionsArray) + addMissingSession(fordwardTestingSessionsArray) + addMissingSession(paperTradingSessionsArray) + addMissingSession(liveTradingSessionsArray) + + function addMissingSession(sessionsArray) { + for (let i = 0; i < sessionsArray.length; i++) { + let session = sessionsArray[i] + if (isMissingChildren(node, session, true) === true) { + let sessionReference = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Session Reference') + sessionReference.payload.referenceParent = session + } + } + } + } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 9291f2c88..2f71bbcd1 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -716,6 +716,11 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addAllDataMineProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add Missing Session References': + { + functionLibraryDataStorageFunctions.addMissingSessionReferences(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add All Data Dependencies': { functionLibraryDataMineFunctions.addAllDataDependencies(payload.node, functionLibraryUiObjectsFromNodes) diff --git a/Panels/Layer.js b/Panels/Layer.js index 57a6107ae..c90adf702 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -205,49 +205,49 @@ function newLayer() { } /* Here we validate that we have all the needed information */ - if (findNodeInNodeMesh(thisObject.definition, 'Data Product') === undefined) { + if (findNodeInNodeMesh(thisObject.definition, 'Data Product', false, true, true, true) === undefined) { thisObject.payload.uiObject.setErrorMessage('Data Product not Found') return } - if (findNodeInNodeMesh(thisObject.definition, 'Market') === undefined) { + if (findNodeInNodeMesh(thisObject.definition, 'Market', false, true, true, true) === undefined) { thisObject.payload.uiObject.setErrorMessage('Market not Found') return } - thisObject.productDefinition = findNodeInNodeMesh(thisObject.definition, 'Product Definition') + thisObject.productDefinition = findNodeInNodeMesh(thisObject.definition, 'Product Definition', false, true, true, true) if (thisObject.productDefinition === undefined) { thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') return } - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Sensor Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Sensor Bot', false, true, true, true) if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot', false, true, true, true) } if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot') + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot', false, true, true, true) } if (thisObject.bot === undefined) { thisObject.payload.uiObject.setErrorMessage('Bot not Found') return } - thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Data Mine') + thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Data Mine', false, true, true, true) if (thisObject.dataMine === undefined) { - thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Trading Mine') + thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Trading Mine', false, true, true, true) if (thisObject.dataMine === undefined) { thisObject.payload.uiObject.setErrorMessage('Data Mine or Trading Mine not Found') return } } - thisObject.exchange = findNodeInNodeMesh(thisObject.definition, 'Crypto Exchange') + thisObject.exchange = findNodeInNodeMesh(thisObject.definition, 'Crypto Exchange', false, true, true, true) if (thisObject.exchange === undefined) { thisObject.payload.uiObject.setErrorMessage('Crypto Exchange not Found') return } - thisObject.baseAsset = findNodeInNodeMesh(thisObject.definition, 'Market Base Asset') + thisObject.baseAsset = findNodeInNodeMesh(thisObject.definition, 'Market Base Asset', false, true, true, true) if (thisObject.baseAsset !== undefined) { thisObject.baseAsset = thisObject.baseAsset.referenceParent } @@ -256,7 +256,7 @@ function newLayer() { return } - thisObject.quotedAsset = findNodeInNodeMesh(thisObject.definition, 'Market Quoted Asset') + thisObject.quotedAsset = findNodeInNodeMesh(thisObject.definition, 'Market Quoted Asset', false, true, true, true) if (thisObject.quotedAsset !== undefined) { thisObject.quotedAsset = thisObject.quotedAsset.referenceParent } @@ -265,13 +265,13 @@ function newLayer() { return } - thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module') + thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module', false, true, true, true) if (thisObject.plotterModule === undefined) { thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') return } - thisObject.networkNode = findNodeInNodeMesh(thisObject.definition, 'Network Node') + thisObject.networkNode = findNodeInNodeMesh(thisObject.definition, 'Network Node', false, true, true, true) if (thisObject.networkNode === undefined) { thisObject.payload.uiObject.setErrorMessage('Network Node not Found') return diff --git a/Utilities/Branches.js b/Utilities/Branches.js index 71123093d..e51b34012 100644 --- a/Utilities/Branches.js +++ b/Utilities/Branches.js @@ -3,11 +3,15 @@ function nodeBranchToArray(node, nodeType) { This function scans a node branch for a certain node type and return an array of with all the nodes of that type found. */ + if (node === undefined) { return } + if (nodeType === undefined) { return } let resultArray = [] scanNodeBranch(node, nodeType) return resultArray function scanNodeBranch(startingNode) { + if (startingNode === undefined) {return} + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) if (nodeDefinition === undefined) { return } diff --git a/Utilities/Hiriarchy.js b/Utilities/Hiriarchy.js index 1c4665a77..e37b075fb 100644 --- a/Utilities/Hiriarchy.js +++ b/Utilities/Hiriarchy.js @@ -1,8 +1,9 @@ -/* -This function scans a node hiriatchy recursively and creates a Map by Id of all the nodes of it. -*/ + function getHiriarchyMap(rootNode) { + /* + This function scans a node hiriatchy recursively and creates a Map by Id of all the nodes of it. + */ let hiriatchyMap = new Map() evalNode(rootNode) return hiriatchyMap diff --git a/Utilities/Meshes.js b/Utilities/Meshes.js index 42d53bea1..d7b48d3b1 100644 --- a/Utilities/Meshes.js +++ b/Utilities/Meshes.js @@ -1,10 +1,10 @@ -function findNodeInNodeMesh(node, nodeType) { +function findNodeInNodeMesh(node, nodeType, connectedViaPayload, findInChildren, findInParents, findInReferenceParents) { /* This function scans a node mesh for a certain node type and returns the first instance found. */ let nodeFound - scanNodeMesh(node, nodeType) + scanNodeMesh(node) return nodeFound function scanNodeMesh(startingNode) { @@ -20,34 +20,54 @@ function findNodeInNodeMesh(node, nodeType) { } /* We scan through this node children */ - if (nodeDefinition.properties !== undefined) { - for (let i = 0; i < nodeDefinition.properties.length; i++) { - let property = nodeDefinition.properties[i] + if (findInChildren === true) { + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] - switch (property.type) { - case 'node': { - scanNodeMesh(startingNode[property.name]) - } - break - case 'array': { - let startingNodePropertyArray = startingNode[property.name] - if (startingNodePropertyArray !== undefined) { - for (let m = 0; m < startingNodePropertyArray.length; m++) { - scanNodeMesh(startingNodePropertyArray[m]) + switch (property.type) { + case 'node': { + scanNodeMesh(startingNode[property.name]) + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + scanNodeMesh(startingNodePropertyArray[m]) + } } + break } - break } } } } + /* We scan parents nodes. */ - if (startingNode.parentNode !== undefined) { - scanNodeMesh(startingNode.parentNode) + if (findInParents === true) { + if (connectedViaPayload === true) { + if (startingNode.payload.parentNode !== undefined) { + scanNodeMesh(startingNode.payload.parentNode) + } + } else { + if (startingNode.parentNode !== undefined) { + scanNodeMesh(startingNode.parentNode) + } + } } + /* We scan reference parents too. */ - if (startingNode.referenceParent !== undefined) { - scanNodeMesh(startingNode.referenceParent) + if (findInReferenceParents === true) { + if (connectedViaPayload === true) { + if (startingNode.payload.referenceParent !== undefined) { + scanNodeMesh(startingNode.payload.referenceParent) + } + } else { + if (startingNode.referenceParent !== undefined) { + scanNodeMesh(startingNode.referenceParent) + } + } } } } \ No newline at end of file From dde838e1450d00d58be4a721a502b777ee5fdada Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 20:04:23 +0200 Subject: [PATCH 111/192] Session Reference --- .../FunctionLibraries/DataStorageFunctions.js | 28 ++++++++++++++++--- DesignSpace/Workspace/Workspace.js | 5 ++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index d2257e0c4..27abaf1de 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -2,6 +2,7 @@ function newDataStorageFunctions() { thisObject = { addAllDataProducts: addAllDataProducts, addAllDataMineProducts: addAllDataMineProducts, + addAllTradingMineProducts: addAllTradingMineProducts, addMissingSessionReferences: addMissingSessionReferences } @@ -27,12 +28,14 @@ function newDataStorageFunctions() { we will create a Data Product. In case we find Product Definition Folders, we will recreate that structure too, using in this case Data Product Folders. */ - let dataMine = node.payload.referenceParent - scanBotArray(dataMine.sensorBots) - scanBotArray(dataMine.indicatorBots) - scanBotArray(dataMine.tradingBots) + let mine = node.payload.referenceParent + scanBotArray(mine.sensorBots) + scanBotArray(mine.indicatorBots) + scanBotArray(mine.tradingBots) function scanBotArray(botArray) { + if (botArray === undefined) {return} + for (let i = 0; i < botArray.length; i++) { let bot = botArray[i] let botProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Bot Products') @@ -64,6 +67,17 @@ function newDataStorageFunctions() { } } + function addAllTradingMineProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + + if (rootNode.type === 'Trading Mine') { + let tradingMineProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Trading Mine Products') + tradingMineProducts.payload.referenceParent = rootNode + } + } + } + function addMissingSessionReferences(node, rootNodes, functionLibraryUiObjectsFromNodes) { let networkNode = findNodeInNodeMesh(node, 'Network Node', true, false, true, false) if (networkNode === undefined) {return} @@ -84,6 +98,12 @@ function newDataStorageFunctions() { if (isMissingChildren(node, session, true) === true) { let sessionReference = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Session Reference') sessionReference.payload.referenceParent = session + /* + Now I will connect the Session Reference child that is auto created with the market + where the Session was found. + */ + let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', true, false, true, false) + sessionReference.singleMarketTradingData.payload.referenceParent = marketTradingTasks.payload.referenceParent } } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 2f71bbcd1..ec4a97271 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -716,6 +716,11 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addAllDataMineProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add All Trading Mine Products': + { + functionLibraryDataStorageFunctions.addAllTradingMineProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add Missing Session References': { functionLibraryDataStorageFunctions.addMissingSessionReferences(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) From bb6f66b2ecbef76d58508cafe16f60067e978318 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 20:56:38 +0200 Subject: [PATCH 112/192] Update TaskFunctions.js --- .../FunctionLibraries/TaskFunctions.js | 156 ++++++++++-------- 1 file changed, 85 insertions(+), 71 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 122e49b0e..0d440625d 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -450,90 +450,104 @@ function newTaskFunctions() { if (node.payload === undefined) { return } if (node.payload.referenceParent === undefined) { return } - let dataMine = node.payload.referenceParent - let taskManager = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Task Manager') + taskManager.name = node.name - addTasksForBotArray(dataMine.sensorBots) - addTasksForBotArray(dataMine.indicatorBots) - addTasksForBotArray(dataMine.tradingBots) + for (let i=0; i< rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Trading System') { + addTaskForTradinSystem(rootNode) + } + } - function addTasksForBotArray(botsArray) { - if (botsArray === undefined) { return } - - for (let i = 0; i < botsArray.length; i++) { - let bot = botsArray[i] - - let task = functionLibraryUiObjectsFromNodes.addUIObject(taskManager, 'Task') - task.name = bot.name - - let botInstance - switch (bot.type) { - case 'Sensor Bot': { - botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Sensor Bot Instance') - botInstance.name = bot.name - break - } - case 'Indicator Bot': { - botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Indicator Bot Instance') - botInstance.name = bot.name - break - } - case 'Trading Bot': { - botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Trading Bot Instance') - botInstance.name = bot.name - break - } - } - - for (let j = 0; j < bot.processes.length; j++) { - let process = bot.processes[j] - let processInstance + function addTaskForTradinSystem(tradingSystem) { + let mine = node.payload.referenceParent + + addTasksForBotArray(mine.sensorBots) + addTasksForBotArray(mine.indicatorBots) + addTasksForBotArray(mine.tradingBots) + + function addTasksForBotArray(botsArray) { + if (botsArray === undefined) { return } + + for (let i = 0; i < botsArray.length; i++) { + let bot = botsArray[i] + + let task = functionLibraryUiObjectsFromNodes.addUIObject(taskManager, 'Task') + task.name = tradingSystem.name + ' ' + bot.name + + let botInstance switch (bot.type) { case 'Sensor Bot': { - processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Sensor Process Instance') - processInstance.payload.referenceParent = process + botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Sensor Bot Instance') + botInstance.name = bot.name break } case 'Indicator Bot': { - processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Indicator Process Instance') - processInstance.payload.referenceParent = process + botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Indicator Bot Instance') + botInstance.name = bot.name break } case 'Trading Bot': { - processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Trading Process Instance') - processInstance.payload.referenceParent = process - - if (node.payload.parentNode === undefined) { return } - if (node.payload.parentNode.payload === undefined) { return } - if (node.payload.parentNode.payload.parentNode === undefined) { return } - if (node.payload.parentNode.payload.parentNode.payload === undefined) { return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } - - let environment = node.payload.parentNode.payload.parentNode.payload.parentNode - let session - - switch (environment.type) { - case 'Testing Environment': { - addSession('Backtesting Session') - break - } - case 'Production Environment': { - addSession('Live Trading Session') - break - } - } + botInstance = functionLibraryUiObjectsFromNodes.addUIObject(task, 'Trading Bot Instance') + botInstance.name = bot.name break + } + } + + for (let j = 0; j < bot.processes.length; j++) { + let process = bot.processes[j] + let processInstance + switch (bot.type) { + case 'Sensor Bot': { + processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Sensor Process Instance') + processInstance.payload.referenceParent = process + break + } + case 'Indicator Bot': { + processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Indicator Process Instance') + processInstance.payload.referenceParent = process + break + } + case 'Trading Bot': { + processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Trading Process Instance') + processInstance.payload.referenceParent = process + + if (node.payload.parentNode === undefined) { return } + if (node.payload.parentNode.payload === undefined) { return } + if (node.payload.parentNode.payload.parentNode === undefined) { return } + if (node.payload.parentNode.payload.parentNode.payload === undefined) { return } + if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } + + let environment = node.payload.parentNode.payload.parentNode.payload.parentNode + let session + + switch (environment.type) { + case 'Testing Environment': { + addSession('Backtesting Session') + break + } + case 'Production Environment': { + addSession('Live Trading Session') + break + } + } + break + + function addSession(sessionType) { + session = functionLibraryUiObjectsFromNodes.addUIObject(processInstance, sessionType) + session.name = task.name + ' ' + session.type + let config = JSON.parse(session.config) + config.folderName = session.name.split(" ").join("-") + session.config = JSON.stringify(config) - function addSession(sessionType) { - session = functionLibraryUiObjectsFromNodes.addUIObject(processInstance, sessionType) - session.name = task.name + ' ' + session.type - - for (let m = 0; m < rootNodes.length; m++) { - let rootNode = rootNodes[m] - if (rootNode.type === 'Trading Engine' && rootNode.isIncluded === true) { - let tradingEngine = rootNode - session.tradingEngineReference.payload.referenceParent = tradingEngine + for (let m = 0; m < rootNodes.length; m++) { + let rootNode = rootNodes[m] + if (rootNode.type === 'Trading Engine' && rootNode.isIncluded === true) { + let tradingEngine = rootNode + session.tradingEngineReference.payload.referenceParent = tradingEngine + session.tradingSystemReference.payload.referenceParent = tradingSystem + } } } } From 7e26c32c46f8a58e4935dcde5afeadeb27f01a9a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 13 Sep 2020 21:43:51 +0200 Subject: [PATCH 113/192] Update TaskFunctions.js --- .../FunctionLibraries/TaskFunctions.js | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 0d440625d..85d020df6 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -18,7 +18,7 @@ function newTaskFunctions() { stopAllMarketTradingTasks: stopAllMarketTradingTasks, runAllDataMineTasks: runAllDataMineTasks, - stopAllDataMineTasks: stopAllDataMineTasks, + stopAllDataMineTasks: stopAllDataMineTasks, runAllTradingMineTasks: runAllTradingMineTasks, stopAllTradingMineTasks: stopAllTradingMineTasks, @@ -59,7 +59,7 @@ function newTaskFunctions() { 'Task Manager->' + 'Data Mine Tasks->Trading Mine Tasks->' + 'Market Data Tasks->Market Trading Tasks->' + - 'Exchange Data Tasks->Exchange Trading Tasks->' + + 'Exchange Data Tasks->Exchange Trading Tasks->' + 'Market->Exchange Markets->Crypto Exchange->' + 'Market Base Asset->Market Quoted Asset->Asset->' + 'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' + @@ -98,8 +98,8 @@ function newTaskFunctions() { 'Data Product->Product Definition->' + 'Data Mining->Testing Environment->Production Environment->' + 'Exchange Data Tasks->Exchange Trading Tasks->Crypto Exchange->' + - 'Market Data Tasks->Market Trading Tasks->Market->' + - 'Data Mine Tasks->Trading Mine Tasks->' + + 'Market Data Tasks->Market Trading Tasks->Market->' + + 'Data Mine Tasks->Trading Mine Tasks->' + 'Task Manager->Task->' + 'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' + 'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' + @@ -168,7 +168,7 @@ function newTaskFunctions() { return } - let taskManager = node.payload.parentNode + let taskManager = node.payload.parentNode if (taskManager.payload.parentNode === undefined) { node.payload.uiObject.setErrorMessage('Task needs to be inside Mine Tasks.') @@ -453,29 +453,51 @@ function newTaskFunctions() { let taskManager = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Task Manager') taskManager.name = node.name - for (let i=0; i< rootNodes.length; i++) { - let rootNode = rootNodes[i] - if (rootNode.type === 'Trading System') { - addTaskForTradinSystem(rootNode) + switch (node.type) { + case 'Data Mine Tasks': { + addDataTasks() + break + } + case 'Trading Mine Tasks': { + addTradingTasks() + break + } + } + + function addDataTasks() { + addTaskForTradinSystem() + } + + function addTradingTasks() { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Trading System') { + addTaskForTradinSystem(rootNode) + } } } function addTaskForTradinSystem(tradingSystem) { let mine = node.payload.referenceParent - + addTasksForBotArray(mine.sensorBots) addTasksForBotArray(mine.indicatorBots) addTasksForBotArray(mine.tradingBots) - + function addTasksForBotArray(botsArray) { if (botsArray === undefined) { return } - + for (let i = 0; i < botsArray.length; i++) { let bot = botsArray[i] - + let task = functionLibraryUiObjectsFromNodes.addUIObject(taskManager, 'Task') - task.name = tradingSystem.name + ' ' + bot.name - + + if (tradingSystem !== undefined) { + task.name = tradingSystem.name + ' ' + bot.name + } else { + task.name = bot.name + } + let botInstance switch (bot.type) { case 'Sensor Bot': { @@ -494,7 +516,7 @@ function newTaskFunctions() { break } } - + for (let j = 0; j < bot.processes.length; j++) { let process = bot.processes[j] let processInstance @@ -512,16 +534,16 @@ function newTaskFunctions() { case 'Trading Bot': { processInstance = functionLibraryUiObjectsFromNodes.addUIObject(botInstance, 'Trading Process Instance') processInstance.payload.referenceParent = process - + if (node.payload.parentNode === undefined) { return } if (node.payload.parentNode.payload === undefined) { return } if (node.payload.parentNode.payload.parentNode === undefined) { return } if (node.payload.parentNode.payload.parentNode.payload === undefined) { return } if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } - + let environment = node.payload.parentNode.payload.parentNode.payload.parentNode let session - + switch (environment.type) { case 'Testing Environment': { addSession('Backtesting Session') @@ -533,7 +555,7 @@ function newTaskFunctions() { } } break - + function addSession(sessionType) { session = functionLibraryUiObjectsFromNodes.addUIObject(processInstance, sessionType) session.name = task.name + ' ' + session.type From 30e71bad19b9fa5326efd899ebf09b394f0ec327 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 11:21:11 +0200 Subject: [PATCH 114/192] build fixed --- DesignSpace/Workspace/Workspace.js | 1 - Globals.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index ec4a97271..155052ec0 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -203,7 +203,6 @@ function newWorkspace() { return } - window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave) window.localStorage.setItem('Session Timestamp', sessionTimestamp) /* Validation Workspace has a name */ diff --git a/Globals.js b/Globals.js index dde37e5cb..1d33cfb9b 100644 --- a/Globals.js +++ b/Globals.js @@ -1,8 +1,6 @@ /* User Interface Colors */ -const CANVAS_APP_NAME = 'Canvas App' - const UI_COLOR = { DARK: "48, 48, 54", LIGHT: "234, 226, 222", From aa915c9bafb4b71f27784deb09373a27a6eaa092 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 12:43:59 +0200 Subject: [PATCH 115/192] Single Market Data --- .../FunctionLibraries/DataStorageFunctions.js | 23 +++++++++++++++---- DesignSpace/Workspace/Workspace.js | 5 ++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index 27abaf1de..d87daecd1 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -2,8 +2,9 @@ function newDataStorageFunctions() { thisObject = { addAllDataProducts: addAllDataProducts, addAllDataMineProducts: addAllDataMineProducts, - addAllTradingMineProducts: addAllTradingMineProducts, - addMissingSessionReferences: addMissingSessionReferences + addAllTradingMineProducts: addAllTradingMineProducts, + addMissingSessionReferences: addMissingSessionReferences, + addMissingAddMissingSingleMarketDatas: addMissingAddMissingSingleMarketDatas } return thisObject @@ -34,7 +35,7 @@ function newDataStorageFunctions() { scanBotArray(mine.tradingBots) function scanBotArray(botArray) { - if (botArray === undefined) {return} + if (botArray === undefined) { return } for (let i = 0; i < botArray.length; i++) { let bot = botArray[i] @@ -80,7 +81,7 @@ function newDataStorageFunctions() { function addMissingSessionReferences(node, rootNodes, functionLibraryUiObjectsFromNodes) { let networkNode = findNodeInNodeMesh(node, 'Network Node', true, false, true, false) - if (networkNode === undefined) {return} + if (networkNode === undefined) { return } let backtestingSessionsArray = nodeBranchToArray(networkNode, 'Backtesting Session') let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Fordward Testing Session') @@ -108,4 +109,18 @@ function newDataStorageFunctions() { } } } + + function addMissingAddMissingSingleMarketDatas(node, rootNodes, functionLibraryUiObjectsFromNodes) { + if (node.payload.referenceParent === undefined) { return } + if (node.payload.referenceParent.exchangeMarkets === undefined) { return } + let marketsArray = node.payload.referenceParent.exchangeMarkets.markets + + for (let i = 0; i < marketsArray.length; i++) { + let market = marketsArray[i] + if (isMissingChildren(node, market, true) === true) { + let singleMarketData = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Single Market Data') + singleMarketData.payload.referenceParent = market + } + } + } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 155052ec0..2a30df246 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -725,6 +725,11 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addMissingSessionReferences(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add Missing Single Market Datas': + { + functionLibraryDataStorageFunctions.addMissingAddMissingSingleMarketDatas(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add All Data Dependencies': { functionLibraryDataMineFunctions.addAllDataDependencies(payload.node, functionLibraryUiObjectsFromNodes) From 11da081248040f2687a5a742b484d7e0a20e2e17 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 15:16:55 +0200 Subject: [PATCH 116/192] Missing Time Machines --- ChartingSpace/PlottersManager.js | 2 +- .../ChartingSpaceFunctions.js | 118 +++++++++++++++++- .../FunctionLibraries/DataStorageFunctions.js | 7 +- .../FunctionLibraries/TaskFunctions.js | 4 +- DesignSpace/Workspace/Workspace.js | 9 +- FloatingSpace/UiObject.js | 1 + Panels/Layer.js | 26 ++-- Utilities/Branches.js | 2 + Utilities/Meshes.js | 20 ++- 9 files changed, 162 insertions(+), 27 deletions(-) diff --git a/ChartingSpace/PlottersManager.js b/ChartingSpace/PlottersManager.js index 476169fd4..aaf872484 100644 --- a/ChartingSpace/PlottersManager.js +++ b/ChartingSpace/PlottersManager.js @@ -144,7 +144,7 @@ function newPlottersManager() { A layer can be referencing a Data Product in two different branches of the Network hiriatchy. In one of those braches we can get the Session node, at the other we Cannot. */ - let sessionReference = findNodeInNodeMesh(layer.definition, 'Session Reference', false, true, true, true) + let sessionReference = findNodeInNodeMesh(layer.definition, 'Session Reference', undefined, false, true, true, true) if (sessionReference !== undefined) { session = sessionReference.referenceParent diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index 780a1d497..ce9e23bb4 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -1,11 +1,12 @@ function newChartingSpaceFunctions() { thisObject = { - addAllDataMineLayers: addAllDataMineLayers + addAllMineLayers: addAllMineLayers, + addMissingTimeMachines: addMissingTimeMachines } return thisObject - function addAllDataMineLayers(node, functionLibraryUiObjectsFromNodes) { + function addAllMineLayers(node, functionLibraryUiObjectsFromNodes) { /* Validations to see if we can do this or not. */ if (node.payload === undefined) { return } @@ -47,4 +48,117 @@ function newChartingSpaceFunctions() { } } } + + function addMissingTimeMachines(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Network') { + let networkNode = rootNode + scanNetworkNode(networkNode) + } + } + + function scanNetworkNode(networkNode) { + if (networkNode === undefined) { return } + + let backtestingSessionsArray = nodeBranchToArray(networkNode, 'Backtesting Session') + let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Fordward Testing Session') + let paperTradingSessionsArray = nodeBranchToArray(networkNode, 'Paper Trading Session') + let liveTradingSessionsArray = nodeBranchToArray(networkNode, 'Live Trading Session') + + scanSessionArray(backtestingSessionsArray) + scanSessionArray(fordwardTestingSessionsArray) + scanSessionArray(paperTradingSessionsArray) + scanSessionArray(liveTradingSessionsArray) + + function scanSessionArray(sessionsArray) { + for (let i = 0; i < sessionsArray.length; i++) { + let session = sessionsArray[i] + if (isMissingChildren(node, session, true) === true) { + let mineProducts + let timeMachine = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Time Machine') + timeMachine.payload.referenceParent = session + timeMachine.name = session.name + timeMachine.payload.floatingObject.collapseToggle() + + /* + We need to create a Timeline Chart for each Data Mine Indicators. + */ + mineProducts = nodeBranchToArray(networkNode, 'Data Mine Products') + for (let j = 0; j < mineProducts.length; j++) { + let mineProduct = mineProducts[j] + + let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') + timelineChart.name = mineProduct.name + timelineChart.layersManager.payload.referenceParent = mineProduct + timelineChart.payload.floatingObject.collapseToggle() + timelineChart.layersManager.payload.floatingObject.collapseToggle() + + let menu = timelineChart.layersManager.payload.uiObject.menu + menu.internalClick('Add All Mine Layers') + menu.internalClick('Add All Mine Layers') + } + + mineProducts = nodeBranchToArray(networkNode, 'Trading Mine Products') + for (let j = 0; j < mineProducts.length; j++) { + let mineProduct = mineProducts[j] + /* + The mine products found so far, belongs to any session. To filer all the sessions + that are not the one we are interested in, we do the following: + */ + if (mineProduct.payload.parentNode === undefined) { continue } + if (mineProduct.payload.parentNode.payload.referenceParent === undefined) { continue } + if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent === undefined) { continue } + if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent.id !== session.id) { continue } + /* + At the current version of Superalgos, beta 6, there is only one Trading Mine, + with only one bot, and it has so many data products that we want to put them + in 3 different timeline charts. So we will create 3 charts, connect them, + and delete from each one 1/3 of the layers. We do all that next: + */ + + for (let k = 0; k < 3; k++) { + let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') + + timelineChart.layersManager.payload.referenceParent = mineProduct + timelineChart.payload.floatingObject.collapseToggle() + timelineChart.layersManager.payload.floatingObject.collapseToggle() + + let menu = timelineChart.layersManager.payload.uiObject.menu + menu.internalClick('Add All Mine Layers') + menu.internalClick('Add All Mine Layers') + + switch (k) { + case 0: { + timelineChart.name = 'Trading Engine' + deleteNodeByName('Trading System') + deleteNodeByName('Objects') + break + } + case 1: { + timelineChart.name = 'Trading System' + deleteNodeByName('Trading Engine') + deleteNodeByName('Objects') + break + } + case 2: { + timelineChart.name = 'Objects' + deleteNodeByName('Trading Engine') + deleteNodeByName('Trading System') + break + } + } + function deleteNodeByName(nodeName) { + let nodeToDelete = findNodeInNodeMesh(timelineChart.layersManager, undefined, nodeName, true, true, false, false) + if (nodeToDelete === undefined) { return } + functionLibraryNodeDeleter.deleteUIObject(nodeToDelete, rootNodes) + } + } + } + } + } + } + } + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index d87daecd1..e549fbc08 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -41,6 +41,7 @@ function newDataStorageFunctions() { let bot = botArray[i] let botProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Bot Products') botProducts.name = bot.name + botProducts.payload.floatingObject.collapseToggle() asymetricalFolderStructureCloning( bot, @@ -80,7 +81,7 @@ function newDataStorageFunctions() { } function addMissingSessionReferences(node, rootNodes, functionLibraryUiObjectsFromNodes) { - let networkNode = findNodeInNodeMesh(node, 'Network Node', true, false, true, false) + let networkNode = findNodeInNodeMesh(node, 'Network Node', undefined, true, false, true, false) if (networkNode === undefined) { return } let backtestingSessionsArray = nodeBranchToArray(networkNode, 'Backtesting Session') @@ -103,8 +104,10 @@ function newDataStorageFunctions() { Now I will connect the Session Reference child that is auto created with the market where the Session was found. */ - let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', true, false, true, false) + let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) sessionReference.singleMarketTradingData.payload.referenceParent = marketTradingTasks.payload.referenceParent + timelineChart.payload.floatingObject.collapseToggle() + timelineChart.singleMarketTradingData.payload.floatingObject.collapseToggle() } } } diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 85d020df6..7245c038e 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -493,7 +493,7 @@ function newTaskFunctions() { let task = functionLibraryUiObjectsFromNodes.addUIObject(taskManager, 'Task') if (tradingSystem !== undefined) { - task.name = tradingSystem.name + ' ' + bot.name + task.name = tradingSystem.name } else { task.name = bot.name } @@ -558,7 +558,7 @@ function newTaskFunctions() { function addSession(sessionType) { session = functionLibraryUiObjectsFromNodes.addUIObject(processInstance, sessionType) - session.name = task.name + ' ' + session.type + session.name = task.name let config = JSON.parse(session.config) config.folderName = session.name.split(" ").join("-") session.config = JSON.stringify(config) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 2a30df246..eded530de 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -740,9 +740,14 @@ function newWorkspace() { functionLibraryDataMineFunctions.addAllDataMineDataDependencies(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break - case 'Add All Data Mine Layers': + case 'Add All Mine Layers': { - functionLibraryChartingSpaceFunctions.addAllDataMineLayers(payload.node, functionLibraryUiObjectsFromNodes) + functionLibraryChartingSpaceFunctions.addAllMineLayers(payload.node, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Time Machines': + { + functionLibraryChartingSpaceFunctions.addMissingTimeMachines(payload.node, thisObject.workspaceNode.rootNodes,functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) } break case 'Play Tutorial': diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 5595b7891..3dab07426 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -309,6 +309,7 @@ function newUiObject() { function invisiblePhysics() { thisObject.menu.invisiblePhysics() childrenRunningPhysics() + thisObject.uiObjectTitle.physics() } function physics() { diff --git a/Panels/Layer.js b/Panels/Layer.js index c90adf702..b917d2c72 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -205,49 +205,49 @@ function newLayer() { } /* Here we validate that we have all the needed information */ - if (findNodeInNodeMesh(thisObject.definition, 'Data Product', false, true, true, true) === undefined) { + if (findNodeInNodeMesh(thisObject.definition, 'Data Product', undefined, false, true, true, true) === undefined) { thisObject.payload.uiObject.setErrorMessage('Data Product not Found') return } - if (findNodeInNodeMesh(thisObject.definition, 'Market', false, true, true, true) === undefined) { + if (findNodeInNodeMesh(thisObject.definition, 'Market', undefined, false, true, true, true) === undefined) { thisObject.payload.uiObject.setErrorMessage('Market not Found') return } - thisObject.productDefinition = findNodeInNodeMesh(thisObject.definition, 'Product Definition', false, true, true, true) + thisObject.productDefinition = findNodeInNodeMesh(thisObject.definition, 'Product Definition', undefined, false, true, true, true) if (thisObject.productDefinition === undefined) { thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') return } - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Sensor Bot', false, true, true, true) + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Sensor Bot', undefined, false, true, true, true) if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot', false, true, true, true) + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Indicator Bot', undefined, false, true, true, true) } if (thisObject.bot === undefined) { - thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot', false, true, true, true) + thisObject.bot = findNodeInNodeMesh(thisObject.definition, 'Trading Bot', undefined, false, true, true, true) } if (thisObject.bot === undefined) { thisObject.payload.uiObject.setErrorMessage('Bot not Found') return } - thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Data Mine', false, true, true, true) + thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Data Mine', undefined, false, true, true, true) if (thisObject.dataMine === undefined) { - thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Trading Mine', false, true, true, true) + thisObject.dataMine = findNodeInNodeMesh(thisObject.definition, 'Trading Mine', undefined, false, true, true, true) if (thisObject.dataMine === undefined) { thisObject.payload.uiObject.setErrorMessage('Data Mine or Trading Mine not Found') return } } - thisObject.exchange = findNodeInNodeMesh(thisObject.definition, 'Crypto Exchange', false, true, true, true) + thisObject.exchange = findNodeInNodeMesh(thisObject.definition, 'Crypto Exchange', undefined, false, true, true, true) if (thisObject.exchange === undefined) { thisObject.payload.uiObject.setErrorMessage('Crypto Exchange not Found') return } - thisObject.baseAsset = findNodeInNodeMesh(thisObject.definition, 'Market Base Asset', false, true, true, true) + thisObject.baseAsset = findNodeInNodeMesh(thisObject.definition, 'Market Base Asset', undefined, false, true, true, true) if (thisObject.baseAsset !== undefined) { thisObject.baseAsset = thisObject.baseAsset.referenceParent } @@ -256,7 +256,7 @@ function newLayer() { return } - thisObject.quotedAsset = findNodeInNodeMesh(thisObject.definition, 'Market Quoted Asset', false, true, true, true) + thisObject.quotedAsset = findNodeInNodeMesh(thisObject.definition, 'Market Quoted Asset', undefined, false, true, true, true) if (thisObject.quotedAsset !== undefined) { thisObject.quotedAsset = thisObject.quotedAsset.referenceParent } @@ -265,13 +265,13 @@ function newLayer() { return } - thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module', false, true, true, true) + thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module', undefined, false, true, true, true) if (thisObject.plotterModule === undefined) { thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') return } - thisObject.networkNode = findNodeInNodeMesh(thisObject.definition, 'Network Node', false, true, true, true) + thisObject.networkNode = findNodeInNodeMesh(thisObject.definition, 'Network Node', undefined, false, true, true, true) if (thisObject.networkNode === undefined) { thisObject.payload.uiObject.setErrorMessage('Network Node not Found') return diff --git a/Utilities/Branches.js b/Utilities/Branches.js index e51b34012..60cf93758 100644 --- a/Utilities/Branches.js +++ b/Utilities/Branches.js @@ -40,3 +40,5 @@ function nodeBranchToArray(node, nodeType) { } } } + + diff --git a/Utilities/Meshes.js b/Utilities/Meshes.js index d7b48d3b1..ae15bf758 100644 --- a/Utilities/Meshes.js +++ b/Utilities/Meshes.js @@ -1,7 +1,8 @@ -function findNodeInNodeMesh(node, nodeType, connectedViaPayload, findInChildren, findInParents, findInReferenceParents) { +function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findInChildren, findInParents, findInReferenceParents) { /* This function scans a node mesh for a certain node type and - returns the first instance found. + returns the first instance found. Please specify either nodeType + or nodeName. */ let nodeFound scanNodeMesh(node) @@ -14,9 +15,18 @@ function findNodeInNodeMesh(node, nodeType, connectedViaPayload, findInChildren, let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) if (nodeDefinition === undefined) { return } - if (startingNode.type === nodeType) { - nodeFound = startingNode - return + if (nodeType !== undefined) { + if (startingNode.type === nodeType) { + nodeFound = startingNode + return + } + } + + if (nodeName !== undefined) { + if (startingNode.name === nodeName) { + nodeFound = startingNode + return + } } /* We scan through this node children */ From 960930c6bf85ae228ef232c06f7dbc35b65fa728 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 15:52:31 +0200 Subject: [PATCH 117/192] Bug Fixed --- .../ChartingSpaceFunctions.js | 18 ++++++++++++++++-- DesignSpace/Workspace/Workspace.js | 2 +- Panels/Layer.js | 8 ++++---- Utilities/Meshes.js | 18 ++++++++++-------- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index ce9e23bb4..f2394e699 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -6,7 +6,7 @@ function newChartingSpaceFunctions() { return thisObject - function addAllMineLayers(node, functionLibraryUiObjectsFromNodes) { + function addAllMineLayers(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { /* Validations to see if we can do this or not. */ if (node.payload === undefined) { return } @@ -45,6 +45,20 @@ function newChartingSpaceFunctions() { undefined, functionLibraryUiObjectsFromNodes ) + /* + There are some layers that should not exist, for example the ones related to Data Products + that do not have a plotter module. Since our previous action created all layers no matter + what, we need now to delete all the ones that do not have a plotter module. + */ + let allLayers = nodeBranchToArray(botLayers, 'Layer') + for (let j = 0; j < allLayers.length; j++) { + let layer = allLayers[j] + + let plotterModule = findNodeInNodeMesh(layer, 'Plotter Module', undefined, true, false, false, true) + if (plotterModule === undefined) { + functionLibraryNodeDeleter.deleteUIObject(layer, rootNodes) + } + } } } } @@ -120,7 +134,7 @@ function newChartingSpaceFunctions() { for (let k = 0; k < 3; k++) { let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') - + timelineChart.layersManager.payload.referenceParent = mineProduct timelineChart.payload.floatingObject.collapseToggle() timelineChart.layersManager.payload.floatingObject.collapseToggle() diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index eded530de..6495c84e4 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -742,7 +742,7 @@ function newWorkspace() { break case 'Add All Mine Layers': { - functionLibraryChartingSpaceFunctions.addAllMineLayers(payload.node, functionLibraryUiObjectsFromNodes) + functionLibraryChartingSpaceFunctions.addAllMineLayers(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) } break case 'Add Missing Time Machines': diff --git a/Panels/Layer.js b/Panels/Layer.js index b917d2c72..f791c5658 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -161,8 +161,8 @@ function newLayer() { '->Layer->' + 'Data Product->' + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + - 'Bot Products->Data Mine Products->' + - 'Single Market Data->Exchange Data Products->' + + 'Bot Products->Data Mine Products->Trading Mine Products->' + + 'Single Market Data->Single Market Trading Data->Exchange Data Products->' + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + @@ -265,9 +265,9 @@ function newLayer() { return } - thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module', undefined, false, true, true, true) + thisObject.plotterModule = findNodeInNodeMesh(thisObject.definition, 'Plotter Module', undefined, false, false, false, true) if (thisObject.plotterModule === undefined) { - thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') + thisObject.payload.uiObject.setErrorMessage('Plotter Module not Found') return } diff --git a/Utilities/Meshes.js b/Utilities/Meshes.js index ae15bf758..f0d474ff9 100644 --- a/Utilities/Meshes.js +++ b/Utilities/Meshes.js @@ -4,13 +4,15 @@ function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findI returns the first instance found. Please specify either nodeType or nodeName. */ + const MAX_DEPTH = 100 let nodeFound - scanNodeMesh(node) + scanNodeMesh(node, 0) return nodeFound - function scanNodeMesh(startingNode) { + function scanNodeMesh(startingNode, depth) { if (startingNode === undefined) { return } if (nodeFound !== undefined) { return } + if (depth >= MAX_DEPTH) {return} let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) if (nodeDefinition === undefined) { return } @@ -37,14 +39,14 @@ function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findI switch (property.type) { case 'node': { - scanNodeMesh(startingNode[property.name]) + scanNodeMesh(startingNode[property.name], depth + 1) } break case 'array': { let startingNodePropertyArray = startingNode[property.name] if (startingNodePropertyArray !== undefined) { for (let m = 0; m < startingNodePropertyArray.length; m++) { - scanNodeMesh(startingNodePropertyArray[m]) + scanNodeMesh(startingNodePropertyArray[m], depth + 1) } } break @@ -58,11 +60,11 @@ function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findI if (findInParents === true) { if (connectedViaPayload === true) { if (startingNode.payload.parentNode !== undefined) { - scanNodeMesh(startingNode.payload.parentNode) + scanNodeMesh(startingNode.payload.parentNode, depth + 1) } } else { if (startingNode.parentNode !== undefined) { - scanNodeMesh(startingNode.parentNode) + scanNodeMesh(startingNode.parentNode, depth + 1) } } } @@ -71,11 +73,11 @@ function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findI if (findInReferenceParents === true) { if (connectedViaPayload === true) { if (startingNode.payload.referenceParent !== undefined) { - scanNodeMesh(startingNode.payload.referenceParent) + scanNodeMesh(startingNode.payload.referenceParent, depth + 1) } } else { if (startingNode.referenceParent !== undefined) { - scanNodeMesh(startingNode.referenceParent) + scanNodeMesh(startingNode.referenceParent, depth + 1) } } } From 07dd47f42ac64ee0fe9363adba09973c59d753b0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 17:53:34 +0200 Subject: [PATCH 118/192] Update CCXTFunctions.js --- .../FunctionLibraries/CCXTFunctions.js | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js index ff51d8cce..5069e98bb 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js @@ -129,7 +129,6 @@ function newCCXTFunctions() { if (node.payload.parentNode.exchangeAssets === undefined) { return } if (node.payload.parentNode.payload.parentNode === undefined) { return } if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { return } - if (node.payload.parentNode.payload.parentNode.payload.parentNode.superActions === undefined) { return } let currentAssets = new Map() let exchangeAssets = node.payload.parentNode.exchangeAssets @@ -184,35 +183,18 @@ function newCCXTFunctions() { newMarket.name = name newMarket.config = '{ \n\"codeName\": \"' + name + '\"\n}' newMarket.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - newMarket.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X + newMarket.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X newMarket.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE newMarket.baseAsset.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 newMarket.quotedAsset.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_45 newMarket.baseAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X - newMarket.quotedAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_150X + newMarket.quotedAsset.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X newMarket.baseAsset.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE newMarket.quotedAsset.payload.floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE newMarket.baseAsset.payload.referenceParent = baseAsset newMarket.quotedAsset.payload.referenceParent = quotedAsset currentMarkets.set(name, newMarket) - - let superActions = node.payload.parentNode.payload.parentNode.payload.parentNode.superActions - - for (let j = 0; j < superActions.superActions.length; j++) { - let superAction = superActions.superActions[j] - let clone = functionLibraryNodeCloning.getNodeClone(superAction) - functionLibraryUiObjectsFromNodes.createUiObjectFromNode(clone, newMarket, newMarket) - newMarket.superActions.push(clone) - switch (j) { - case 0: - clone.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X - break - case 1: - clone.payload.floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X - break - } - } } } } From d6e7991baa00ebdc8611aca53851799e1136f781 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 18:48:10 +0200 Subject: [PATCH 119/192] Missing stuff --- .../FunctionLibraries/DataStorageFunctions.js | 33 +++++++++++++++++-- .../FunctionLibraries/TaskFunctions.js | 4 +-- DesignSpace/Workspace/Workspace.js | 21 ++++++++++-- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index e549fbc08..29f5dafd9 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -4,7 +4,9 @@ function newDataStorageFunctions() { addAllDataMineProducts: addAllDataMineProducts, addAllTradingMineProducts: addAllTradingMineProducts, addMissingSessionReferences: addMissingSessionReferences, - addMissingAddMissingSingleMarketDatas: addMissingAddMissingSingleMarketDatas + addMissingSingleMarketData: addMissingSingleMarketData, + addMissingExchangeSessions: addMissingExchangeSessions, + addMissingExchangeDataProducts: addMissingExchangeDataProducts } return thisObject @@ -113,7 +115,7 @@ function newDataStorageFunctions() { } } - function addMissingAddMissingSingleMarketDatas(node, rootNodes, functionLibraryUiObjectsFromNodes) { + function addMissingSingleMarketData(node, rootNodes, functionLibraryUiObjectsFromNodes) { if (node.payload.referenceParent === undefined) { return } if (node.payload.referenceParent.exchangeMarkets === undefined) { return } let marketsArray = node.payload.referenceParent.exchangeMarkets.markets @@ -126,4 +128,31 @@ function newDataStorageFunctions() { } } } + + function addMissingExchangeSessions(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingExchange(node, rootNodes, 'Exchange Sessions', functionLibraryUiObjectsFromNodes) + } + + function addMissingExchangeDataProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingExchange(node, rootNodes, 'Exchange Data Products', functionLibraryUiObjectsFromNodes) + } + + function addMissingExchange(node, rootNodes, newNodeType, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Crypto Ecosystem') { + let cryptoEcosystem = rootNode + for (let j = 0; j < cryptoEcosystem.cryptoExchanges.length; j++) { + let cryptoExchanges = cryptoEcosystem.cryptoExchanges[j] + for (let k = 0; k < cryptoExchanges.exchanges.length; k++) { + let cryptoExchange = cryptoExchanges.exchanges[k] + if (isMissingChildren(node, cryptoExchange, true) === true) { + let exchange = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) + exchange.payload.referenceParent = cryptoExchange + } + } + } + } + } + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 7245c038e..8267b6f3a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -390,8 +390,8 @@ function newTaskFunctions() { for (let k = 0; k < cryptoExchanges.exchanges.length; k++) { let cryptoExchange = cryptoExchanges.exchanges[k] if (isMissingChildren(node, cryptoExchange, true) === true) { - let exchangeDataTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) - exchangeDataTasks.payload.referenceParent = cryptoExchange + let exchangeTasks = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) + exchangeTasks.payload.referenceParent = cryptoExchange } } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 6495c84e4..b4c9a0b64 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -725,9 +725,24 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addMissingSessionReferences(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break - case 'Add Missing Single Market Datas': + case 'Add Missing Single Market Data': { - functionLibraryDataStorageFunctions.addMissingAddMissingSingleMarketDatas(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + functionLibraryDataStorageFunctions.addMissingSingleMarketData(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Single Market Trading Data': + { + functionLibraryDataStorageFunctions.addMissingSingleMarketTradingData(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Exchange Sessions': + { + functionLibraryDataStorageFunctions.addMissingExchangeSessions(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Add Missing Exchange Data Products': + { + functionLibraryDataStorageFunctions.addMissingExchangeDataProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break case 'Add All Data Dependencies': @@ -747,7 +762,7 @@ function newWorkspace() { break case 'Add Missing Time Machines': { - functionLibraryChartingSpaceFunctions.addMissingTimeMachines(payload.node, thisObject.workspaceNode.rootNodes,functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + functionLibraryChartingSpaceFunctions.addMissingTimeMachines(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) } break case 'Play Tutorial': From e23c5fb3aaddc0863e4fff6643a54e5f1752e7c4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 19:28:07 +0200 Subject: [PATCH 120/192] Latest fixes --- ...CCXTFunctions.js => CryptoEcosystemFunctions.js} | 2 +- DesignSpace/Workspace/Workspace.js | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) rename DesignSpace/Workspace/FunctionLibraries/{CCXTFunctions.js => CryptoEcosystemFunctions.js} (99%) diff --git a/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js similarity index 99% rename from DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js rename to DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index 5069e98bb..ec75c0190 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -1,4 +1,4 @@ -function newCCXTFunctions() { +function newCryptoEcosystemFunctions() { thisObject = { addMissingExchanges: addMissingExchanges, addMissingAssets: addMissingAssets, diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index b4c9a0b64..5a6ea267b 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -62,7 +62,7 @@ function newWorkspace() { let functionLibraryShortcutKeys = newShortcutKeys() let functionLibraryOnFocus = newOnFocus() let functionLibrarySuperScripts = newSuperScriptsFunctions() - let functionLibraryCCXTFunctions = newCCXTFunctions() + let functionLibraryCryptoEcosystemFunctions = newCryptoEcosystemFunctions() let functionLibraryWebhookFunctions = newWebhookFunctions() let functionLibraryDependenciesFilter = newDependenciesFilter() let functionLibraryNodePath = newNodePath() @@ -687,17 +687,17 @@ function newWorkspace() { break case 'Add Missing Crypto Exchanges': { - functionLibraryCCXTFunctions.addMissingExchanges(payload.node, functionLibraryUiObjectsFromNodes) + functionLibraryCryptoEcosystemFunctions.addMissingExchanges(payload.node, functionLibraryUiObjectsFromNodes) } break case 'Add Missing Assets': { - functionLibraryCCXTFunctions.addMissingAssets(payload.node, functionLibraryUiObjectsFromNodes) + functionLibraryCryptoEcosystemFunctions.addMissingAssets(payload.node, functionLibraryUiObjectsFromNodes) } break case 'Add Missing Markets': { - functionLibraryCCXTFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) + functionLibraryCryptoEcosystemFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) } break case 'Add All Output Datasets': @@ -730,11 +730,6 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addMissingSingleMarketData(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break - case 'Add Missing Single Market Trading Data': - { - functionLibraryDataStorageFunctions.addMissingSingleMarketTradingData(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) - } - break case 'Add Missing Exchange Sessions': { functionLibraryDataStorageFunctions.addMissingExchangeSessions(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) From 89f6926027f3e47996c1623305c8623b155681a5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Sep 2020 20:46:37 +0200 Subject: [PATCH 121/192] Bug fixes --- .../FunctionLibraries/ChartingSpaceFunctions.js | 13 ++++++++++--- .../FunctionLibraries/DataStorageFunctions.js | 7 +++---- .../Workspace/FunctionLibraries/SessionFunctions.js | 2 +- .../Workspace/FunctionLibraries/TaskFunctions.js | 2 +- .../FunctionLibraries/UiObjectsFromNodes.js | 2 +- FloatingSpace/UiObjectTitle.js | 8 ++++++++ Panels/Layer.js | 2 +- Utilities/Branches.js | 4 +++- 8 files changed, 28 insertions(+), 12 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index f2394e699..fda297ad3 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -77,7 +77,7 @@ function newChartingSpaceFunctions() { if (networkNode === undefined) { return } let backtestingSessionsArray = nodeBranchToArray(networkNode, 'Backtesting Session') - let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Fordward Testing Session') + let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Forward Testing Session') let paperTradingSessionsArray = nodeBranchToArray(networkNode, 'Paper Trading Session') let liveTradingSessionsArray = nodeBranchToArray(networkNode, 'Live Trading Session') @@ -89,11 +89,13 @@ function newChartingSpaceFunctions() { function scanSessionArray(sessionsArray) { for (let i = 0; i < sessionsArray.length; i++) { let session = sessionsArray[i] + let market = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) + if (market.payload.referenceParent === undefined) { continue } if (isMissingChildren(node, session, true) === true) { let mineProducts let timeMachine = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Time Machine') timeMachine.payload.referenceParent = session - timeMachine.name = session.name + timeMachine.name = session.name + ' ' + session.type timeMachine.payload.floatingObject.collapseToggle() /* @@ -102,6 +104,12 @@ function newChartingSpaceFunctions() { mineProducts = nodeBranchToArray(networkNode, 'Data Mine Products') for (let j = 0; j < mineProducts.length; j++) { let mineProduct = mineProducts[j] + /* + We need to filter out the ones that do not belong to the market where + the session is running at. + */ + if (mineProduct.payload.parentNode.payload.referenceParent === undefined) { continue } + if (mineProduct.payload.parentNode.payload.referenceParent.id !== market.payload.referenceParent.id) { continue } let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') timelineChart.name = mineProduct.name @@ -122,7 +130,6 @@ function newChartingSpaceFunctions() { that are not the one we are interested in, we do the following: */ if (mineProduct.payload.parentNode === undefined) { continue } - if (mineProduct.payload.parentNode.payload.referenceParent === undefined) { continue } if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent === undefined) { continue } if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent.id !== session.id) { continue } /* diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index 29f5dafd9..b3ca80693 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -87,7 +87,7 @@ function newDataStorageFunctions() { if (networkNode === undefined) { return } let backtestingSessionsArray = nodeBranchToArray(networkNode, 'Backtesting Session') - let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Fordward Testing Session') + let fordwardTestingSessionsArray = nodeBranchToArray(networkNode, 'Forward Testing Session') let paperTradingSessionsArray = nodeBranchToArray(networkNode, 'Paper Trading Session') let liveTradingSessionsArray = nodeBranchToArray(networkNode, 'Live Trading Session') @@ -101,15 +101,14 @@ function newDataStorageFunctions() { let session = sessionsArray[i] if (isMissingChildren(node, session, true) === true) { let sessionReference = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Session Reference') - sessionReference.payload.referenceParent = session + sessionReference.payload.referenceParent = session /* Now I will connect the Session Reference child that is auto created with the market where the Session was found. */ let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) sessionReference.singleMarketTradingData.payload.referenceParent = marketTradingTasks.payload.referenceParent - timelineChart.payload.floatingObject.collapseToggle() - timelineChart.singleMarketTradingData.payload.floatingObject.collapseToggle() + marketTradingTasks.payload.floatingObject.collapseToggle() } } } diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index a80f00fcb..7a92aa824 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -86,7 +86,7 @@ function newSessionFunctions() { let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath) lightingPath = '' + - 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + + 'Backtesting Session->Paper Trading Session->Forward Testing Session->Live Trading Session->' + 'Parameters->' + 'Session Base Asset->Session Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->Snapshots->Heartbeats->User Defined Parameters->' + 'Exchange Account Asset->Asset->' + diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 8267b6f3a..89a39afc2 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -62,7 +62,7 @@ function newTaskFunctions() { 'Exchange Data Tasks->Exchange Trading Tasks->' + 'Market->Exchange Markets->Crypto Exchange->' + 'Market Base Asset->Market Quoted Asset->Asset->' + - 'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' + + 'Backtesting Session->Live Trading Session->Paper Trading Session->Forward Testing Session->' + 'Process Definition->' + 'Process Output->' + 'Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->Output Dataset Folder->' + diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 417c88a7e..2a7e86a28 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -696,7 +696,7 @@ function newUiObjectsFromNodes() { /* Check if there are sessions to run */ if (userAddingNew === false && node.savedPayload !== undefined) { - if (uiObjectType === 'Live Trading Session' || uiObjectType === 'Fordward Testing Session' || uiObjectType === 'Backtesting Session' || uiObjectType === 'Paper Trading Session') { + if (uiObjectType === 'Live Trading Session' || uiObjectType === 'Forward Testing Session' || uiObjectType === 'Backtesting Session' || uiObjectType === 'Paper Trading Session') { if (node.savedPayload.uiObject.isRunning === true) { if (node.payload.parentNode !== undefined) { if (sessionsToRun !== undefined) { // it might be undefined when you are spawning a session that was running while backed up diff --git a/FloatingSpace/UiObjectTitle.js b/FloatingSpace/UiObjectTitle.js index 2e387ef81..c1438e11e 100644 --- a/FloatingSpace/UiObjectTitle.js +++ b/FloatingSpace/UiObjectTitle.js @@ -116,6 +116,14 @@ function newUiObjectTitle() { } break } + case 'Use Reference Parent Type': { + let nodeToUse = thisObject.payload.node.payload.referenceParent + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.type + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.type + } + break + } case 'Use Reference Grandparent': { let nodeToUse = thisObject.payload.node.payload.referenceParent if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { diff --git a/Panels/Layer.js b/Panels/Layer.js index f791c5658..fb78668a3 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -165,7 +165,7 @@ function newLayer() { 'Single Market Data->Single Market Trading Data->Exchange Data Products->' + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + - 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + + 'Backtesting Session->Paper Trading Session->Forward Testing Session->Live Trading Session->' + 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + 'Market->Market Base Asset->Asset->' + 'Market Quoted Asset->Asset->' + diff --git a/Utilities/Branches.js b/Utilities/Branches.js index 60cf93758..b67bb9438 100644 --- a/Utilities/Branches.js +++ b/Utilities/Branches.js @@ -21,12 +21,14 @@ function nodeBranchToArray(node, nodeType) { } if (nodeDefinition.properties === undefined) { return } + let lastNodePropertyName for (let i = 0; i < nodeDefinition.properties.length; i++) { let property = nodeDefinition.properties[i] - + if (lastNodePropertyName === property.name) {continue} // Some nodes have a single property por multiple child node types. We need to check repeated properties only once so as no to duplicate results. switch (property.type) { case 'node': { scanNodeBranch(startingNode[property.name]) + lastNodePropertyName = property.name } break case 'array': { From e567acdd5d4fe040a5aad05bc8ff14e7eb998668 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 12:57:50 +0200 Subject: [PATCH 122/192] Data Mining Installed --- .../CryptoEcosystemFunctions.js | 52 +++++++++++- .../FunctionLibraries/TaskFunctions.js | 3 +- DesignSpace/Workspace/Workspace.js | 10 +++ Utilities/Branches.js | 13 ++- Utilities/Menu.js | 14 ++++ Utilities/NodeChildren.js | 84 +++++++++++++++++++ 6 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 Utilities/Menu.js diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index ec75c0190..90673f35d 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -2,7 +2,9 @@ function newCryptoEcosystemFunctions() { thisObject = { addMissingExchanges: addMissingExchanges, addMissingAssets: addMissingAssets, - addMissingMarkets: addMissingMarkets + addMissingMarkets: addMissingMarkets, + installMarket: installMarket, + uninstallMarket: uninstallMarket } return thisObject @@ -203,4 +205,52 @@ function newCryptoEcosystemFunctions() { console.log(err.stack) } } + + function installMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + + let market = node + let cryptoExchange = findNodeInNodeMesh(node, 'Crypto Exchange', undefined, true, false, true, false) + if (cryptoExchange === undefined) { + node.payload.uiObject.setErrorMessage('Market must be a descendant of a Crypto Exchange') + return + } + + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Network') { + installInNetwork(rootNode) + } + } + + function installInNetwork(network) { + /* + Here we complete the missing stuff at Data Mining + */ + let dataMining = findInBranch(network, 'Data Mining', node, true) + if (dataMining === undefined) { return } + + let exchangeDataTasks = findOrCreateChildWithReference(dataMining, 'Exchange Data Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeDataTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let marketDataTask = findAndRecreateChildWithReference(exchangeDataTasks, 'Market Data Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + + menuClick(marketDataTask, 'Add Missing Data Mine Tasks', true) + menuClickOfNodeArray(marketDataTask.dataMineTasks, 'Add All Tasks', true) + /* + Here we complete the missing stuff at Session Independent Data + */ + let sessionIndependentData = findInBranch(network, 'Session Independent Data', node, true) + if (sessionIndependentData === undefined) { return } + + let exchangeDataProducts = findOrCreateChildWithReference(sessionIndependentData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeDataProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let singleMarketData = findAndRecreateChildWithReference(exchangeDataProducts, 'Single Market Data', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + + menuClick(singleMarketData, 'Add All Data Mine Products', true) + menuClickOfNodeArray(singleMarketData.dataMineProducts, 'Add All Data Products', true) + } + } + + function uninstallMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 89a39afc2..626082b22 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -451,7 +451,8 @@ function newTaskFunctions() { if (node.payload.referenceParent === undefined) { return } let taskManager = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Task Manager') - taskManager.name = node.name + taskManager.name = node.payload.referenceParent.name + taskManager.payload.floatingObject.collapseToggle() switch (node.type) { case 'Data Mine Tasks': { diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 5a6ea267b..991d43d68 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -700,6 +700,16 @@ function newWorkspace() { functionLibraryCryptoEcosystemFunctions.addMissingMarkets(payload.node, functionLibraryUiObjectsFromNodes, functionLibraryNodeCloning) } break + case 'Install Market': + { + functionLibraryCryptoEcosystemFunctions.installMarket(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + } + break + case 'Uninstall Market': + { + functionLibraryCryptoEcosystemFunctions.uninstallMarket(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + } + break case 'Add All Output Datasets': { functionLibraryDataMineFunctions.addAllOutputDatasets(payload.node, functionLibraryUiObjectsFromNodes) diff --git a/Utilities/Branches.js b/Utilities/Branches.js index b67bb9438..7609b6ec3 100644 --- a/Utilities/Branches.js +++ b/Utilities/Branches.js @@ -43,4 +43,15 @@ function nodeBranchToArray(node, nodeType) { } } - +function findInBranch(startingNode, nodeType, errorNode, connectedViaPayload) { + /* + This function finds a node in a brach and reports an error if it could not be found. + */ + let nodeFound = findNodeInNodeMesh(startingNode, nodeType, undefined, connectedViaPayload, true, false, false) + if (nodeFound === undefined) { + errorNode.payload.uiObject.setErrorMessage('Could not find ' + nodeType + ' at ' + startingNode.type + ' ' + startingNode.name) + return + } else { + return nodeFound + } +} diff --git a/Utilities/Menu.js b/Utilities/Menu.js new file mode 100644 index 000000000..6412faf23 --- /dev/null +++ b/Utilities/Menu.js @@ -0,0 +1,14 @@ +function menuClickOfNodeArray(nodeArray, action, confirm) { + for (let j=0; j < nodeArray.length; j++) { + let node = nodeArray[j] + menuClick(node, action, confirm) + } +} + +function menuClick(node, action, confirm) { + let menu = node.payload.uiObject.menu + menu.internalClick(action) + if (confirm === true) { + menu.internalClick(action) + } +} \ No newline at end of file diff --git a/Utilities/NodeChildren.js b/Utilities/NodeChildren.js index 3af5b1643..43889d8df 100644 --- a/Utilities/NodeChildren.js +++ b/Utilities/NodeChildren.js @@ -58,4 +58,88 @@ function isMissingChildren(startingNode, checkNode, checkReferenceParent) { } return true } +} + +function findChildReferencingThisNode(startingNode, checkNode) { + /* + This functioin scan all the children of a node and returns the child + that is referencing the checkNode. + */ + if (startingNode === undefined) { return } + if (checkNode === undefined) { return } + + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + /* We scan through this node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + let child = startingNode[property.name] + + if (child.payload !== undefined) { + if (child.payload.referenceParent !== undefined) { + if (child.payload.referenceParent.id === checkNode.id) { + return child + } + } + } + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + let arrayItem = startingNodePropertyArray[m] + + if (arrayItem.payload !== undefined) { + if (arrayItem.payload.referenceParent !== undefined) { + if (arrayItem.payload.referenceParent.id === checkNode.id) { + return arrayItem + } + } + } + } + } + break + } + } + } + return true + } +} + +function findOrCreateChildWithReference(startingNode, childType, referencedNode, functionLibraryUiObjectsFromNodes) { + /* + This function find the child node of starting node that references + refereced node. If there is none, then it creates a child and stablish + the referecen. + */ + let child + if (isMissingChildren(startingNode, referencedNode, true) === true) { + child = functionLibraryUiObjectsFromNodes.addUIObject(startingNode, childType) + child.payload.referenceParent = referencedNode + } else { + child = findChildReferencingThisNode(startingNode, referencedNode) + } + return child +} + +function findAndRecreateChildWithReference(startingNode, childType, referencedNode, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + /* + This function finds the child of the starting node that references + the reference node and if found it deletes it. Existing or not + it creates it again with the child type specified. + */ + let child + child = findChildReferencingThisNode(startingNode, referencedNode) + if (child !== undefined) { + functionLibraryNodeDeleter.deleteUIObject(child, rootNodes) + } + child = functionLibraryUiObjectsFromNodes.addUIObject(startingNode, childType) + child.payload.referenceParent = referencedNode + return child } \ No newline at end of file From f10e7a7c01198e66a4127d378c4cca564a4a4b5f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 13:29:57 +0200 Subject: [PATCH 123/192] Update CryptoEcosystemFunctions.js --- .../CryptoEcosystemFunctions.js | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index 90673f35d..cebf36007 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -236,6 +236,26 @@ function newCryptoEcosystemFunctions() { menuClick(marketDataTask, 'Add Missing Data Mine Tasks', true) menuClickOfNodeArray(marketDataTask.dataMineTasks, 'Add All Tasks', true) /* + Next we complete the missing stuff at Testing Environment + */ + installEnvironment('Testing Environment') + /* + Next we complete the missing stuff at Production Environment + */ + installEnvironment('Production Environment') + + function installEnvironment(environment) { + let tradingMining = findInBranch(network, environment, node, true) + if (tradingMining === undefined) { return } + + let exchangeTradingTasks = findOrCreateChildWithReference(tradingMining, 'Exchange Trading Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeTradingTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let marketTradingTask = findAndRecreateChildWithReference(exchangeTradingTasks, 'Market Trading Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + + menuClick(marketTradingTask, 'Add Missing Trading Mine Tasks', true) + menuClickOfNodeArray(marketTradingTask.tradingMineTasks, 'Add All Tasks', true) + } + /* Here we complete the missing stuff at Session Independent Data */ let sessionIndependentData = findInBranch(network, 'Session Independent Data', node, true) @@ -244,9 +264,27 @@ function newCryptoEcosystemFunctions() { let exchangeDataProducts = findOrCreateChildWithReference(sessionIndependentData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeDataProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 let singleMarketData = findAndRecreateChildWithReference(exchangeDataProducts, 'Single Market Data', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + singleMarketData.payload.floatingObject.collapseToggle() menuClick(singleMarketData, 'Add All Data Mine Products', true) menuClickOfNodeArray(singleMarketData.dataMineProducts, 'Add All Data Products', true) + /* + Finally we complete the missing stuff at Session Based Data + */ + let sessionBasedData = findInBranch(network, 'Session Based Data', node, true) + if (sessionBasedData === undefined) { return } + + let exchangeSessions = findOrCreateChildWithReference(sessionBasedData, 'Exchange Sessions', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeSessions.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + + menuClick(exchangeSessions, 'Add Missing Session References', true) + + for (let j = 0; j < exchangeSessions.sessionReferences.length; j++) { + sessionReference = exchangeSessions.sessionReferences[j] + menuClick(sessionReference.singleMarketTradingData, 'Add All Trading Mine Products', true) + menuClickOfNodeArray(sessionReference.singleMarketTradingData.tradingMineProducts, 'Add All Data Products', true) + sessionReference.singleMarketTradingData.payload.floatingObject.collapseToggle() + } } } From 7af85bf77dc4ee0a7ab5ffd3f3644c3a6c911a4a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 14:56:30 +0200 Subject: [PATCH 124/192] Dashboards --- .../ChartingSpaceFunctions.js | 46 +++++- .../CryptoEcosystemFunctions.js | 132 +++++++++++------- DesignSpace/Workspace/Workspace.js | 5 + 3 files changed, 128 insertions(+), 55 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index fda297ad3..bd6676ddb 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -1,6 +1,7 @@ function newChartingSpaceFunctions() { thisObject = { addAllMineLayers: addAllMineLayers, + addMissingDashboards: addMissingDashboards, addMissingTimeMachines: addMissingTimeMachines } @@ -64,6 +65,10 @@ function newChartingSpaceFunctions() { } function addMissingTimeMachines(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + if (node.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage('This node needs to have a Reference Parent for this command tu run.') + return + } for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] @@ -89,6 +94,9 @@ function newChartingSpaceFunctions() { function scanSessionArray(sessionsArray) { for (let i = 0; i < sessionsArray.length; i++) { let session = sessionsArray[i] + let environment = findNodeInNodeMesh(session, node.payload.referenceParent.type, undefined, true, false, true, false) + if (environment === undefined) { continue } + if (environment.id !== node.payload.referenceParent.id) { continue } let market = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) if (market.payload.referenceParent === undefined) { continue } if (isMissingChildren(node, session, true) === true) { @@ -97,7 +105,7 @@ function newChartingSpaceFunctions() { timeMachine.payload.referenceParent = session timeMachine.name = session.name + ' ' + session.type timeMachine.payload.floatingObject.collapseToggle() - + timeMachine.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 /* We need to create a Timeline Chart for each Data Mine Indicators. */ @@ -182,4 +190,40 @@ function newChartingSpaceFunctions() { } } } + + function addMissingDashboards(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Network') { + let network = rootNode + scanNetwork(network) + } + } + + function scanNetwork(network) { + if (network === undefined) { return } + + for (let j = 0; j < network.networkNodes.length; j++) { + let networkNode = network.networkNodes[j] + scanNetworkNode(networkNode) + } + + function scanNetworkNode(networkNode) { + let testingEnvironment = findInBranch(networkNode, 'Testing Environment', node, true) + let productionEnvironment = findInBranch(networkNode, 'Production Environment', node, true) + + if (isMissingChildren(node, testingEnvironment, true) === true) { + let dashboard = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Dashboard') + dashboard.payload.referenceParent = testingEnvironment + dashboard.name = testingEnvironment.type + ' ' + networkNode.name + } + + if (isMissingChildren(node, productionEnvironment, true) === true) { + let dashboard = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Dashboard') + dashboard.payload.referenceParent = productionEnvironment + dashboard.name = productionEnvironment.type + ' ' + networkNode.name + } + } + } + } } diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index cebf36007..c069847d8 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -222,70 +222,94 @@ function newCryptoEcosystemFunctions() { } } + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Charting Space') { + installInChartingSpace(rootNode) + } + } + function installInNetwork(network) { - /* - Here we complete the missing stuff at Data Mining - */ - let dataMining = findInBranch(network, 'Data Mining', node, true) - if (dataMining === undefined) { return } - let exchangeDataTasks = findOrCreateChildWithReference(dataMining, 'Exchange Data Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) - exchangeDataTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - let marketDataTask = findAndRecreateChildWithReference(exchangeDataTasks, 'Market Data Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) - - menuClick(marketDataTask, 'Add Missing Data Mine Tasks', true) - menuClickOfNodeArray(marketDataTask.dataMineTasks, 'Add All Tasks', true) - /* - Next we complete the missing stuff at Testing Environment - */ - installEnvironment('Testing Environment') - /* - Next we complete the missing stuff at Production Environment - */ - installEnvironment('Production Environment') - - function installEnvironment(environment) { - let tradingMining = findInBranch(network, environment, node, true) - if (tradingMining === undefined) { return } - - let exchangeTradingTasks = findOrCreateChildWithReference(tradingMining, 'Exchange Trading Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) - exchangeTradingTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - let marketTradingTask = findAndRecreateChildWithReference(exchangeTradingTasks, 'Market Trading Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) - - menuClick(marketTradingTask, 'Add Missing Trading Mine Tasks', true) - menuClickOfNodeArray(marketTradingTask.tradingMineTasks, 'Add All Tasks', true) + for (let j = 0; j < network.networkNodes.length; j++) { + let networkNode = network.networkNodes[j] + installInNetworkNode(networkNode) } - /* - Here we complete the missing stuff at Session Independent Data - */ - let sessionIndependentData = findInBranch(network, 'Session Independent Data', node, true) - if (sessionIndependentData === undefined) { return } - let exchangeDataProducts = findOrCreateChildWithReference(sessionIndependentData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) - exchangeDataProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - let singleMarketData = findAndRecreateChildWithReference(exchangeDataProducts, 'Single Market Data', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) - singleMarketData.payload.floatingObject.collapseToggle() + function installInNetworkNode(networkNode) { + /* + Here we complete the missing stuff at Data Mining + */ + let dataMining = findInBranch(networkNode, 'Data Mining', node, true) + if (dataMining === undefined) { return } - menuClick(singleMarketData, 'Add All Data Mine Products', true) - menuClickOfNodeArray(singleMarketData.dataMineProducts, 'Add All Data Products', true) - /* - Finally we complete the missing stuff at Session Based Data - */ - let sessionBasedData = findInBranch(network, 'Session Based Data', node, true) - if (sessionBasedData === undefined) { return } + let exchangeDataTasks = findOrCreateChildWithReference(dataMining, 'Exchange Data Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeDataTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let marketDataTask = findAndRecreateChildWithReference(exchangeDataTasks, 'Market Data Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) - let exchangeSessions = findOrCreateChildWithReference(sessionBasedData, 'Exchange Sessions', cryptoExchange, functionLibraryUiObjectsFromNodes) - exchangeSessions.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + menuClick(marketDataTask, 'Add Missing Data Mine Tasks', true) + menuClickOfNodeArray(marketDataTask.dataMineTasks, 'Add All Tasks', true) + /* + Next we complete the missing stuff at Testing Environment + */ + installEnvironment('Testing Environment') + /* + Next we complete the missing stuff at Production Environment + */ + installEnvironment('Production Environment') - menuClick(exchangeSessions, 'Add Missing Session References', true) + function installEnvironment(environment) { + let tradingMining = findInBranch(networkNode, environment, node, true) + if (tradingMining === undefined) { return } - for (let j = 0; j < exchangeSessions.sessionReferences.length; j++) { - sessionReference = exchangeSessions.sessionReferences[j] - menuClick(sessionReference.singleMarketTradingData, 'Add All Trading Mine Products', true) - menuClickOfNodeArray(sessionReference.singleMarketTradingData.tradingMineProducts, 'Add All Data Products', true) - sessionReference.singleMarketTradingData.payload.floatingObject.collapseToggle() + let exchangeTradingTasks = findOrCreateChildWithReference(tradingMining, 'Exchange Trading Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeTradingTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let marketTradingTask = findAndRecreateChildWithReference(exchangeTradingTasks, 'Market Trading Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + + menuClick(marketTradingTask, 'Add Missing Trading Mine Tasks', true) + menuClickOfNodeArray(marketTradingTask.tradingMineTasks, 'Add All Tasks', true) + } + /* + Here we complete the missing stuff at Session Independent Data + */ + let sessionIndependentData = findInBranch(networkNode, 'Session Independent Data', node, true) + if (sessionIndependentData === undefined) { return } + + let exchangeDataProducts = findOrCreateChildWithReference(sessionIndependentData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeDataProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let singleMarketData = findAndRecreateChildWithReference(exchangeDataProducts, 'Single Market Data', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + singleMarketData.payload.floatingObject.collapseToggle() + + menuClick(singleMarketData, 'Add All Data Mine Products', true) + menuClickOfNodeArray(singleMarketData.dataMineProducts, 'Add All Data Products', true) + /* + Finally we complete the missing stuff at Session Based Data + */ + let sessionBasedData = findInBranch(networkNode, 'Session Based Data', node, true) + if (sessionBasedData === undefined) { return } + + let exchangeSessions = findOrCreateChildWithReference(sessionBasedData, 'Exchange Sessions', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeSessions.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + + menuClick(exchangeSessions, 'Add Missing Session References', true) + + for (let j = 0; j < exchangeSessions.sessionReferences.length; j++) { + sessionReference = exchangeSessions.sessionReferences[j] + menuClick(sessionReference.singleMarketTradingData, 'Add All Trading Mine Products', true) + menuClickOfNodeArray(sessionReference.singleMarketTradingData.tradingMineProducts, 'Add All Data Products', true) + sessionReference.singleMarketTradingData.payload.floatingObject.collapseToggle() + } } } + + function installInChartingSpace(chartingSpace) { + let dashboard = findNodeInNodeMesh(chartingSpace, undefined, 'Installed Charts', true, true, false, false) + if (dashboard === undefined) { + node.payload.uiObject.setErrorMessage('Could not find Dashboard named Installed Charts at the Charting Space.') + return + } + + } } function uninstallMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 991d43d68..6632dfeb4 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -770,6 +770,11 @@ function newWorkspace() { functionLibraryChartingSpaceFunctions.addMissingTimeMachines(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) } break + case 'Add Missing Dashboards': + { + functionLibraryChartingSpaceFunctions.addMissingDashboards(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + } + break case 'Play Tutorial': { canvas.tutorialSpace.playTutorial(payload.node) From f919c88cb01c44e8c159f6687716085caeb6183b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 17:13:46 +0200 Subject: [PATCH 125/192] Update CryptoEcosystemFunctions.js --- .../CryptoEcosystemFunctions.js | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index c069847d8..ae28574ab 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -214,6 +214,7 @@ function newCryptoEcosystemFunctions() { node.payload.uiObject.setErrorMessage('Market must be a descendant of a Crypto Exchange') return } + let environmentArray = [] for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] @@ -241,7 +242,10 @@ function newCryptoEcosystemFunctions() { Here we complete the missing stuff at Data Mining */ let dataMining = findInBranch(networkNode, 'Data Mining', node, true) - if (dataMining === undefined) { return } + if (dataMining === undefined) { + node.payload.uiObject.setErrorMessage('Data Mining node not found at Network Node ' + networkNode.name) + return + } let exchangeDataTasks = findOrCreateChildWithReference(dataMining, 'Exchange Data Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeDataTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 @@ -259,10 +263,19 @@ function newCryptoEcosystemFunctions() { installEnvironment('Production Environment') function installEnvironment(environment) { - let tradingMining = findInBranch(networkNode, environment, node, true) - if (tradingMining === undefined) { return } + /* + Now we install the environmnet at the current Network Node + */ + let environmentFound = findInBranch(networkNode, environment, node, true) + if (environmentFound === undefined) { + node.payload.uiObject.setErrorMessage(environment + ' node not found at Network Node ' + networkNode.name) + return + } - let exchangeTradingTasks = findOrCreateChildWithReference(tradingMining, 'Exchange Trading Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) + /* This will be needed at the charging space, for creating Dashboards */ + environmentArray.push({ environmentNode: environmentFound, networkNode: networkNode}) + + let exchangeTradingTasks = findOrCreateChildWithReference(environmentFound, 'Exchange Trading Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeTradingTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 let marketTradingTask = findAndRecreateChildWithReference(exchangeTradingTasks, 'Market Trading Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) @@ -273,7 +286,10 @@ function newCryptoEcosystemFunctions() { Here we complete the missing stuff at Session Independent Data */ let sessionIndependentData = findInBranch(networkNode, 'Session Independent Data', node, true) - if (sessionIndependentData === undefined) { return } + if (sessionIndependentData === undefined) { + node.payload.uiObject.setErrorMessage('Session Independent Data node not found at Network Node ' + networkNode.name) + return + } let exchangeDataProducts = findOrCreateChildWithReference(sessionIndependentData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeDataProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 @@ -286,7 +302,10 @@ function newCryptoEcosystemFunctions() { Finally we complete the missing stuff at Session Based Data */ let sessionBasedData = findInBranch(networkNode, 'Session Based Data', node, true) - if (sessionBasedData === undefined) { return } + if (sessionBasedData === undefined) { + node.payload.uiObject.setErrorMessage('Session Based Data node not found at Network Node ' + networkNode.name) + return + } let exchangeSessions = findOrCreateChildWithReference(sessionBasedData, 'Exchange Sessions', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeSessions.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 @@ -303,12 +322,15 @@ function newCryptoEcosystemFunctions() { } function installInChartingSpace(chartingSpace) { - let dashboard = findNodeInNodeMesh(chartingSpace, undefined, 'Installed Charts', true, true, false, false) - if (dashboard === undefined) { - node.payload.uiObject.setErrorMessage('Could not find Dashboard named Installed Charts at the Charting Space.') - return - } + for (let i = 0; i < environmentArray.length; i++) { + let environment = environmentArray[i] + if (isMissingChildren(chartingSpace, environment.environmentNode, true) === true) { + let dashboard = functionLibraryUiObjectsFromNodes.addUIObject(chartingSpace, 'Dashboard') + dashboard.payload.referenceParent = environment.environmentNode + dashboard.name = environment.environmentNode.type + ' ' + environment.networkNode.name + } + } } } From b4cfab3a0dc4b17ba9f4507b6c9b65db6e78c8d7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 20:00:48 +0200 Subject: [PATCH 126/192] Bug with Session References fixed --- .../ChartingSpaceFunctions.js | 177 +++++++++--------- .../CryptoEcosystemFunctions.js | 66 +++++-- .../FunctionLibraries/DataStorageFunctions.js | 25 ++- DesignSpace/Workspace/Workspace.js | 4 +- FloatingSpace/FloatingObject.js | 15 ++ 5 files changed, 174 insertions(+), 113 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index bd6676ddb..453752151 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -2,7 +2,8 @@ function newChartingSpaceFunctions() { thisObject = { addAllMineLayers: addAllMineLayers, addMissingDashboards: addMissingDashboards, - addMissingTimeMachines: addMissingTimeMachines + addMissingTimeMachines: addMissingTimeMachines, + createTimeMachine: createTimeMachine } return thisObject @@ -100,97 +101,101 @@ function newChartingSpaceFunctions() { let market = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) if (market.payload.referenceParent === undefined) { continue } if (isMissingChildren(node, session, true) === true) { - let mineProducts - let timeMachine = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Time Machine') - timeMachine.payload.referenceParent = session - timeMachine.name = session.name + ' ' + session.type - timeMachine.payload.floatingObject.collapseToggle() - timeMachine.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - /* - We need to create a Timeline Chart for each Data Mine Indicators. - */ - mineProducts = nodeBranchToArray(networkNode, 'Data Mine Products') - for (let j = 0; j < mineProducts.length; j++) { - let mineProduct = mineProducts[j] - /* - We need to filter out the ones that do not belong to the market where - the session is running at. - */ - if (mineProduct.payload.parentNode.payload.referenceParent === undefined) { continue } - if (mineProduct.payload.parentNode.payload.referenceParent.id !== market.payload.referenceParent.id) { continue } - - let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') - timelineChart.name = mineProduct.name - timelineChart.layersManager.payload.referenceParent = mineProduct - timelineChart.payload.floatingObject.collapseToggle() - timelineChart.layersManager.payload.floatingObject.collapseToggle() - - let menu = timelineChart.layersManager.payload.uiObject.menu - menu.internalClick('Add All Mine Layers') - menu.internalClick('Add All Mine Layers') - } - - mineProducts = nodeBranchToArray(networkNode, 'Trading Mine Products') - for (let j = 0; j < mineProducts.length; j++) { - let mineProduct = mineProducts[j] - /* - The mine products found so far, belongs to any session. To filer all the sessions - that are not the one we are interested in, we do the following: - */ - if (mineProduct.payload.parentNode === undefined) { continue } - if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent === undefined) { continue } - if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent.id !== session.id) { continue } - /* - At the current version of Superalgos, beta 6, there is only one Trading Mine, - with only one bot, and it has so many data products that we want to put them - in 3 different timeline charts. So we will create 3 charts, connect them, - and delete from each one 1/3 of the layers. We do all that next: - */ - - for (let k = 0; k < 3; k++) { - let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') - - timelineChart.layersManager.payload.referenceParent = mineProduct - timelineChart.payload.floatingObject.collapseToggle() - timelineChart.layersManager.payload.floatingObject.collapseToggle() - - let menu = timelineChart.layersManager.payload.uiObject.menu - menu.internalClick('Add All Mine Layers') - menu.internalClick('Add All Mine Layers') - - switch (k) { - case 0: { - timelineChart.name = 'Trading Engine' - deleteNodeByName('Trading System') - deleteNodeByName('Objects') - break - } - case 1: { - timelineChart.name = 'Trading System' - deleteNodeByName('Trading Engine') - deleteNodeByName('Objects') - break - } - case 2: { - timelineChart.name = 'Objects' - deleteNodeByName('Trading Engine') - deleteNodeByName('Trading System') - break - } - } - function deleteNodeByName(nodeName) { - let nodeToDelete = findNodeInNodeMesh(timelineChart.layersManager, undefined, nodeName, true, true, false, false) - if (nodeToDelete === undefined) { return } - functionLibraryNodeDeleter.deleteUIObject(nodeToDelete, rootNodes) - } - } - } + createTimeMachine(node, session, market.payload.referenceParent, networkNode, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) } } } } } + function createTimeMachine(dashboard, session, market, networkNode, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + let mineProducts + let timeMachine = functionLibraryUiObjectsFromNodes.addUIObject(dashboard, 'Time Machine') + timeMachine.payload.referenceParent = session + timeMachine.name = session.name + ' ' + session.type + timeMachine.payload.floatingObject.collapseToggle() + timeMachine.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + /* + We need to create a Timeline Chart for each Data Mine Indicators. + */ + mineProducts = nodeBranchToArray(networkNode, 'Data Mine Products') + for (let j = 0; j < mineProducts.length; j++) { + let mineProduct = mineProducts[j] + /* + We need to filter out the ones that do not belong to the market where + the session is running at. + */ + if (mineProduct.payload.parentNode.payload.referenceParent === undefined) { continue } + if (mineProduct.payload.parentNode.payload.referenceParent.id !== market.id) { continue } + + let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') + timelineChart.name = mineProduct.name + timelineChart.layersManager.payload.referenceParent = mineProduct + timelineChart.payload.floatingObject.collapseToggle() + timelineChart.layersManager.payload.floatingObject.collapseToggle() + + let menu = timelineChart.layersManager.payload.uiObject.menu + menu.internalClick('Add All Mine Layers') + menu.internalClick('Add All Mine Layers') + } + + mineProducts = nodeBranchToArray(networkNode, 'Trading Mine Products') + for (let j = 0; j < mineProducts.length; j++) { + let mineProduct = mineProducts[j] + /* + The mine products found so far, belongs to any session. To filer all the sessions + that are not the one we are interested in, we do the following: + */ + if (mineProduct.payload.parentNode === undefined) { continue } + if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent === undefined) { continue } + if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent.id !== session.id) { continue } + /* + At the current version of Superalgos, beta 6, there is only one Trading Mine, + with only one bot, and it has so many data products that we want to put them + in 3 different timeline charts. So we will create 3 charts, connect them, + and delete from each one 1/3 of the layers. We do all that next: + */ + + for (let k = 0; k < 3; k++) { + let timelineChart = functionLibraryUiObjectsFromNodes.addUIObject(timeMachine, 'Timeline Chart') + + timelineChart.layersManager.payload.referenceParent = mineProduct + timelineChart.payload.floatingObject.collapseToggle() + timelineChart.layersManager.payload.floatingObject.collapseToggle() + + let menu = timelineChart.layersManager.payload.uiObject.menu + menu.internalClick('Add All Mine Layers') + menu.internalClick('Add All Mine Layers') + + switch (k) { + case 0: { + timelineChart.name = 'Trading Engine' + deleteNodeByName('Trading System') + deleteNodeByName('Objects') + break + } + case 1: { + timelineChart.name = 'Trading System' + deleteNodeByName('Trading Engine') + deleteNodeByName('Objects') + break + } + case 2: { + timelineChart.name = 'Objects' + deleteNodeByName('Trading Engine') + deleteNodeByName('Trading System') + break + } + } + function deleteNodeByName(nodeName) { + let nodeToDelete = findNodeInNodeMesh(timelineChart.layersManager, undefined, nodeName, true, true, false, false) + if (nodeToDelete === undefined) { return } + functionLibraryNodeDeleter.deleteUIObject(nodeToDelete, rootNodes) + } + } + } + } + function addMissingDashboards(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index ae28574ab..e67c29b25 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -206,7 +206,7 @@ function newCryptoEcosystemFunctions() { } } - function installMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + function installMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter, functionLibraryChartingSpaceFunctions, functionLibraryDataStorageFunctions) { let market = node let cryptoExchange = findNodeInNodeMesh(node, 'Crypto Exchange', undefined, true, false, true, false) @@ -214,7 +214,7 @@ function newCryptoEcosystemFunctions() { node.payload.uiObject.setErrorMessage('Market must be a descendant of a Crypto Exchange') return } - let environmentArray = [] + let dashboardsArray = [] for (let i = 0; i < rootNodes.length; i++) { let rootNode = rootNodes[i] @@ -253,6 +253,8 @@ function newCryptoEcosystemFunctions() { menuClick(marketDataTask, 'Add Missing Data Mine Tasks', true) menuClickOfNodeArray(marketDataTask.dataMineTasks, 'Add All Tasks', true) + + let sessionsCreatedArray = [] /* Next we complete the missing stuff at Testing Environment */ @@ -272,15 +274,20 @@ function newCryptoEcosystemFunctions() { return } - /* This will be needed at the charging space, for creating Dashboards */ - environmentArray.push({ environmentNode: environmentFound, networkNode: networkNode}) - let exchangeTradingTasks = findOrCreateChildWithReference(environmentFound, 'Exchange Trading Tasks', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeTradingTasks.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 let marketTradingTask = findAndRecreateChildWithReference(exchangeTradingTasks, 'Market Trading Tasks', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) menuClick(marketTradingTask, 'Add Missing Trading Mine Tasks', true) menuClickOfNodeArray(marketTradingTask.tradingMineTasks, 'Add All Tasks', true) + + /* This will be needed at the charging space, for creating Dashboards */ + let backtestingSessionsArray = nodeBranchToArray(marketTradingTask, 'Backtesting Session') + let liveTradingSessionsArray = nodeBranchToArray(marketTradingTask, 'Live Trading Session') + let allSessionsArray = backtestingSessionsArray.concat(liveTradingSessionsArray) + sessionsCreatedArray = sessionsCreatedArray.concat(allSessionsArray) + + dashboardsArray.push({ environmentNode: environmentFound, networkNode: networkNode, sessionsArray: allSessionsArray }) } /* Here we complete the missing stuff at Session Independent Data @@ -309,9 +316,36 @@ function newCryptoEcosystemFunctions() { let exchangeSessions = findOrCreateChildWithReference(sessionBasedData, 'Exchange Sessions', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeSessions.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - - menuClick(exchangeSessions, 'Add Missing Session References', true) - + /* + We need to delete all the session references related to the market we are installing. + We make a copy of the array so that if we need to delete some nodes it does not + affect the loop evaluating the nodes. + */ + let sessionReferencesArray = [] + for (let i = 0; i < exchangeSessions.sessionReferences.length; i++) { + sessionReference = exchangeSessions.sessionReferences[i] + sessionReferencesArray.push(sessionReference) + } + for (let i = 0; i < sessionReferencesArray.length; i++) { + sessionReference = sessionReferencesArray[i] + if (sessionReference.singleMarketTradingData === undefined) { continue } + if (sessionReference.singleMarketTradingData.payload.referenceParent === undefined) { continue } + if (sessionReference.singleMarketTradingData.payload.referenceParent.id === node.id) { + functionLibraryNodeDeleter.deleteUIObject(sessionReference, rootNodes) + } + } + /* + Create the new session references. + */ + for (let i = 0; i < sessionsCreatedArray.length; i++) { + let session = sessionsCreatedArray[i] + if (isMissingChildren(exchangeSessions, session, true) === true) { + functionLibraryDataStorageFunctions.createSessionReference(exchangeSessions, session, functionLibraryUiObjectsFromNodes) + } + } + /* + Create everything inside the session references. + */ for (let j = 0; j < exchangeSessions.sessionReferences.length; j++) { sessionReference = exchangeSessions.sessionReferences[j] menuClick(sessionReference.singleMarketTradingData, 'Add All Trading Mine Products', true) @@ -323,18 +357,20 @@ function newCryptoEcosystemFunctions() { function installInChartingSpace(chartingSpace) { - for (let i = 0; i < environmentArray.length; i++) { - let environment = environmentArray[i] - if (isMissingChildren(chartingSpace, environment.environmentNode, true) === true) { - let dashboard = functionLibraryUiObjectsFromNodes.addUIObject(chartingSpace, 'Dashboard') - dashboard.payload.referenceParent = environment.environmentNode - dashboard.name = environment.environmentNode.type + ' ' + environment.networkNode.name + for (let i = 0; i < dashboardsArray.length; i++) { + let arrayItem = dashboardsArray[i] + let dashboard = findOrCreateChildWithReference(chartingSpace, 'Dashboard', arrayItem.environmentNode, functionLibraryUiObjectsFromNodes) + dashboard.name = arrayItem.environmentNode.type + ' ' + arrayItem.networkNode.name + + for (let j = 0; j < arrayItem.sessionsArray.length; j++) { + let session = arrayItem.sessionsArray[j] + functionLibraryChartingSpaceFunctions.createTimeMachine(dashboard, session, node, arrayItem.networkNode, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) } } } } - function uninstallMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) { + function uninstallMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter, functionLibraryChartingSpaceFunctions, functionLibraryDataStorageFunctions) { } } diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index b3ca80693..6b2ca9502 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -6,7 +6,8 @@ function newDataStorageFunctions() { addMissingSessionReferences: addMissingSessionReferences, addMissingSingleMarketData: addMissingSingleMarketData, addMissingExchangeSessions: addMissingExchangeSessions, - addMissingExchangeDataProducts: addMissingExchangeDataProducts + addMissingExchangeDataProducts: addMissingExchangeDataProducts, + createSessionReference: createSessionReference } return thisObject @@ -100,20 +101,24 @@ function newDataStorageFunctions() { for (let i = 0; i < sessionsArray.length; i++) { let session = sessionsArray[i] if (isMissingChildren(node, session, true) === true) { - let sessionReference = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Session Reference') - sessionReference.payload.referenceParent = session - /* - Now I will connect the Session Reference child that is auto created with the market - where the Session was found. - */ - let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) - sessionReference.singleMarketTradingData.payload.referenceParent = marketTradingTasks.payload.referenceParent - marketTradingTasks.payload.floatingObject.collapseToggle() + createSessionReference(node, session, functionLibraryUiObjectsFromNodes) } } } } + function createSessionReference(node, session, functionLibraryUiObjectsFromNodes) { + let sessionReference = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Session Reference') + sessionReference.payload.referenceParent = session + /* + Now I will connect the Session Reference child that is auto created with the market + where the Session was found. + */ + let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) + sessionReference.singleMarketTradingData.payload.referenceParent = marketTradingTasks.payload.referenceParent + marketTradingTasks.payload.floatingObject.collapseToggle() + } + function addMissingSingleMarketData(node, rootNodes, functionLibraryUiObjectsFromNodes) { if (node.payload.referenceParent === undefined) { return } if (node.payload.referenceParent.exchangeMarkets === undefined) { return } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 6632dfeb4..1c8ed2df4 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -702,12 +702,12 @@ function newWorkspace() { break case 'Install Market': { - functionLibraryCryptoEcosystemFunctions.installMarket(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + functionLibraryCryptoEcosystemFunctions.installMarket(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter, functionLibraryChartingSpaceFunctions, functionLibraryDataStorageFunctions) } break case 'Uninstall Market': { - functionLibraryCryptoEcosystemFunctions.uninstallMarket(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + functionLibraryCryptoEcosystemFunctions.uninstallMarket(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter, functionLibraryChartingSpaceFunctions, functionLibraryDataStorageFunctions) } break case 'Add All Output Datasets': diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 76901b340..c3da76f1c 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -274,6 +274,9 @@ function newFloatingObject() { } function invisiblePhysics() { + if (thisObject.payload === undefined) {return} + if (thisObject.payload.uiObject === undefined) {return} + if (thisObject.payload.uiObject !== undefined) { thisObject.payload.uiObject.invisiblePhysics() } @@ -589,6 +592,9 @@ function newFloatingObject() { } function drawBackground() { + if (thisObject.payload === undefined) {return} + if (thisObject.payload.uiObject === undefined) {return} + if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { if (thisObject.payload.uiObject.isShowing !== true) { @@ -599,6 +605,9 @@ function newFloatingObject() { } function drawMiddleground() { + if (thisObject.payload === undefined) {return} + if (thisObject.payload.uiObject === undefined) {return} + if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { if (thisObject.payload.uiObject.isShowing !== true) { @@ -609,6 +618,9 @@ function newFloatingObject() { } function drawForeground() { + if (thisObject.payload === undefined) {return} + if (thisObject.payload.uiObject === undefined) {return} + if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { if (thisObject.payload.uiObject.isShowing !== true) { @@ -619,6 +631,9 @@ function newFloatingObject() { } function drawOnFocus() { + if (thisObject.payload === undefined) {return} + if (thisObject.payload.uiObject === undefined) {return} + thisObject.payload.uiObject.drawOnFocus() } From adb0247cfd21b2089553f2b113242a104b7b40f8 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 20:24:35 +0200 Subject: [PATCH 127/192] Update CryptoEcosystemFunctions.js --- .../CryptoEcosystemFunctions.js | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index e67c29b25..544347a5e 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -321,7 +321,7 @@ function newCryptoEcosystemFunctions() { We make a copy of the array so that if we need to delete some nodes it does not affect the loop evaluating the nodes. */ - let sessionReferencesArray = [] + let sessionReferencesArray = [] for (let i = 0; i < exchangeSessions.sessionReferences.length; i++) { sessionReference = exchangeSessions.sessionReferences[i] sessionReferencesArray.push(sessionReference) @@ -358,10 +358,35 @@ function newCryptoEcosystemFunctions() { function installInChartingSpace(chartingSpace) { for (let i = 0; i < dashboardsArray.length; i++) { + /* + If the Dashboard we need is not already there we create a new one. + */ let arrayItem = dashboardsArray[i] let dashboard = findOrCreateChildWithReference(chartingSpace, 'Dashboard', arrayItem.environmentNode, functionLibraryUiObjectsFromNodes) dashboard.name = arrayItem.environmentNode.type + ' ' + arrayItem.networkNode.name - + /* + We delete all the existing Time Machines related to the market we are currently installing. + For that, we make a new array with the existing Time Machines so that the deleting + of each node does not affect the proccessing of the whole set. + */ + let timeMachines = [] + for (let i = 0; i < dashboard.timeMachines.length; i++) { + let timeMachine = dashboard.timeMachines[i] + timeMachines.push(timeMachine) + } + for (let i = 0; i < timeMachines.length; i++) { + let timeMachine = timeMachines[i] + let session = timeMachine.payload.referenceParent + if (session === undefined) {continue} + let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) + if (marketTradingTasks.payload.referenceParent === undefined) {continue} + if (marketTradingTasks.payload.referenceParent.id === market.id) { + functionLibraryNodeDeleter.deleteUIObject(timeMachine, rootNodes) + } + } + /* + We create a time machine for each session added during the previous processing. + */ for (let j = 0; j < arrayItem.sessionsArray.length; j++) { let session = arrayItem.sessionsArray[j] functionLibraryChartingSpaceFunctions.createTimeMachine(dashboard, session, node, arrayItem.networkNode, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) From b083ee89e1decebc449a491aed7f5c4ebe991529 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 20:41:08 +0200 Subject: [PATCH 128/192] Update FloatingLayer.js --- FloatingSpace/FloatingLayer.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index a17f10bf2..eaf64b132 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -207,6 +207,7 @@ function newFloatingLayer() { } function makeVisible() { + let newInvisibleArray = [] for (let i = 0; i < invisibleFloatingObjects.length; i++) { let floatingObject = invisibleFloatingObjects[i] @@ -214,14 +215,15 @@ function newFloatingLayer() { if (floatingObject.isParentCollapsed === false) { visibleFloatingObjects.push(floatingObject) - invisibleFloatingObjects.splice(i, 1) // Delete item from array. - makeVisible() - return // Only one at the time. + } else { + newInvisibleArray.push(floatingObject) } } + invisibleFloatingObjects = newInvisibleArray } function makeInvisible() { + let newVisibleArray = [] for (let i = 0; i < visibleFloatingObjects.length; i++) { let floatingObject = visibleFloatingObjects[i] @@ -229,11 +231,11 @@ function newFloatingLayer() { if (floatingObject.isParentCollapsed === true) { invisibleFloatingObjects.push(floatingObject) - visibleFloatingObjects.splice(i, 1) // Delete item from array. - makeInvisible() - return // Only one at the time. + } else { + newVisibleArray.push(floatingObject) } } + visibleFloatingObjects = newVisibleArray } /******************************************/ From e578d93c93a91d6c377ab162cd97c35eb3ea816f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Sep 2020 20:50:29 +0200 Subject: [PATCH 129/192] Bug Fixes --- .../FunctionLibraries/CryptoEcosystemFunctions.js | 14 ++++++++++++-- Utilities/Meshes.js | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index 544347a5e..f7503e608 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -377,9 +377,19 @@ function newCryptoEcosystemFunctions() { for (let i = 0; i < timeMachines.length; i++) { let timeMachine = timeMachines[i] let session = timeMachine.payload.referenceParent - if (session === undefined) {continue} + if (session === undefined) { + /* + This is what usually happens, that the intall process make these + time machines to lose their reference parent since the install + process deletes them. + */ + functionLibraryNodeDeleter.deleteUIObject(timeMachine, rootNodes) + continue + } let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) - if (marketTradingTasks.payload.referenceParent === undefined) {continue} + if (marketTradingTasks === undefined) {continue} + if (marketTradingTasks.payload === undefined) {continue} + if (marketTradingTasks.payload.referenceParent === undefined) { continue } if (marketTradingTasks.payload.referenceParent.id === market.id) { functionLibraryNodeDeleter.deleteUIObject(timeMachine, rootNodes) } diff --git a/Utilities/Meshes.js b/Utilities/Meshes.js index f0d474ff9..44144bf95 100644 --- a/Utilities/Meshes.js +++ b/Utilities/Meshes.js @@ -11,6 +11,7 @@ function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findI function scanNodeMesh(startingNode, depth) { if (startingNode === undefined) { return } + if (startingNode.payload === undefined) { return } if (nodeFound !== undefined) { return } if (depth >= MAX_DEPTH) {return} From 040b1a5c9fae619ae9b820314b52863a903966ef Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Sep 2020 09:23:52 +0200 Subject: [PATCH 130/192] Update FloatingLayer.js --- FloatingSpace/FloatingLayer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index eaf64b132..e5a2a52a1 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -63,7 +63,7 @@ function newFloatingLayer() { } function initialize() { - invisiblePhysicsIntervalId = setInterval(invisiblePhysics, 1000) + invisiblePhysicsIntervalId = setInterval(invisiblePhysics, 10000) } function getContainer(point) { From cb9b0ce904213e447f1379f6f863b83e6e0dabea Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Sep 2020 10:33:33 +0200 Subject: [PATCH 131/192] Refactoring --- .../CryptoEcosystemFunctions.js | 54 +++++++++---------- .../FunctionLibraries/DataStorageFunctions.js | 16 +++--- .../FunctionLibraries/TaskFunctions.js | 4 +- DesignSpace/Workspace/Workspace.js | 8 +-- Panels/Layer.js | 4 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index f7503e608..c5c2f3743 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -290,47 +290,47 @@ function newCryptoEcosystemFunctions() { dashboardsArray.push({ environmentNode: environmentFound, networkNode: networkNode, sessionsArray: allSessionsArray }) } /* - Here we complete the missing stuff at Session Independent Data + Here we complete the missing stuff at Data Mines Data */ - let sessionIndependentData = findInBranch(networkNode, 'Session Independent Data', node, true) - if (sessionIndependentData === undefined) { - node.payload.uiObject.setErrorMessage('Session Independent Data node not found at Network Node ' + networkNode.name) + let dataMinesData = findInBranch(networkNode, 'Data Mines Data', node, true) + if (dataMinesData === undefined) { + node.payload.uiObject.setErrorMessage('Data Mines Data node not found at Network Node ' + networkNode.name) return } - let exchangeDataProducts = findOrCreateChildWithReference(sessionIndependentData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) + let exchangeDataProducts = findOrCreateChildWithReference(dataMinesData, 'Exchange Data Products', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeDataProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - let singleMarketData = findAndRecreateChildWithReference(exchangeDataProducts, 'Single Market Data', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) - singleMarketData.payload.floatingObject.collapseToggle() + let marketDataProducts = findAndRecreateChildWithReference(exchangeDataProducts, 'Market Data Products', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + marketDataProducts.payload.floatingObject.collapseToggle() - menuClick(singleMarketData, 'Add All Data Mine Products', true) - menuClickOfNodeArray(singleMarketData.dataMineProducts, 'Add All Data Products', true) + menuClick(marketDataProducts, 'Add All Data Mine Products', true) + menuClickOfNodeArray(marketDataProducts.dataMineProducts, 'Add All Data Products', true) /* - Finally we complete the missing stuff at Session Based Data + Finally we complete the missing stuff at Trading Mines Data */ - let sessionBasedData = findInBranch(networkNode, 'Session Based Data', node, true) - if (sessionBasedData === undefined) { - node.payload.uiObject.setErrorMessage('Session Based Data node not found at Network Node ' + networkNode.name) + let tradingMinesData = findInBranch(networkNode, 'Trading Mines Data', node, true) + if (tradingMinesData === undefined) { + node.payload.uiObject.setErrorMessage('Trading Mines Data node not found at Network Node ' + networkNode.name) return } - let exchangeSessions = findOrCreateChildWithReference(sessionBasedData, 'Exchange Sessions', cryptoExchange, functionLibraryUiObjectsFromNodes) - exchangeSessions.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 + let exchangeTradingProducts = findOrCreateChildWithReference(tradingMinesData, 'Exchange Trading Products', cryptoExchange, functionLibraryUiObjectsFromNodes) + exchangeTradingProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 /* We need to delete all the session references related to the market we are installing. We make a copy of the array so that if we need to delete some nodes it does not affect the loop evaluating the nodes. */ let sessionReferencesArray = [] - for (let i = 0; i < exchangeSessions.sessionReferences.length; i++) { - sessionReference = exchangeSessions.sessionReferences[i] + for (let i = 0; i < exchangeTradingProducts.sessionReferences.length; i++) { + sessionReference = exchangeTradingProducts.sessionReferences[i] sessionReferencesArray.push(sessionReference) } for (let i = 0; i < sessionReferencesArray.length; i++) { sessionReference = sessionReferencesArray[i] - if (sessionReference.singleMarketTradingData === undefined) { continue } - if (sessionReference.singleMarketTradingData.payload.referenceParent === undefined) { continue } - if (sessionReference.singleMarketTradingData.payload.referenceParent.id === node.id) { + if (sessionReference.marketTradingProducts === undefined) { continue } + if (sessionReference.marketTradingProducts.payload.referenceParent === undefined) { continue } + if (sessionReference.marketTradingProducts.payload.referenceParent.id === node.id) { functionLibraryNodeDeleter.deleteUIObject(sessionReference, rootNodes) } } @@ -339,18 +339,18 @@ function newCryptoEcosystemFunctions() { */ for (let i = 0; i < sessionsCreatedArray.length; i++) { let session = sessionsCreatedArray[i] - if (isMissingChildren(exchangeSessions, session, true) === true) { - functionLibraryDataStorageFunctions.createSessionReference(exchangeSessions, session, functionLibraryUiObjectsFromNodes) + if (isMissingChildren(exchangeTradingProducts, session, true) === true) { + functionLibraryDataStorageFunctions.createSessionReference(exchangeTradingProducts, session, functionLibraryUiObjectsFromNodes) } } /* Create everything inside the session references. */ - for (let j = 0; j < exchangeSessions.sessionReferences.length; j++) { - sessionReference = exchangeSessions.sessionReferences[j] - menuClick(sessionReference.singleMarketTradingData, 'Add All Trading Mine Products', true) - menuClickOfNodeArray(sessionReference.singleMarketTradingData.tradingMineProducts, 'Add All Data Products', true) - sessionReference.singleMarketTradingData.payload.floatingObject.collapseToggle() + for (let j = 0; j < exchangeTradingProducts.sessionReferences.length; j++) { + sessionReference = exchangeTradingProducts.sessionReferences[j] + menuClick(sessionReference.marketTradingProducts, 'Add All Trading Mine Products', true) + menuClickOfNodeArray(sessionReference.marketTradingProducts.tradingMineProducts, 'Add All Data Products', true) + sessionReference.marketTradingProducts.payload.floatingObject.collapseToggle() } } } diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index 6b2ca9502..8c511bf62 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -4,8 +4,8 @@ function newDataStorageFunctions() { addAllDataMineProducts: addAllDataMineProducts, addAllTradingMineProducts: addAllTradingMineProducts, addMissingSessionReferences: addMissingSessionReferences, - addMissingSingleMarketData: addMissingSingleMarketData, - addMissingExchangeSessions: addMissingExchangeSessions, + addMissingMarketDataProducts: addMissingMarketDataProducts, + addMissingExchangeTradingProducts: addMissingExchangeTradingProducts, addMissingExchangeDataProducts: addMissingExchangeDataProducts, createSessionReference: createSessionReference } @@ -115,11 +115,11 @@ function newDataStorageFunctions() { where the Session was found. */ let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) - sessionReference.singleMarketTradingData.payload.referenceParent = marketTradingTasks.payload.referenceParent + sessionReference.marketTradingProducts.payload.referenceParent = marketTradingTasks.payload.referenceParent marketTradingTasks.payload.floatingObject.collapseToggle() } - function addMissingSingleMarketData(node, rootNodes, functionLibraryUiObjectsFromNodes) { + function addMissingMarketDataProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { if (node.payload.referenceParent === undefined) { return } if (node.payload.referenceParent.exchangeMarkets === undefined) { return } let marketsArray = node.payload.referenceParent.exchangeMarkets.markets @@ -127,14 +127,14 @@ function newDataStorageFunctions() { for (let i = 0; i < marketsArray.length; i++) { let market = marketsArray[i] if (isMissingChildren(node, market, true) === true) { - let singleMarketData = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Single Market Data') - singleMarketData.payload.referenceParent = market + let marketDataProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Market Data Products') + marketDataProducts.payload.referenceParent = market } } } - function addMissingExchangeSessions(node, rootNodes, functionLibraryUiObjectsFromNodes) { - addMissingExchange(node, rootNodes, 'Exchange Sessions', functionLibraryUiObjectsFromNodes) + function addMissingExchangeTradingProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingExchange(node, rootNodes, 'Exchange Trading Products', functionLibraryUiObjectsFromNodes) } function addMissingExchangeDataProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 626082b22..24b0c3687 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -91,8 +91,8 @@ function newTaskFunctions() { let taskDefinition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, taskLightingPath) let networkLightingPath = '->Network->Network Node->' + - 'Data Storage->Session Independent Data->Exchange Data Products->' + - 'Single Market Data->' + + 'Data Storage->Data Mines Data->Exchange Data Products->' + + 'Market Data Products->' + 'Data Mine Products->Bot Products->' + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Data Product->Product Definition->' + diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 1c8ed2df4..f8e57fec5 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -735,14 +735,14 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addMissingSessionReferences(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break - case 'Add Missing Single Market Data': + case 'Add Missing Market Data Products': { - functionLibraryDataStorageFunctions.addMissingSingleMarketData(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + functionLibraryDataStorageFunctions.addMissingMarketDataProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break - case 'Add Missing Exchange Sessions': + case 'Add Missing Exchange Trading Products': { - functionLibraryDataStorageFunctions.addMissingExchangeSessions(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + functionLibraryDataStorageFunctions.addMissingExchangeTradingProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break case 'Add Missing Exchange Data Products': diff --git a/Panels/Layer.js b/Panels/Layer.js index fb78668a3..191540e89 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -162,8 +162,8 @@ function newLayer() { 'Data Product->' + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Bot Products->Data Mine Products->Trading Mine Products->' + - 'Single Market Data->Single Market Trading Data->Exchange Data Products->' + - 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + + 'Market Data Products->Single Market Trading Data->Exchange Data Products->' + + 'Session Reference->Data Mines Data->Trading Mines Data->Exchange Trading Products->Trading Mines Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + 'Backtesting Session->Paper Trading Session->Forward Testing Session->Live Trading Session->' + 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + From 1daf5a583f2b9d96c8f594bb2bbb1b7c5335e670 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Sep 2020 12:51:09 +0200 Subject: [PATCH 132/192] Bug Fixes --- ChartingSpace/TimeMachine.js | 16 +++++++ .../ChartingSpaceFunctions.js | 2 +- .../CryptoEcosystemFunctions.js | 2 +- Panels/Layer.js | 5 ++- Spaces/ChartingSpace.js | 2 - Utilities/Meshes.js | 4 +- Utilities/NodeChildren.js | 42 +++++++++++++++++++ 7 files changed, 66 insertions(+), 7 deletions(-) diff --git a/ChartingSpace/TimeMachine.js b/ChartingSpace/TimeMachine.js index b9fa5471f..bcd25a4b2 100644 --- a/ChartingSpace/TimeMachine.js +++ b/ChartingSpace/TimeMachine.js @@ -142,6 +142,7 @@ function newTimeMachine() { function initialize(callBackFunction) { timeFrame = INITIAL_TIME_PERIOD loadFrame(thisObject.payload, thisObject.container.frame) + setInitialPosition() saveFrame(thisObject.payload, thisObject.container.frame) recalculateCoordinateSystem() @@ -158,6 +159,21 @@ function newTimeMachine() { callBackFunction() } + function setInitialPosition() { + let centerOfScreenX = browserCanvas.width / 2 - browserCanvas.width / TIME_MACHINE_WIDTH / 2 + let centerOfScreenY = browserCanvas.height / 2 - (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT / 2 + + if (thisObject.container.frame.position.x === 0 && thisObject.container.frame.position.y === 0) { + let timeMachineIndex = findChildIndexAtParentNode(thisObject.payload.node) + let dashboardIndex = findChildIndexAtParentNode(thisObject.payload.parentNode) + let timeMachinesCount = thisObject.payload.parentNode.timeMachines.length + let dashboardsCount = thisObject.payload.parentNode.payload.parentNode.dashboards.length + + thisObject.container.frame.position.x = centerOfScreenX + thisObject.container.frame.width * timeMachineIndex * 2 - timeMachinesCount * thisObject.container.frame.width + thisObject.container.frame.position.y = centerOfScreenY + thisObject.container.frame.height * dashboardIndex * 2 - dashboardsCount * thisObject.container.frame.height + } + } + function onKeyPressed(event) { thisObject.edgeEditor.onKeyPressed(event) } diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index 453752151..f58d93b0c 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -112,7 +112,7 @@ function newChartingSpaceFunctions() { let mineProducts let timeMachine = functionLibraryUiObjectsFromNodes.addUIObject(dashboard, 'Time Machine') timeMachine.payload.referenceParent = session - timeMachine.name = session.name + ' ' + session.type + timeMachine.name = session.name + ' ' + session.type + ' ' + networkNode.name timeMachine.payload.floatingObject.collapseToggle() timeMachine.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 /* diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index c5c2f3743..579d3a0c9 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -377,7 +377,7 @@ function newCryptoEcosystemFunctions() { for (let i = 0; i < timeMachines.length; i++) { let timeMachine = timeMachines[i] let session = timeMachine.payload.referenceParent - if (session === undefined) { + if (session === undefined || session.cleaned === true) { /* This is what usually happens, that the intall process make these time machines to lose their reference parent since the install diff --git a/Panels/Layer.js b/Panels/Layer.js index 191540e89..885280d3e 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -162,8 +162,9 @@ function newLayer() { 'Data Product->' + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Bot Products->Data Mine Products->Trading Mine Products->' + - 'Market Data Products->Single Market Trading Data->Exchange Data Products->' + - 'Session Reference->Data Mines Data->Trading Mines Data->Exchange Trading Products->Trading Mines Data->Data Storage->Network Node->' + + 'Market Data Products->Exchange Data Products->' + + 'Market Trading Products->Session Reference->Exchange Trading Products->' + + 'Data Mines Data->Trading Mines Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + 'Backtesting Session->Paper Trading Session->Forward Testing Session->Live Trading Session->' + 'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' + diff --git a/Spaces/ChartingSpace.js b/Spaces/ChartingSpace.js index f42e0c77c..6fcc122c5 100644 --- a/Spaces/ChartingSpace.js +++ b/Spaces/ChartingSpace.js @@ -345,8 +345,6 @@ function newChartingSpace() { timeMachine.payload.uiObject.setValue('Loading...') /* Setting up the new time machine. */ - timeMachine.container.frame.position.x = browserCanvas.width / 2 - browserCanvas.width / TIME_MACHINE_WIDTH / 2 - timeMachine.container.frame.position.y = browserCanvas.height / 2 - (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT / 2 timeMachine.initialize(onTimeMachineInitialized) function onTimeMachineInitialized() { diff --git a/Utilities/Meshes.js b/Utilities/Meshes.js index 44144bf95..834cb48e1 100644 --- a/Utilities/Meshes.js +++ b/Utilities/Meshes.js @@ -11,7 +11,9 @@ function findNodeInNodeMesh(node, nodeType, nodeName, connectedViaPayload, findI function scanNodeMesh(startingNode, depth) { if (startingNode === undefined) { return } - if (startingNode.payload === undefined) { return } + if (connectedViaPayload === true) { + if (startingNode.payload === undefined) { return } + } if (nodeFound !== undefined) { return } if (depth >= MAX_DEPTH) {return} diff --git a/Utilities/NodeChildren.js b/Utilities/NodeChildren.js index 43889d8df..5e59b2295 100644 --- a/Utilities/NodeChildren.js +++ b/Utilities/NodeChildren.js @@ -142,4 +142,46 @@ function findAndRecreateChildWithReference(startingNode, childType, referencedNo child = functionLibraryUiObjectsFromNodes.addUIObject(startingNode, childType) child.payload.referenceParent = referencedNode return child +} + +function findChildIndexAtParentNode(startingNode) { + /* + This functioin scan all the children of a node's parent and returns the child + index at the node property array that contains it. + */ + if (startingNode === undefined) { return } + if (startingNode.payload === undefined) { return } + if (startingNode.payload.parentNode === undefined) { return } + + let parentNode = startingNode.payload.parentNode + + let nodeDefinition = APP_SCHEMA_MAP.get(parentNode.type) + if (nodeDefinition === undefined) { return } + + /* We scan through this parent node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + /* We ignore these types of children. */ + } + break + case 'array': { + let startingNodePropertyArray = parentNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + let arrayItem = startingNodePropertyArray[m] + + if (arrayItem.id === startingNode.id) { + return m + } + } + } + break + } + } + } + } } \ No newline at end of file From 9bae5e2f116b34616d824589c48c2a851ac3da6e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Sep 2020 16:07:18 +0200 Subject: [PATCH 133/192] Session References enroqued --- .../FunctionLibraries/DataStorageFunctions.js | 21 ++++++++++++------- DesignSpace/Workspace/Workspace.js | 5 +++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js index 8c511bf62..3eb4e3822 100644 --- a/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/DataStorageFunctions.js @@ -5,6 +5,7 @@ function newDataStorageFunctions() { addAllTradingMineProducts: addAllTradingMineProducts, addMissingSessionReferences: addMissingSessionReferences, addMissingMarketDataProducts: addMissingMarketDataProducts, + addMissingMarketTradingProducts: addMissingMarketTradingProducts, addMissingExchangeTradingProducts: addMissingExchangeTradingProducts, addMissingExchangeDataProducts: addMissingExchangeDataProducts, createSessionReference: createSessionReference @@ -100,6 +101,9 @@ function newDataStorageFunctions() { function addMissingSession(sessionsArray) { for (let i = 0; i < sessionsArray.length; i++) { let session = sessionsArray[i] + /* We will filter out all the sessions that does not belong to the market we are in */ + let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) + if (node.payload.referenceParent.id !== marketTradingTasks.payload.referenceParent.id) { continue } if (isMissingChildren(node, session, true) === true) { createSessionReference(node, session, functionLibraryUiObjectsFromNodes) } @@ -110,16 +114,17 @@ function newDataStorageFunctions() { function createSessionReference(node, session, functionLibraryUiObjectsFromNodes) { let sessionReference = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Session Reference') sessionReference.payload.referenceParent = session - /* - Now I will connect the Session Reference child that is auto created with the market - where the Session was found. - */ - let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) - sessionReference.marketTradingProducts.payload.referenceParent = marketTradingTasks.payload.referenceParent - marketTradingTasks.payload.floatingObject.collapseToggle() } function addMissingMarketDataProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingMarketProducts(node, rootNodes, 'Market Data Products', functionLibraryUiObjectsFromNodes) + } + + function addMissingMarketTradingProducts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + addMissingMarketProducts(node, rootNodes, 'Market Trading Products', functionLibraryUiObjectsFromNodes) + } + + function addMissingMarketProducts(node, rootNodes, newNodeType, functionLibraryUiObjectsFromNodes) { if (node.payload.referenceParent === undefined) { return } if (node.payload.referenceParent.exchangeMarkets === undefined) { return } let marketsArray = node.payload.referenceParent.exchangeMarkets.markets @@ -127,7 +132,7 @@ function newDataStorageFunctions() { for (let i = 0; i < marketsArray.length; i++) { let market = marketsArray[i] if (isMissingChildren(node, market, true) === true) { - let marketDataProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Market Data Products') + let marketDataProducts = functionLibraryUiObjectsFromNodes.addUIObject(node, newNodeType) marketDataProducts.payload.referenceParent = market } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index f8e57fec5..78bd8024d 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -740,6 +740,11 @@ function newWorkspace() { functionLibraryDataStorageFunctions.addMissingMarketDataProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) } break + case 'Add Missing Market Trading Products': + { + functionLibraryDataStorageFunctions.addMissingMarketTradingProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break case 'Add Missing Exchange Trading Products': { functionLibraryDataStorageFunctions.addMissingExchangeTradingProducts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) From 89777a0aef1faf2cedbcf5c7663dd990075c0d15 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Sep 2020 16:44:54 +0200 Subject: [PATCH 134/192] Issues fixed --- .../ChartingSpaceFunctions.js | 3 +- .../CryptoEcosystemFunctions.js | 34 +++++-------------- Panels/Layer.js | 2 +- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js index f58d93b0c..ded2d034d 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/ChartingSpaceFunctions.js @@ -147,8 +147,7 @@ function newChartingSpaceFunctions() { that are not the one we are interested in, we do the following: */ if (mineProduct.payload.parentNode === undefined) { continue } - if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent === undefined) { continue } - if (mineProduct.payload.parentNode.payload.parentNode.payload.referenceParent.id !== session.id) { continue } + if (mineProduct.payload.parentNode.payload.referenceParent.id !== session.id) { continue } /* At the current version of Superalgos, beta 6, there is only one Trading Mine, with only one bot, and it has so many data products that we want to put them diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index 579d3a0c9..b010b2525 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -316,41 +316,25 @@ function newCryptoEcosystemFunctions() { let exchangeTradingProducts = findOrCreateChildWithReference(tradingMinesData, 'Exchange Trading Products', cryptoExchange, functionLibraryUiObjectsFromNodes) exchangeTradingProducts.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180 - /* - We need to delete all the session references related to the market we are installing. - We make a copy of the array so that if we need to delete some nodes it does not - affect the loop evaluating the nodes. - */ - let sessionReferencesArray = [] - for (let i = 0; i < exchangeTradingProducts.sessionReferences.length; i++) { - sessionReference = exchangeTradingProducts.sessionReferences[i] - sessionReferencesArray.push(sessionReference) - } - for (let i = 0; i < sessionReferencesArray.length; i++) { - sessionReference = sessionReferencesArray[i] - if (sessionReference.marketTradingProducts === undefined) { continue } - if (sessionReference.marketTradingProducts.payload.referenceParent === undefined) { continue } - if (sessionReference.marketTradingProducts.payload.referenceParent.id === node.id) { - functionLibraryNodeDeleter.deleteUIObject(sessionReference, rootNodes) - } - } + let marketTradingProducts = findAndRecreateChildWithReference(exchangeTradingProducts, 'Market Trading Products', market, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter) + marketTradingProducts.payload.floatingObject.collapseToggle() /* Create the new session references. */ for (let i = 0; i < sessionsCreatedArray.length; i++) { let session = sessionsCreatedArray[i] - if (isMissingChildren(exchangeTradingProducts, session, true) === true) { - functionLibraryDataStorageFunctions.createSessionReference(exchangeTradingProducts, session, functionLibraryUiObjectsFromNodes) + if (isMissingChildren(marketTradingProducts, session, true) === true) { + functionLibraryDataStorageFunctions.createSessionReference(marketTradingProducts, session, functionLibraryUiObjectsFromNodes) } } /* Create everything inside the session references. */ - for (let j = 0; j < exchangeTradingProducts.sessionReferences.length; j++) { - sessionReference = exchangeTradingProducts.sessionReferences[j] - menuClick(sessionReference.marketTradingProducts, 'Add All Trading Mine Products', true) - menuClickOfNodeArray(sessionReference.marketTradingProducts.tradingMineProducts, 'Add All Data Products', true) - sessionReference.marketTradingProducts.payload.floatingObject.collapseToggle() + for (let j = 0; j < marketTradingProducts.sessionReferences.length; j++) { + sessionReference = marketTradingProducts.sessionReferences[j] + menuClick(sessionReference, 'Add All Trading Mine Products', true) + menuClickOfNodeArray(sessionReference.tradingMineProducts, 'Add All Data Products', true) + sessionReference.payload.floatingObject.collapseToggle() } } } diff --git a/Panels/Layer.js b/Panels/Layer.js index 885280d3e..db36f4226 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -163,7 +163,7 @@ function newLayer() { 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + 'Bot Products->Data Mine Products->Trading Mine Products->' + 'Market Data Products->Exchange Data Products->' + - 'Market Trading Products->Session Reference->Exchange Trading Products->' + + 'Session Reference->Market Trading Products->Exchange Trading Products->' + 'Data Mines Data->Trading Mines Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + 'Backtesting Session->Paper Trading Session->Forward Testing Session->Live Trading Session->' + From 3f8e71b0f28ff5808b7a6d40a18b976e1f07799c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Sep 2020 18:27:06 +0200 Subject: [PATCH 135/192] Unistall --- ChartingSpace/TimeMachine.js | 10 +-- .../CryptoEcosystemFunctions.js | 69 ++++++++++++++++++- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/ChartingSpace/TimeMachine.js b/ChartingSpace/TimeMachine.js index bcd25a4b2..5ca3031da 100644 --- a/ChartingSpace/TimeMachine.js +++ b/ChartingSpace/TimeMachine.js @@ -160,17 +160,13 @@ function newTimeMachine() { } function setInitialPosition() { - let centerOfScreenX = browserCanvas.width / 2 - browserCanvas.width / TIME_MACHINE_WIDTH / 2 - let centerOfScreenY = browserCanvas.height / 2 - (browserCanvas.height - TOP_SPACE_HEIGHT - COCKPIT_SPACE_HEIGHT) / TIME_MACHINE_HEIGHT / 2 - + if (thisObject.container.frame.position.x === 0 && thisObject.container.frame.position.y === 0) { let timeMachineIndex = findChildIndexAtParentNode(thisObject.payload.node) let dashboardIndex = findChildIndexAtParentNode(thisObject.payload.parentNode) - let timeMachinesCount = thisObject.payload.parentNode.timeMachines.length - let dashboardsCount = thisObject.payload.parentNode.payload.parentNode.dashboards.length - thisObject.container.frame.position.x = centerOfScreenX + thisObject.container.frame.width * timeMachineIndex * 2 - timeMachinesCount * thisObject.container.frame.width - thisObject.container.frame.position.y = centerOfScreenY + thisObject.container.frame.height * dashboardIndex * 2 - dashboardsCount * thisObject.container.frame.height + thisObject.container.frame.position.x = thisObject.container.frame.width * timeMachineIndex * 2 + thisObject.container.frame.position.y = thisObject.container.frame.height * dashboardIndex * 2 } } diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index b010b2525..3641b3df9 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -371,8 +371,8 @@ function newCryptoEcosystemFunctions() { continue } let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) - if (marketTradingTasks === undefined) {continue} - if (marketTradingTasks.payload === undefined) {continue} + if (marketTradingTasks === undefined) { continue } + if (marketTradingTasks.payload === undefined) { continue } if (marketTradingTasks.payload.referenceParent === undefined) { continue } if (marketTradingTasks.payload.referenceParent.id === market.id) { functionLibraryNodeDeleter.deleteUIObject(timeMachine, rootNodes) @@ -390,6 +390,71 @@ function newCryptoEcosystemFunctions() { } function uninstallMarket(node, rootNodes, functionLibraryUiObjectsFromNodes, functionLibraryNodeDeleter, functionLibraryChartingSpaceFunctions, functionLibraryDataStorageFunctions) { + let market = node + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Charting Space') { + uninstallInChartingSpace(rootNode) + } + } + function uninstallInChartingSpace(chartingSpace) { + + /* Delete all time machines which are referencing sessions inside the market being unistalled. */ + let timeMachines = nodeBranchToArray(chartingSpace, 'Time Machine') + for (let i = 0; i < timeMachines.length; i++) { + let timeMachine = timeMachines[i] + let session = timeMachine.payload.referenceParent + if (session === undefined) { continue } + let marketTradingTasks = findNodeInNodeMesh(session, 'Market Trading Tasks', undefined, true, false, true, false) + if (marketTradingTasks === undefined) { continue } + if (marketTradingTasks.payload === undefined) { continue } + if (marketTradingTasks.payload.referenceParent === undefined) { continue } + if (marketTradingTasks.payload.referenceParent.id === market.id) { + functionLibraryNodeDeleter.deleteUIObject(timeMachine, rootNodes) + } + } + + /* Delete all Dashboards that does not have time machines inside. */ + let dashboardArray = nodeBranchToArray(chartingSpace, 'Dashboard') + for (let i = 0; i < dashboardArray.length; i++) { + let dashboard = dashboardArray[i] + if (dashboard.timeMachines.length === 0) { + functionLibraryNodeDeleter.deleteUIObject(dashboard, rootNodes) + } + } + + /* Scan Networks for the market being unistalled to delete it. */ + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === 'Network') { + uninstallInNetwork(rootNode) + } + } + } + + function uninstallInNetwork(network) { + + let marketDataTasksArray = nodeBranchToArray(network, 'Market Data Tasks') + let marketTradingTasksArray = nodeBranchToArray(network, 'Market Trading Tasks') + let marketDataProductsArray = nodeBranchToArray(network, 'Market Data Products') + let marketTradingProductsArray = nodeBranchToArray(network, 'Market Trading Products') + + uninstalMarketArray(marketDataTasksArray) + uninstalMarketArray(marketTradingTasksArray) + uninstalMarketArray(marketDataProductsArray) + uninstalMarketArray(marketTradingProductsArray) + + function uninstalMarketArray(marketArray) { + for (let i = 0; i < marketArray.length; i++) { + let marketReference = marketArray[i] + if (marketReference.payload === undefined) { continue } + if (marketReference.payload.referenceParent === undefined) { continue } + if (marketReference.payload.referenceParent.id === market.id) { + functionLibraryNodeDeleter.deleteUIObject(marketReference, rootNodes) + } + } + } + } } } From f8e81c5e3aa6d132b15b5149557737c666b7eea2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 18 Sep 2020 15:31:08 +0200 Subject: [PATCH 136/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index e21a2eebd..76863cd51 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -328,6 +328,7 @@ function newTutorialSpace() { } function done() { + if (ckeckGoingToAnotherTutorial() === true ) {return} let tutorial = { status: 'Done' } @@ -335,6 +336,16 @@ function newTutorialSpace() { advance() } + function ckeckGoingToAnotherTutorial() { + if (currentNode.payload !== undefined) { + if (currentNode.payload.referenceParent !== undefined) { + if (currentNode.payload.referenceParent.type === 'Tutorial') { + playTutorial(currentNode.payload.referenceParent) + } + } + } + } + function playTutorialTopic(node) { currentTopicNode = node currentNode = node @@ -446,7 +457,6 @@ function newTutorialSpace() { } function findNextNode(node) { - for (let i = 0; i < node.tutorialSteps.length; i++) { let tutorialStep = node.tutorialSteps[i] @@ -519,6 +529,10 @@ function newTutorialSpace() { let html = '' if (nodeConfig.title !== undefined && nodeConfig.title !== '') { html = html + '

' + nodeConfig.title + '

' + } else { + if (currentNode.name !== 'New ' + currentNode.type) { + html = html + '

' + currentNode.name + '

' + } } html = html + '
' if (nodeConfig.summary !== undefined && nodeConfig.summary !== '') { @@ -554,7 +568,7 @@ function newTutorialSpace() { for (let i = 0; i < nodeConfig.bulletArray.length; i++) { let bullet = nodeConfig.bulletArray[i] html = html + '
  • ' - html = html + '

    ' + bullet[0] + ': ' + bullet[1] + '

    ' + html = html + '

    ' + bullet[0] + ' ' + bullet[1] + '

    ' html = html + '
  • ' } html = html + '' From de27a44a4c69253404e02de56b8b89cf3831610f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 18 Sep 2020 19:51:10 +0200 Subject: [PATCH 137/192] Includes --- .../FunctionLibraries/IncludesFunctions.js | 84 +++++++++++++++++++ .../FunctionLibraries/UiObjectsFromNodes.js | 2 +- DesignSpace/Workspace/Workspace.js | 31 +++++++ FloatingSpace/UiObjectTitle.js | 8 ++ Utilities/NodeChildren.js | 41 +++++++++ 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 DesignSpace/Workspace/FunctionLibraries/IncludesFunctions.js diff --git a/DesignSpace/Workspace/FunctionLibraries/IncludesFunctions.js b/DesignSpace/Workspace/FunctionLibraries/IncludesFunctions.js new file mode 100644 index 000000000..10d5f54a4 --- /dev/null +++ b/DesignSpace/Workspace/FunctionLibraries/IncludesFunctions.js @@ -0,0 +1,84 @@ +function newIncludesFunctions() { + thisObject = { + includeMissingDataMines: includeMissingDataMines, + includeMissingTradingMines: includeMissingTradingMines, + includeMissingTradingSystems: includeMissingTradingSystems, + includeMissingTradingEngines: includeMissingTradingEngines, + includeMissingSuperScripts: includeMissingSuperScripts, + includeMissingTutorials: includeMissingTutorials + } + return thisObject + + function getIncludedFileNames(includeType, callBack) { + callServer(undefined, 'IncludedFileNames/' + includeType, onResponse) + + function onResponse(err, data) { + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('Failed to Fetch Included ' + includeType + ' from the Backend') + return + } + + let includedFileNames = JSON.parse(data) + callBack(includedFileNames) + } + } + + function addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) { + for (let i = 0; i < fileNames.length; i++) { + let fileName = fileNames[i] + fileName = fileName.replace('.json', '') + if (isMissingChildrenByName(node, fileName) === true) { + let child = functionLibraryUiObjectsFromNodes.addUIObject(node, 'Included File') + child.name = fileName + } + } + } + + function includeMissingDataMines(node, rootNodes, functionLibraryUiObjectsFromNodes) { + getIncludedFileNames('Data-Mines', onNamesArrived) + + function onNamesArrived(fileNames) { + addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) + } + } + + function includeMissingTradingMines(node, rootNodes, functionLibraryUiObjectsFromNodes) { + getIncludedFileNames('Trading-Mines', onNamesArrived) + + function onNamesArrived(fileNames) { + addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) + } + } + + function includeMissingTradingSystems(node, rootNodes, functionLibraryUiObjectsFromNodes) { + getIncludedFileNames('Trading-Systems', onNamesArrived) + + function onNamesArrived(fileNames) { + addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) + } + } + + function includeMissingTradingEngines(node, rootNodes, functionLibraryUiObjectsFromNodes) { + getIncludedFileNames('Trading-Engines', onNamesArrived) + + function onNamesArrived(fileNames) { + addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) + } + } + + function includeMissingSuperScripts(node, rootNodes, functionLibraryUiObjectsFromNodes) { + getIncludedFileNames('Super-Scripts', onNamesArrived) + + function onNamesArrived(fileNames) { + addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) + } + } + + function includeMissingTutorials(node, rootNodes, functionLibraryUiObjectsFromNodes) { + getIncludedFileNames('Tutorials', onNamesArrived) + + function onNamesArrived(fileNames) { + addIncludedFileIfNeeded(node, fileNames, functionLibraryUiObjectsFromNodes) + } + } +} diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 2a7e86a28..38ded860c 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -47,7 +47,7 @@ function newUiObjectsFromNodes() { function onResponse(err, data) { if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Failed to Fetch Inclided Names from the Backend') + console.log('Failed to Fetch Included Names from the Backend') return } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 78bd8024d..cea402cf2 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -70,6 +70,7 @@ function newWorkspace() { let functionLibraryDataStorageFunctions = newDataStorageFunctions() let functionLibraryChartingSpaceFunctions = newChartingSpaceFunctions() let functionLibraryTutorialFunctions = newTutorialFunctions() + let functionLibraryIncludesFunctions = newIncludesFunctions() thisObject.nodeChildren = newNodeChildren() @@ -879,6 +880,36 @@ function newWorkspace() { } } break + case 'Include Missing Data Mines': + { + functionLibraryIncludesFunctions.includeMissingDataMines(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Include Missing Trading Mines': + { + functionLibraryIncludesFunctions.includeMissingTradingMines(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Include Missing Trading Systems': + { + functionLibraryIncludesFunctions.includeMissingTradingSystems(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Include Missing Trading Engines': + { + functionLibraryIncludesFunctions.includeMissingTradingEngines(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Include Missing Super Scripts': + { + functionLibraryIncludesFunctions.includeMissingSuperScripts(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break + case 'Include Missing Tutorials': + { + functionLibraryIncludesFunctions.includeMissingTutorials(payload.node, thisObject.workspaceNode.rootNodes, functionLibraryUiObjectsFromNodes) + } + break } } } diff --git a/FloatingSpace/UiObjectTitle.js b/FloatingSpace/UiObjectTitle.js index c1438e11e..c7ea3990d 100644 --- a/FloatingSpace/UiObjectTitle.js +++ b/FloatingSpace/UiObjectTitle.js @@ -108,6 +108,14 @@ function newUiObjectTitle() { for (let i = 0; i < nodeDefinition.title.length; i++) { let titleReference = nodeDefinition.title[i] switch (titleReference) { + case 'Use Parent': { + let nodeToUse = thisObject.payload.parentNode + if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { + thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title + thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name + } + break + } case 'Use Reference Parent': { let nodeToUse = thisObject.payload.node.payload.referenceParent if (nodeToUse !== undefined && nodeToUse.payload !== undefined) { diff --git a/Utilities/NodeChildren.js b/Utilities/NodeChildren.js index 5e59b2295..ad36f93eb 100644 --- a/Utilities/NodeChildren.js +++ b/Utilities/NodeChildren.js @@ -184,4 +184,45 @@ function findChildIndexAtParentNode(startingNode) { } } } +} + +function isMissingChildrenByName(startingNode, nodeName) { + /* + This functioin scan all the children of a node and returns true or false + depending if the node has a children with a certain name. + */ + if (startingNode === undefined) { return } + + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + /* We scan through this node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + let child = startingNode[property.name] + if (child.name === nodeName) { + return false + } + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + let arrayItem = startingNodePropertyArray[m] + if (arrayItem.name === nodeName) { + return false + } + } + } + break + } + } + } + return true + } } \ No newline at end of file From 24f06d8f44fe1c7ca77a1c94701811feab6969bc Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 19 Sep 2020 11:58:54 +0200 Subject: [PATCH 138/192] Update UiObjectsFromNodes.js --- .../FunctionLibraries/UiObjectsFromNodes.js | 219 ++++++------------ 1 file changed, 75 insertions(+), 144 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 38ded860c..d9b05f2dd 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -39,171 +39,91 @@ function newUiObjectsFromNodes() { } } - getIncludedNames() - - function getIncludedNames() { - - callServer(undefined, 'IncludedNames', onResponse) - - function onResponse(err, data) { - if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Failed to Fetch Included Names from the Backend') - return - } - - let includedNames = JSON.parse(data) - addIncludedNodes(includedNames) - } - } + addIncludedNodes() function addIncludedNodes(includedNames) { let blobService = newFileStorage() - let includedDataMines = includedNames.includedDataMines - let includedTradingMines = includedNames.includedTradingMines - let includedTradingSystems = includedNames.includedTradingSystems - let includedSuperScripts = includedNames.includedSuperScripts - let includedTradingEngines = includedNames.includedTradingEngines - let totalIncluded = 0 + let totalRead = 0 - for (let i = 0; i < includedDataMines.length; i++) { - let name = includedDataMines[i] - blobService.getFileFromHost('DataMines' + '/' + name, onFileReceived, true) - function onFileReceived(err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.') - return + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.type === 'Includes') { + let includes = rootNode + if (includes.includedDataMines !== undefined) { + totalIncluded = totalIncluded + includes.includedDataMines.includedFiles.length + includeAllTheseFiles(includes.includedDataMines.includedFiles, 'Data-Mines') } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Data Mine') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { - rootNodes.splice(i, 1) - } - } - } + if (includes.includedTradingMines !== undefined) { + totalIncluded = totalIncluded + includes.includedTradingMines.includedFiles.length + includeAllTheseFiles(includes.includedTradingMines.includedFiles, 'Trading-Mines') } - receivedNode.isIncluded = true - node.rootNodes.unshift(receivedNode) - totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { - addUserDefinedNodes() + if (includes.includedTradingSystems !== undefined) { + totalIncluded = totalIncluded + includes.includedTradingSystems.includedFiles.length + includeAllTheseFiles(includes.includedTradingSystems.includedFiles, 'Trading-Systems') + } + if (includes.includedTradingEngines !== undefined) { + totalIncluded = totalIncluded + includes.includedTradingEngines.includedFiles.length + includeAllTheseFiles(includes.includedTradingEngines.includedFiles, 'Trading-Engines') + } + if (includes.includedSuperScripts !== undefined) { + totalIncluded = totalIncluded + includes.includedSuperScripts.includedFiles.length + includeAllTheseFiles(includes.includedSuperScripts.includedFiles, 'Super-Scripts') + } + if (includes.includedTutorials !== undefined) { + totalIncluded = totalIncluded + includes.includedTutorials.includedFiles.length + includeAllTheseFiles(includes.includedTutorials.includedFiles, 'Tutorials') } } } - for (let i = 0; i < includedTradingMines.length; i++) { - let name = includedTradingMines[i] - blobService.getFileFromHost('TradingMines' + '/' + name, onFileReceived, true) - function onFileReceived(err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Trading Mine ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Trading Mine') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { - rootNodes.splice(i, 1) - } - } - } - } - receivedNode.isIncluded = true - node.rootNodes.unshift(receivedNode) - totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { - addUserDefinedNodes() - } - } + /* + If there is no Includes node at the workspace, we load it anyways here. + */ + if (totalIncluded === 0) { + addUserDefinedNodes() } - for (let i = 0; i < includedTradingSystems.length; i++) { - let name = includedTradingSystems[i] - blobService.getFileFromHost('TradingSystems' + '/' + name, onFileReceived, true) - function onFileReceived(err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Trading System ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Trading System') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { + function includeAllTheseFiles(includedFiles, includedType) { + for (let i = 0; i < includedFiles.length; i++) { + let includedFile = includedFiles[i] + let name = includedFile.name + blobService.getFileFromHost(includedType + '/' + name + '.json', onFileReceived, true) + + function onFileReceived(err, text, response) { + + if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + console.log('[WARN] Cannot load included ' + includedType + ' ' + name + '. The workspace will be loaded with this included file missing.') + } else { + let receivedNode = JSON.parse(text) + /* + If the workspace already contains a root node with the id of the head of the hirierchy + we are loading, we remove it because the included file has precedende. + */ + for (let i = 0; i < node.rootNodes.length; i++) { + let rootNode = node.rootNodes[i] + if (rootNode.id === receivedNode.id) { rootNodes.splice(i, 1) + break } } - } - } - receivedNode.isIncluded = true - node.rootNodes.unshift(receivedNode) - totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { - addUserDefinedNodes() - } - } - } + receivedNode.isIncluded = true - for (let i = 0; i < includedSuperScripts.length; i++) { - let name = includedSuperScripts[i] - blobService.getFileFromHost('SuperScripts' + '/' + name, onFileReceived, true) - function onFileReceived(err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Super Script ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Super Scripts') { - if (rootNode.config !== undefined) { - let config = JSON.parse(rootNode.config) - if (config.name === name) { - rootNodes.splice(i, 1) + if (includedFile.includedFilePosition !== undefined) { + let positionOffset = { + x: includedFile.includedFilePosition.savedPayload.position.x - receivedNode.savedPayload.position.x, + y: includedFile.includedFilePosition.savedPayload.position.y - receivedNode.savedPayload.position.y } + receivedNode.positionOffset = positionOffset } - } - } - receivedNode.isIncluded = true - node.rootNodes.unshift(receivedNode) - totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { - addUserDefinedNodes() - } - } - } - for (let i = 0; i < includedTradingEngines.length; i++) { - let name = includedTradingEngines[i] - blobService.getFileFromHost('TradingEngines' + '/' + name, onFileReceived, true) - function onFileReceived(err, text, response) { - if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - console.log('Cannot load included Trading Engine ' + name + '. The workspace can not be loaded.') - return - } - let receivedNode = JSON.parse(text) - for (let i = 0; i < node.rootNodes.length; i++) { - let rootNode = node.rootNodes[i] - if (rootNode.type === 'Trading Engine') { - if (rootNode.name === name) { - rootNodes.splice(i, 1) - } + node.rootNodes.unshift(receivedNode) + } + + totalRead++ + if (totalIncluded === totalRead) { + addUserDefinedNodes() } - } - receivedNode.isIncluded = true - node.rootNodes.unshift(receivedNode) - totalIncluded++ - if (totalIncluded === includedDataMines.length + includedTradingSystems.length + includedSuperScripts.length + includedTradingEngines.length + includedTradingMines.length) { - addUserDefinedNodes() } } } @@ -294,6 +214,17 @@ function newUiObjectsFromNodes() { } */ + /* + This function can be called with a positionOffset to change the node + saved position and all of its descendants positions as well with an + offset. It can also happen that the positionOffset is defined as a property + of the node, in which case it will produce exactly the same effect. + */ + if (node.positionOffset !== undefined) { + positionOffset = node.positionOffset + } + + /* Get node definition */ let nodeDefinition = getNodeDefinition(node) if (nodeDefinition !== undefined) { From a762d7bafef6c8a4b515b4de1474c94d3d359ec2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 09:36:22 +0200 Subject: [PATCH 139/192] Update Workspace.js --- DesignSpace/Workspace/Workspace.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index cea402cf2..b40efe538 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -186,6 +186,14 @@ function newWorkspace() { /* Validation if it is too early to save. */ if (isInitialized === false) { return } + /* Validation of that the user changed the workspace name at least once. */ + if (workspace.name === 'Default') { + canvas.cockpitSpace.setStatus( + 'Could not save the Workspace. Please rename the Workspace so that it can be saved.' + , 150, canvas.cockpitSpace.statusTypes.WARNING) + return + } + /* Validation of 2 sessions opened at the same time. */ let savedSessionTimestamp = window.localStorage.getItem('Session Timestamp') if (Number(savedSessionTimestamp) !== sessionTimestamp) { From 12754e3a39b13d8f1c417673e4fa75eafe881aa0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 10:19:07 +0200 Subject: [PATCH 140/192] Update Workspace.js --- DesignSpace/Workspace/Workspace.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index b40efe538..037ef7c05 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -411,8 +411,17 @@ function newWorkspace() { } function replaceWorkspaceByLoadingOne(name) { - let blobService = newFileStorage() - blobService.getFileFromHost('LoadWorkspace' + '/' + name, onFileReceived, true) + + let webCommand + if (name.indexOf('Included -> ' >= 0)) { + name = name.replace('Included -> ', '') + webCommand = 'LoadIncludedWorkspace' + } else { + webCommand = 'LoadWorkspace' + } + + let blobService = newFileStorage() + blobService.getFileFromHost(webCommand + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { canvas.cockpitSpace.setStatus('Could not load the Workspace called "' + name + '". ', 500, canvas.cockpitSpace.statusTypes.WARNING) From bbdab16eab9f5d576a2486fe6c393cd41d0194bb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 10:58:08 +0200 Subject: [PATCH 141/192] Bug fixed --- DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js | 4 ++-- DesignSpace/Workspace/Workspace.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index d9b05f2dd..5bf1c7389 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -174,7 +174,7 @@ function newUiObjectsFromNodes() { if (node.payload.referenceParent.cleaned === true) { node.payload.referenceParent = mapOfNodes.get(node.payload.referenceParent.id) if (node.payload.referenceParent === undefined) { - console.log(node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') + //console.log('[WARN]' + node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') } continue // We were referencing a deleted node, so we replace it potentially with a newly created one. } else { @@ -185,7 +185,7 @@ function newUiObjectsFromNodes() { if (node.savedPayload.referenceParent !== undefined) { // these are children recreated node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) if (node.payload.referenceParent === undefined) { - console.log(node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') + //console.log('[WARN]' + node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') } } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 037ef7c05..0701507c5 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -413,7 +413,7 @@ function newWorkspace() { function replaceWorkspaceByLoadingOne(name) { let webCommand - if (name.indexOf('Included -> ' >= 0)) { + if (name.indexOf('Included -> ') >= 0) { name = name.replace('Included -> ', '') webCommand = 'LoadIncludedWorkspace' } else { From 6f5ab3a3abedf9740211be8ecef6163d9261addf Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 13:23:25 +0200 Subject: [PATCH 142/192] Tutorial Auto Starts --- .../FunctionLibraries/NodeCloning.js | 1 + .../FunctionLibraries/ProtocolNode.js | 1 + .../FunctionLibraries/UiObjectsFromNodes.js | 22 +++++++++++++++++++ DesignSpace/Workspace/Workspace.js | 8 +++++-- FloatingSpace/UiObject.js | 1 + Spaces/TutorialSpace.js | 3 +++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js b/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js index 9d5f920aa..d0f91677a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js +++ b/DesignSpace/Workspace/FunctionLibraries/NodeCloning.js @@ -152,6 +152,7 @@ function newNodeCloning() { arrangementStyle: (node.payload.floatingObject.arrangementStyle) }, uiObject: { + isPlaying: node.payload.uiObject.isPlaying, isRunning: node.payload.uiObject.isRunning, shortcutKey: node.payload.uiObject.shortcutKey } diff --git a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js index 2e5803fa6..04c7bf1cb 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -162,6 +162,7 @@ function newProtocolNode() { arrangementStyle: (node.payload.floatingObject.arrangementStyle) }, uiObject: { + isPlaying: node.payload.uiObject.isPlaying, isRunning: node.payload.uiObject.isRunning, shortcutKey: node.payload.uiObject.shortcutKey } diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 5bf1c7389..c3f52c5a9 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -2,6 +2,7 @@ function newUiObjectsFromNodes() { thisObject = { runTasks: runTasks, runSessions: runSessions, + playTutorials: playTutorials, recreateWorkspace: recreateWorkspace, getNodeById: getNodeById, tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents, @@ -14,6 +15,7 @@ function newUiObjectsFromNodes() { let mapOfNodes let tasksToRun let sessionsToRun + let tutorialsToPlay return thisObject @@ -25,6 +27,7 @@ function newUiObjectsFromNodes() { mapOfNodes = new Map() tasksToRun = [] sessionsToRun = [] + tutorialsToPlay = [] removeNullRootNodes() @@ -163,6 +166,14 @@ function newUiObjectsFromNodes() { sessionsToRun = undefined } + function playTutorials() { + for (let i = 0; i < tutorialsToPlay.length; i++) { + let node = tutorialsToPlay[i] + node.payload.uiObject.menu.internalClick('Play Tutorial') + } + tutorialsToPlay = undefined + } + function tryToConnectChildrenWithReferenceParents() { /* We reconstruct here the reference relationships. */ for (const [key, node] of mapOfNodes) { @@ -637,5 +648,16 @@ function newUiObjectsFromNodes() { } } } + + /* Check if there are tutorials to play */ + if (userAddingNew === false && node.savedPayload !== undefined) { + if (uiObjectType === 'Tutorial') { + if (node.savedPayload.uiObject.isPlaying === true) { + if (tutorialsToPlay !== undefined) { // it might be undefined when you are spawning a tutorial that was playing while backed up + tutorialsToPlay.push(node) + } + } + } + } } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 0701507c5..bdf92afb8 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -140,10 +140,14 @@ function newWorkspace() { setTimeout(functionLibraryUiObjectsFromNodes.runTasks, 70000) // We give a few seconds for the tasks to start setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 80000) + // We give a few seconds + setTimeout(functionLibraryUiObjectsFromNodes.playTutorials, 3000) } else { functionLibraryUiObjectsFromNodes.runTasks() // We give a few seconds for the tasks to start setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 10000) + // We give a few seconds + setTimeout(functionLibraryUiObjectsFromNodes.playTutorials, 1000) } } @@ -412,7 +416,7 @@ function newWorkspace() { function replaceWorkspaceByLoadingOne(name) { - let webCommand + let webCommand if (name.indexOf('Included -> ') >= 0) { name = name.replace('Included -> ', '') webCommand = 'LoadIncludedWorkspace' @@ -420,7 +424,7 @@ function newWorkspace() { webCommand = 'LoadWorkspace' } - let blobService = newFileStorage() + let blobService = newFileStorage() blobService.getFileFromHost(webCommand + '/' + name, onFileReceived, true) function onFileReceived(err, text, response) { if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 3dab07426..e492442f9 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -21,6 +21,7 @@ function newUiObject() { uiObjectTitle: undefined, circularProgressBar: undefined, isRunning: undefined, + isPlaying: undefined, shortcutKey: undefined, isShowing: undefined, hasError: undefined, diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 76863cd51..e2e25e3ba 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -300,6 +300,7 @@ function newTutorialSpace() { } function playTutorial(node) { + node.payload.uiObject.isPlaying = true tutorialRootNode = node currentNode = node currentStatus = 'Playing Tutorial' @@ -307,6 +308,7 @@ function newTutorialSpace() { } function resumeTutorial(node) { + node.payload.uiObject.isPlaying = true tutorialRootNode = node currentNode = node currentStatus = 'Playing Tutorial' @@ -315,6 +317,7 @@ function newTutorialSpace() { } function stop() { + tutorialRootNode.payload.uiObject.isPlaying = false tutorialRootNode = undefined currentStatus = 'Stopped' } From e44781ea98fd7c6a3b883938e8e43bdc3b83b362 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 15:58:03 +0200 Subject: [PATCH 143/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 110 ++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 26 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index e2e25e3ba..67fb7cb99 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -3,7 +3,8 @@ function newTutorialSpace() { let thisObject = { stop: stop, skip: skip, - done: done, + previous: previous, + next: next, playTutorial: playTutorial, resumeTutorial: resumeTutorial, playTutorialTopic: playTutorialTopic, @@ -36,6 +37,7 @@ function newTutorialSpace() { let tutorialRootNode let currentNode let currentStatus = 'Stopped' + let navigationStack let tutorialDiv = document.getElementById('tutorialDiv') let tutorialFormDiv = document.getElementById('tutorialFormDiv') @@ -63,6 +65,7 @@ function newTutorialSpace() { tutorialRootNode = undefined currentNode = undefined + navigationStack = undefined tutorialDiv = undefined tutorialFormDiv = undefined @@ -293,29 +296,12 @@ function newTutorialSpace() { tutorialFormDiv.style = ' ' + 'position:fixed; top:' + (tutorialPosition.y + HEIGHT - FORM_HEIGHT) + 'px; ' + 'left:' + tutorialPosition.x + 'px; ' + - 'width: ' + WIDTH + 'px;' + + 'width: ' + (WIDTH + 20) + 'px;' + 'height: ' + FORM_HEIGHT + 'px;' + 'z-index:1;' } } - function playTutorial(node) { - node.payload.uiObject.isPlaying = true - tutorialRootNode = node - currentNode = node - currentStatus = 'Playing Tutorial' - resumeModeActivated = false - } - - function resumeTutorial(node) { - node.payload.uiObject.isPlaying = true - tutorialRootNode = node - currentNode = node - currentStatus = 'Playing Tutorial' - resumeModeActivated = true - advance() - } - function stop() { tutorialRootNode.payload.uiObject.isPlaying = false tutorialRootNode = undefined @@ -330,8 +316,37 @@ function newTutorialSpace() { advance() } - function done() { - if (ckeckGoingToAnotherTutorial() === true ) {return} + function previous() { + if (navigationStack.length > 1) { + let previousNode = navigationStack[navigationStack.length - 2] + switch (previousNode.type) { + case 'Tutorial': { + currentNode = previousNode + findTutorialNode(currentNode) + currentStatus = 'Playing Tutorial' + navigationStack.splice(navigationStack.length - 1) + break + } + case 'Tutorial Topic': { + currentNode = previousNode + findTutorialNode(currentNode) + currentStatus = 'Playing Topic' + navigationStack.splice(navigationStack.length - 1) + break + } + case 'Tutorial Step': { + currentNode = previousNode + findTutorialNode(currentNode) + currentStatus = 'Playing Step' + navigationStack.splice(navigationStack.length - 1) + break + } + } + } + } + + function next() { + if (ckeckGoingToAnotherTutorial() === true) { return } let tutorial = { status: 'Done' } @@ -343,41 +358,76 @@ function newTutorialSpace() { if (currentNode.payload !== undefined) { if (currentNode.payload.referenceParent !== undefined) { if (currentNode.payload.referenceParent.type === 'Tutorial') { - playTutorial(currentNode.payload.referenceParent) + tutorialRootNode = currentNode.payload.referenceParent + currentNode = currentNode.payload.referenceParent + currentStatus = 'Playing Tutorial' + resumeModeActivated = false + navigationStack.push(currentNode) + findTutorialNode(currentNode) + return true } } } } + function playTutorial(node) { + navigationStack = [] + node.payload.uiObject.isPlaying = true + tutorialRootNode = node + currentNode = node + currentStatus = 'Playing Tutorial' + resumeModeActivated = false + navigationStack.push(currentNode) + } + + function resumeTutorial(node) { + navigationStack = [] + node.payload.uiObject.isPlaying = true + tutorialRootNode = node + currentNode = node + currentStatus = 'Playing Tutorial' + resumeModeActivated = true + navigationStack.push(currentNode) + advance() + } + function playTutorialTopic(node) { + navigationStack = [] currentTopicNode = node currentNode = node currentStatus = 'Playing Topic' resumeModeActivated = false + navigationStack.push(currentNode) findTutorialNode(node) } function resumeTutorialTopic(node) { + navigationStack = [] currentTopicNode = node currentNode = node currentStatus = 'Playing Topic' resumeModeActivated = true + navigationStack.push(currentNode) findTutorialNode(node) } function playTutorialStep(node) { + navigationStack = [] currentStepNode = node currentNode = node currentStatus = 'Playing Step' resumeModeActivated = false + navigationStack.push(currentNode) findTutorialNode(node) } function resumeTutorialStep(node) { + navigationStack = [] currentStepNode = node currentNode = node currentStatus = 'Playing Step' resumeModeActivated = true + navigationStack.push(currentNode) findTutorialNode(node) } @@ -468,6 +518,8 @@ function newTutorialSpace() { currentNode = tutorialStep currentStatus = 'Playing Step' advanced = true + navigationStack.push(currentNode) + findTutorialNode(currentNode) return } else { let tutorial = { @@ -478,6 +530,8 @@ function newTutorialSpace() { currentNode = tutorialStep currentStatus = 'Playing Step' advanced = true + navigationStack.push(currentNode) + findTutorialNode(currentNode) return } } @@ -499,6 +553,8 @@ function newTutorialSpace() { currentNode = tutorialTopic currentStatus = 'Playing Topic' advanced = true + navigationStack.push(currentNode) + findTutorialNode(currentNode) return } else { let tutorial = { @@ -509,6 +565,8 @@ function newTutorialSpace() { currentNode = tutorialTopic currentStatus = 'Playing Topic' advanced = true + navigationStack.push(currentNode) + findTutorialNode(currentNode) return } } @@ -593,16 +651,16 @@ function newTutorialSpace() { html = html + '

    ' + nodeConfig.paragraph2 + '

    ' } if (nodeConfig.note !== undefined && nodeConfig.note !== '') { - html = html + '' + html = html + '' } if (nodeConfig.tip !== undefined && nodeConfig.tip !== '') { - html = html + '' + html = html + '' } if (nodeConfig.important !== undefined && nodeConfig.important !== '') { - html = html + '' + html = html + '' } if (nodeConfig.warning !== undefined && nodeConfig.warning !== '') { - html = html + '' + html = html + '' } html = html + '
    ' From 6be231eab30a14d6fde9ddfdbc9df90523a5e936 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 16:09:43 +0200 Subject: [PATCH 144/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 67fb7cb99..aeca389c2 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -251,7 +251,7 @@ function newTutorialSpace() { const HEIGHT = 650 const WIDTH = 400 const MARGIN = 300 - const FORM_HEIGHT = 80 + const FORM_HEIGHT = 40 let nodeConfig = JSON.parse(currentNode.config) switch (nodeConfig.position) { @@ -294,7 +294,7 @@ function newTutorialSpace() { buildHTML() tutorialFormDiv.style = ' ' + - 'position:fixed; top:' + (tutorialPosition.y + HEIGHT - FORM_HEIGHT) + 'px; ' + + 'position:fixed; top:' + (tutorialPosition.y + HEIGHT - 30) + 'px; ' + 'left:' + tutorialPosition.x + 'px; ' + 'width: ' + (WIDTH + 20) + 'px;' + 'height: ' + FORM_HEIGHT + 'px;' + From 8bcc7def95bc8a86517c894ffd71d69806e5280d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 20:16:42 +0200 Subject: [PATCH 145/192] No pinning first objects --- FloatingSpace/FloatingObject.js | 50 ++++++++++++++++++++------------- Spaces/TutorialSpace.js | 3 -- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index c3da76f1c..035538222 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -309,36 +309,46 @@ function newFloatingObject() { function positionContraintsPhysics() { const MAX_DISTANCE_TO_PARENT = 5000 const MIN_DISTANCE_TO_PARENT = 100 + const DEFAULT_NODE_TO_NODE_DISTANCE = 400 if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) { let parent = thisObject.payload.chainParent - if (parent === undefined) { return } - if (parent.payload === undefined) { return } - if (parent.payload.position === undefined) { return } + let distanceToParent + let parentChildren + let parentDistanceToGarndParent + if (parent === undefined) { + parentDistanceToGarndParent = DEFAULT_NODE_TO_NODE_DISTANCE + distanceToParent = DEFAULT_NODE_TO_NODE_DISTANCE + parentChildren = 1 + } else { + if (parent.payload === undefined) { return } + if (parent.payload.position === undefined) { return } + distanceToParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ... + parentChildren = canvas.designSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node) + parentDistanceToGarndParent = parent.payload.distance + } - let distanceToParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ... - let parentChildren = canvas.designSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node) let axisCount = parentChildren.childrenCount let axisIndex = parentChildren.childIndex let baseAngle = 0 let angleToParentAngle - if (parent.payload.distance !== undefined) { + if (parentDistanceToGarndParent !== undefined) { switch (thisObject.distanceToParent) { case DISTANCE_TO_PARENT.PARENT_025X: - distanceToParent = parent.payload.distance / 4 + distanceToParent = parentDistanceToGarndParent / 4 break case DISTANCE_TO_PARENT.PARENT_050X: - distanceToParent = parent.payload.distance / 2 + distanceToParent = parentDistanceToGarndParent / 2 break case DISTANCE_TO_PARENT.PARENT_100X: - distanceToParent = parent.payload.distance + distanceToParent = parentDistanceToGarndParent break case DISTANCE_TO_PARENT.PARENT_150X: - distanceToParent = parent.payload.distance * 1.5 + distanceToParent = parentDistanceToGarndParent * 1.5 break case DISTANCE_TO_PARENT.PARENT_200X: - distanceToParent = parent.payload.distance * 2 + distanceToParent = parentDistanceToGarndParent * 2 break } } @@ -371,16 +381,18 @@ function newFloatingObject() { axisIndex = axisCount } - if (parent.payload.chainParent !== undefined && parent.payload.angle !== undefined) { - axisCount++ - axisIndex++ - baseAngle = parent.payload.angle + 180 - lastParentAngle = parent.payload.angle - } else { - if (lastParentAngle !== undefined) { + if (parent !== undefined) { + if (parent.payload.chainParent !== undefined && parent.payload.angle !== undefined) { axisCount++ axisIndex++ - baseAngle = lastParentAngle + 180 + baseAngle = parent.payload.angle + 180 + lastParentAngle = parent.payload.angle + } else { + if (lastParentAngle !== undefined) { + axisCount++ + axisIndex++ + baseAngle = lastParentAngle + 180 + } } } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index aeca389c2..8e2459406 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -647,9 +647,6 @@ function newTutorialSpace() { if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { html = html + '

    ' + nodeConfig.paragraph2 + '

    ' } - if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { - html = html + '

    ' + nodeConfig.paragraph2 + '

    ' - } if (nodeConfig.note !== undefined && nodeConfig.note !== '') { html = html + '' } From c8bc21120199aa4a8f28c01afc264f315ffb8df9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 20:50:11 +0200 Subject: [PATCH 146/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 8e2459406..e9e2bdc8e 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -250,7 +250,7 @@ function newTutorialSpace() { function makeVsible() { const HEIGHT = 650 const WIDTH = 400 - const MARGIN = 300 + const MARGIN = 100 const FORM_HEIGHT = 40 let nodeConfig = JSON.parse(currentNode.config) From 1e1292d7473a30c608aaf17355901ad9fe82292b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 21:33:35 +0200 Subject: [PATCH 147/192] Doc on demand --- SideSpace/ListView.js | 2 +- SideSpace/SidePanelTab.js | 2 ++ Spaces/DocSpace.js | 21 ++++++++++++++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/SideSpace/ListView.js b/SideSpace/ListView.js index 5aac6fb7e..16474d696 100644 --- a/SideSpace/ListView.js +++ b/SideSpace/ListView.js @@ -205,7 +205,7 @@ function newListView() { } function drawBackground() { - let label = 'Your Workspaces' + let label = 'Available Workspaces' let backgroundColor = UI_COLOR.WHITE let params = { diff --git a/SideSpace/SidePanelTab.js b/SideSpace/SidePanelTab.js index b774ef9f8..bd853f480 100644 --- a/SideSpace/SidePanelTab.js +++ b/SideSpace/SidePanelTab.js @@ -69,10 +69,12 @@ function newSidePanelTab() { function open() { animation = 'opening' + thisObject.container.eventHandler.raiseEvent('opening') } function close() { animation = 'closing' + thisObject.container.eventHandler.raiseEvent('closing') } function onMouseClick(event) { diff --git a/Spaces/DocSpace.js b/Spaces/DocSpace.js index 31d43701b..b073e4674 100644 --- a/Spaces/DocSpace.js +++ b/Spaces/DocSpace.js @@ -23,15 +23,19 @@ function newDocSpace() { resize() - let openingEventSubscriptionId - let closedEventSubscriptionId let browserResizedEventSubscriptionId + let openingEventSubscriptionId + let closingEventSubscriptionId + + const DEFAULT_URL = 'https://julian-molina.github.io/Documentation/' return thisObject function initialize() { thisObject.sidePanelTab = newSidePanelTab() thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) thisObject.sidePanelTab.initialize('right') + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening) + closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing) browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) @@ -41,7 +45,18 @@ function newDocSpace() { function finalize() { canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) - thisObject.sidePanelTab.container.eventHandler.stopListening(closedEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(closingEventSubscriptionId) + } + + function onOpening() { + let docIFrame = document.getElementById('docIFrame') + if (docIFrame.src === "") { + docIFrame.src = DEFAULT_URL + } + } + + function onClosing() { + } function navigateTo(url) { From 6efa6d27eb04c681f3c0acfbe94281e4b7aa2efa Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 21 Sep 2020 21:42:35 +0200 Subject: [PATCH 148/192] Update FloatingObject.js --- FloatingSpace/FloatingObject.js | 45 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 035538222..bb386c79d 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -29,7 +29,7 @@ function newFloatingObject() { isParentCollapsed: false, frozenManually: false, collapsedManually: false, - unCollapseParent: unCollapseParent, + unCollapseParent: unCollapseParent, getPinStatus: getPinStatus, getFreezeStatus: getFreezeStatus, getCollapseStatus: getCollapseStatus, @@ -274,9 +274,9 @@ function newFloatingObject() { } function invisiblePhysics() { - if (thisObject.payload === undefined) {return} - if (thisObject.payload.uiObject === undefined) {return} - + if (thisObject.payload === undefined) { return } + if (thisObject.payload.uiObject === undefined) { return } + if (thisObject.payload.uiObject !== undefined) { thisObject.payload.uiObject.invisiblePhysics() } @@ -313,20 +313,20 @@ function newFloatingObject() { if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) { let parent = thisObject.payload.chainParent - let distanceToParent + let distanceToParent let parentChildren let parentDistanceToGarndParent - if (parent === undefined) { + if (parent === undefined) { parentDistanceToGarndParent = DEFAULT_NODE_TO_NODE_DISTANCE - distanceToParent = DEFAULT_NODE_TO_NODE_DISTANCE + distanceToParent = DEFAULT_NODE_TO_NODE_DISTANCE parentChildren = 1 - } else { + } else { if (parent.payload === undefined) { return } if (parent.payload.position === undefined) { return } distanceToParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ... parentChildren = canvas.designSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node) parentDistanceToGarndParent = parent.payload.distance - } + } let axisCount = parentChildren.childrenCount let axisIndex = parentChildren.childIndex @@ -419,9 +419,14 @@ function newFloatingObject() { return } - let newPosition = { - x: parent.payload.position.x, - y: parent.payload.position.y + let newPosition + if (parent !== undefined) { + newPosition = { + x: parent.payload.position.x, + y: parent.payload.position.y + } + } else { + return } let displacement @@ -604,8 +609,8 @@ function newFloatingObject() { } function drawBackground() { - if (thisObject.payload === undefined) {return} - if (thisObject.payload.uiObject === undefined) {return} + if (thisObject.payload === undefined) { return } + if (thisObject.payload.uiObject === undefined) { return } if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { @@ -617,8 +622,8 @@ function newFloatingObject() { } function drawMiddleground() { - if (thisObject.payload === undefined) {return} - if (thisObject.payload.uiObject === undefined) {return} + if (thisObject.payload === undefined) { return } + if (thisObject.payload.uiObject === undefined) { return } if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { @@ -630,8 +635,8 @@ function newFloatingObject() { } function drawForeground() { - if (thisObject.payload === undefined) {return} - if (thisObject.payload.uiObject === undefined) {return} + if (thisObject.payload === undefined) { return } + if (thisObject.payload.uiObject === undefined) { return } if (canvas.floatingSpace.isItFar(thisObject.payload) && thisObject.payload.uiObject.isShowing === false) { return } if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { @@ -643,8 +648,8 @@ function newFloatingObject() { } function drawOnFocus() { - if (thisObject.payload === undefined) {return} - if (thisObject.payload.uiObject === undefined) {return} + if (thisObject.payload === undefined) { return } + if (thisObject.payload.uiObject === undefined) { return } thisObject.payload.uiObject.drawOnFocus() } From 1874ed6c7441a5933c4e5cafb06878a5ee3d1444 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 22 Sep 2020 15:41:29 +0200 Subject: [PATCH 149/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 44 ++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index e9e2bdc8e..3ce4d4526 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -324,21 +324,21 @@ function newTutorialSpace() { currentNode = previousNode findTutorialNode(currentNode) currentStatus = 'Playing Tutorial' - navigationStack.splice(navigationStack.length - 1) + navigationStack.splice(navigationStack.length - 1) break } case 'Tutorial Topic': { currentNode = previousNode findTutorialNode(currentNode) currentStatus = 'Playing Topic' - navigationStack.splice(navigationStack.length - 1) + navigationStack.splice(navigationStack.length - 1) break } case 'Tutorial Step': { currentNode = previousNode findTutorialNode(currentNode) currentStatus = 'Playing Step' - navigationStack.splice(navigationStack.length - 1) + navigationStack.splice(navigationStack.length - 1) break } } @@ -597,7 +597,7 @@ function newTutorialSpace() { } html = html + '
    ' if (nodeConfig.summary !== undefined && nodeConfig.summary !== '') { - html = html + '
    ' + nodeConfig.summary + '
    ' + html = html + '
    ' + addToolTips(nodeConfig.summary) + '
    ' } if (nodeConfig.subTitle !== undefined && nodeConfig.subTitle !== '') { html = html + '

    ' + nodeConfig.subTitle + '

    ' @@ -606,6 +606,7 @@ function newTutorialSpace() { html = html + '
    ' newGifName = nodeConfig.gif } + if (nodeConfig.definition !== undefined && nodeConfig.definition !== '') { html = html + '' html = html + '' @@ -616,52 +617,67 @@ function newTutorialSpace() { } html = html + '' html = html + '' html = html + '' html = html + '
    ' - html = html + '' + nodeConfig.definition + '' + html = html + '' + addToolTips(nodeConfig.definition) + '' html = html + '
    ' } if (nodeConfig.bulletListIntro !== undefined && nodeConfig.bulletListIntro !== '') { - html = html + '

    ' + nodeConfig.bulletListIntro + '

    ' + html = html + '

    ' + addToolTips(nodeConfig.bulletListIntro) + '

    ' } if (nodeConfig.bulletArray !== undefined) { html = html + '
      ' for (let i = 0; i < nodeConfig.bulletArray.length; i++) { let bullet = nodeConfig.bulletArray[i] html = html + '
    • ' - html = html + '

      ' + bullet[0] + ' ' + bullet[1] + '

      ' + html = html + '

      ' + addToolTips(bullet[0]) + ' ' + addToolTips(bullet[1]) + '

      ' html = html + '
    • ' } html = html + '
    ' } if (nodeConfig.paragraph1 !== undefined && nodeConfig.paragraph1 !== '') { - html = html + '

    ' + nodeConfig.paragraph1 + '

    ' + html = html + '

    ' + addToolTips(nodeConfig.paragraph1) + '

    ' } if (nodeConfig.callOut !== undefined && nodeConfig.callOut !== '') { - html = html + '
    ' + nodeConfig.callOut + '' + html = html + '
    ' + addToolTips(nodeConfig.callOut) + '' if (nodeConfig.externalLink !== undefined) { html = html + '' + nodeConfig.externalLink[0] + '' } html = html + '
    ' } if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { - html = html + '

    ' + nodeConfig.paragraph2 + '

    ' + html = html + '

    ' + addToolTips(nodeConfig.paragraph2) + '

    ' } if (nodeConfig.note !== undefined && nodeConfig.note !== '') { - html = html + '' + html = html + '' } if (nodeConfig.tip !== undefined && nodeConfig.tip !== '') { - html = html + '' + html = html + '' } if (nodeConfig.important !== undefined && nodeConfig.important !== '') { - html = html + '' + html = html + '' } if (nodeConfig.warning !== undefined && nodeConfig.warning !== '') { - html = html + '' + html = html + '' } html = html + '
    ' tutorialDiv.innerHTML = html + + function addToolTips(text) { + const TOOL_TIP_HTML = '
    NODE_TYPENODE_DEFINITION
    ' + let resultingText = '' + let splittedText = text.split('->') + + for (let i = 0; i < splittedText.length; i = i + 2) { + let firstPart = splittedText[i] + let nodeType = splittedText[i + 1] + if (nodeType === undefined ) {return resultingText + firstPart} + let tooltip = TOOL_TIP_HTML.replace('NODE_TYPE', nodeType).replace('NODE_DEFINITION', 'La concha del mono, lo logre!') + resultingText = resultingText + firstPart + tooltip + } + return resultingText + } } function draw() { From 2ad465f9a6048b22f4d14d4dc5a6cb723ff79c1c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 22 Sep 2020 18:18:53 +0200 Subject: [PATCH 150/192] Tool Tips --- PostLoader.js | 12 ++++++++++-- Spaces/TutorialSpace.js | 43 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/PostLoader.js b/PostLoader.js index 8dd748334..f8e8307ef 100644 --- a/PostLoader.js +++ b/PostLoader.js @@ -3,6 +3,8 @@ let markets let APP_SCHEMA_MAP = new Map() let APP_SCHEMA_ARRAY = [] +let DOC_SCHEMA_MAP = new Map() +let DOC_SCHEMA_ARRAY = [] function newDashboard() { const MODULE_NAME = 'Dashboard' @@ -22,15 +24,21 @@ function newDashboard() { function start() { try { setBrowserEvents() - setUpAppSchema() + setUpSchemas() - function setUpAppSchema() { + function setUpSchemas() { APP_SCHEMA_ARRAY = getAppSchema() for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) { let nodeDefinition = APP_SCHEMA_ARRAY[i] let key = nodeDefinition.type APP_SCHEMA_MAP.set(key, nodeDefinition) } + DOC_SCHEMA_ARRAY = getDocSchema() + for (let i = 0; i < DOC_SCHEMA_ARRAY.length; i++) { + let nodeDefinition = DOC_SCHEMA_ARRAY[i] + let key = nodeDefinition.type + DOC_SCHEMA_MAP.set(key, nodeDefinition) + } startCanvas() } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 3ce4d4526..0da537187 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -111,6 +111,7 @@ function newTutorialSpace() { } } + checkPressButton() checkGif() checkImage() checkDocumentation() @@ -118,6 +119,34 @@ function newTutorialSpace() { checkReference() return + function checkPressButton() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if (config.pressButton === undefined || config.pressButton ==="") { + return + } + /* Remove this item from the navigation stack. */ + navigationStack.splice(navigationStack.length - 1) + switch (config.pressButton) { + case "Stop": { + stop() + return + } + case "Skip": { + skip() + return + } + case "Previous": { + previous() + return + } + case "Next": { + next() + return + } + } + } + function checkGif() { let tutorialGifDiv = document.getElementById('tutorialGifDiv') if (tutorialGifDiv !== null && tutorialGifDiv !== undefined) { @@ -673,8 +702,18 @@ function newTutorialSpace() { let firstPart = splittedText[i] let nodeType = splittedText[i + 1] if (nodeType === undefined ) {return resultingText + firstPart} - let tooltip = TOOL_TIP_HTML.replace('NODE_TYPE', nodeType).replace('NODE_DEFINITION', 'La concha del mono, lo logre!') - resultingText = resultingText + firstPart + tooltip + let definitionNode = DOC_SCHEMA_MAP.get(nodeType) + if (definitionNode === undefined) { + currentNode.setErrorMessage(nodeType + ' not found at Doc Schema.') + return + } + let definition = definitionNode.definition + if (definition === undefined || definition === "") { + resultingText = resultingText + firstPart + nodeType + } else { + let tooltip = TOOL_TIP_HTML.replace('NODE_TYPE', nodeType).replace('NODE_DEFINITION', definition) + resultingText = resultingText + firstPart + tooltip + } } return resultingText } From 329c14b6ba63b8a189f8ecce44bd17dd35543c76 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 23 Sep 2020 10:16:16 +0200 Subject: [PATCH 151/192] Position at Node --- .../CryptoEcosystemFunctions.js | 2 +- FloatingSpace/UiObject.js | 2 +- Spaces/TutorialSpace.js | 43 ++++++++++++------- Utilities/Dates.js | 13 ++++++ 4 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 Utilities/Dates.js diff --git a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js index 3641b3df9..66b356307 100644 --- a/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/CryptoEcosystemFunctions.js @@ -86,7 +86,7 @@ function newCryptoEcosystemFunctions() { node.payload.uiObject.setErrorMessage('Failed to Fetch Assets from the Exchange') return } - let queryParams = loadPropertyFromNodeConfig(node.payload, 'addMissingAssets') + let queryParams = loadPropertyFromNodeConfig(node.payload, 'addMissingAssetsFilter') let markets = JSON.parse(data) for (let i = 0; i < markets.length; i++) { diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index e492442f9..dfef9b09f 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -783,7 +783,7 @@ function newUiObject() { if (message !== undefined) { errorMessage = message thisObject.hasError = true - if (duration === undefined) { duration = 1 } + if (duration === undefined) { duration = 2 } errorMessageCounter = 100 * duration /* diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 0da537187..04751fd8f 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -122,7 +122,7 @@ function newTutorialSpace() { function checkPressButton() { if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) - if (config.pressButton === undefined || config.pressButton ==="") { + if (config.pressButton === undefined || config.pressButton === "") { return } /* Remove this item from the navigation stack. */ @@ -190,6 +190,7 @@ function newTutorialSpace() { canvas.docSpace.sidePanelTab.close() return } + canvas.docSpace.sidePanelTab.open() if (newDocumentationURL === currentDocumentationURL) { return } currentDocumentationURL = newDocumentationURL @@ -242,8 +243,15 @@ function newTutorialSpace() { if (currentNode.payload.referenceParent !== undefined) { if (currentNode.payload.referenceParent.payload !== undefined) { if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { - canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) - currentNode.payload.referenceParent.payload.uiObject.highlight() + let config = JSON.parse(currentNode.config) + if (config.useReferenceParentTo === 'Position at Node' || config.useReferenceParentTo === 'Position at Node & Start Tutorial') { + /* + This moves the Designs Space so that the referenced node is at the center of the screen. + */ + canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) + currentNode.payload.referenceParent.payload.uiObject.highlight() + return + } } } } @@ -386,14 +394,17 @@ function newTutorialSpace() { function ckeckGoingToAnotherTutorial() { if (currentNode.payload !== undefined) { if (currentNode.payload.referenceParent !== undefined) { - if (currentNode.payload.referenceParent.type === 'Tutorial') { - tutorialRootNode = currentNode.payload.referenceParent - currentNode = currentNode.payload.referenceParent - currentStatus = 'Playing Tutorial' - resumeModeActivated = false - navigationStack.push(currentNode) - findTutorialNode(currentNode) - return true + let config = JSON.parse(currentNode.config) + if (config.useReferenceParentTo === 'Start Tutorial' || config.useReferenceParentTo === 'Position at Node & Start Tutorial') { + if (currentNode.payload.referenceParent.type === 'Tutorial') { + tutorialRootNode = currentNode.payload.referenceParent + currentNode = currentNode.payload.referenceParent + currentStatus = 'Playing Tutorial' + resumeModeActivated = false + navigationStack.push(currentNode) + findTutorialNode(currentNode) + return true + } } } } @@ -641,7 +652,7 @@ function newTutorialSpace() { html = html + '' html = html + '' if (nodeConfig.image !== undefined && nodeConfig.image !== '') { - html = html + '
    ' + html = html + '
    ' newImageName = nodeConfig.image } html = html + '' @@ -701,18 +712,18 @@ function newTutorialSpace() { for (let i = 0; i < splittedText.length; i = i + 2) { let firstPart = splittedText[i] let nodeType = splittedText[i + 1] - if (nodeType === undefined ) {return resultingText + firstPart} + if (nodeType === undefined) { return resultingText + firstPart } let definitionNode = DOC_SCHEMA_MAP.get(nodeType) if (definitionNode === undefined) { - currentNode.setErrorMessage(nodeType + ' not found at Doc Schema.') + currentNode.payload.uiObject.setErrorMessage(nodeType + ' not found at Doc Schema.') return } let definition = definitionNode.definition if (definition === undefined || definition === "") { - resultingText = resultingText + firstPart + nodeType + resultingText = resultingText + firstPart + nodeType } else { let tooltip = TOOL_TIP_HTML.replace('NODE_TYPE', nodeType).replace('NODE_DEFINITION', definition) - resultingText = resultingText + firstPart + tooltip + resultingText = resultingText + firstPart + tooltip } } return resultingText diff --git a/Utilities/Dates.js b/Utilities/Dates.js new file mode 100644 index 000000000..9102d52ba --- /dev/null +++ b/Utilities/Dates.js @@ -0,0 +1,13 @@ +function formatDate(date) { + var d = new Date(date), + month = '' + (d.getMonth() + 1), + day = '' + d.getDate(), + year = d.getFullYear(); + + if (month.length < 2) + month = '0' + month; + if (day.length < 2) + day = '0' + day; + + return [year, month, day].join('-'); +} \ No newline at end of file From 8dffd34b5312b41b356b27b911b74e3c8fa5bb12 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 23 Sep 2020 11:24:17 +0200 Subject: [PATCH 152/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 71 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 04751fd8f..2cd41acaf 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -52,6 +52,7 @@ function newTutorialSpace() { let newDocumentationURL let currentDocumentationURL let resumeModeActivated // In this mode, we skip all the node which status is 'Done' + let lastExecutedAction = '' return thisObject @@ -244,13 +245,64 @@ function newTutorialSpace() { if (currentNode.payload.referenceParent.payload !== undefined) { if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { let config = JSON.parse(currentNode.config) - if (config.useReferenceParentTo === 'Position at Node' || config.useReferenceParentTo === 'Position at Node & Start Tutorial') { + if ( + config.positionAtReferenceParent === true || + config.positionAtReferenceParent === undefined + ) { /* This moves the Designs Space so that the referenced node is at the center of the screen. */ canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) + } + if ( + config.highlightReferenceParent === true + ) { currentNode.payload.referenceParent.payload.uiObject.highlight() - return + } + if ( + config.highlightReferenceParent === true + ) { + currentNode.payload.referenceParent.payload.uiObject.highlight() + } + if ( + config.setErrorMessageReferenceParent !== undefined + ) { + currentNode.payload.referenceParent.payload.uiObject.setErrorMessage(config.setErrorMessageReferenceParent) + } + if ( + config.setWarningMessageReferenceParent !== undefined + ) { + currentNode.payload.referenceParent.payload.uiObject.setWarningMessage(config.setWarningMessageReferenceParent) + } + if ( + config.setInfoMessageReferenceParent !== undefined + ) { + currentNode.payload.referenceParent.payload.uiObject.setInfoMessage(config.setInfoMessageReferenceParent) + } + if ( + config.setValueReferenceParent !== undefined + ) { + currentNode.payload.referenceParent.payload.uiObject.setValue(config.setValueReferenceParent) + } + if ( + config.setPercentageReferenceParent !== undefined + ) { + currentNode.payload.referenceParent.payload.uiObject.setPercentage(config.setPercentageReferenceParent) + } + if ( + config.setStatusReferenceParent !== undefined + ) { + currentNode.payload.referenceParent.payload.uiObject.setStatus(config.setStatusReferenceParent) + } + if ( + config.menuActionReferenceParent !== undefined + ) { + if (config.menuActionReferenceParent + currentNode.id !== lastExecutedAction) { + currentNode.payload.referenceParent.payload.uiObject.menu.internalClick(config.menuActionReferenceParent) + lastExecutedAction = config.menuActionReferenceParent + currentNode.id + } + } else { + lastExecutedAction = "" } } } @@ -346,6 +398,7 @@ function newTutorialSpace() { } function skip() { + lastExecutedAction = "" let tutorial = { status: 'Skipped' } @@ -354,6 +407,7 @@ function newTutorialSpace() { } function previous() { + lastExecutedAction = "" if (navigationStack.length > 1) { let previousNode = navigationStack[navigationStack.length - 2] switch (previousNode.type) { @@ -383,6 +437,7 @@ function newTutorialSpace() { } function next() { + lastExecutedAction = "" if (ckeckGoingToAnotherTutorial() === true) { return } let tutorial = { status: 'Done' @@ -395,7 +450,7 @@ function newTutorialSpace() { if (currentNode.payload !== undefined) { if (currentNode.payload.referenceParent !== undefined) { let config = JSON.parse(currentNode.config) - if (config.useReferenceParentTo === 'Start Tutorial' || config.useReferenceParentTo === 'Position at Node & Start Tutorial') { + if (config.startTutorialReferenceParent === true) { if (currentNode.payload.referenceParent.type === 'Tutorial') { tutorialRootNode = currentNode.payload.referenceParent currentNode = currentNode.payload.referenceParent @@ -663,20 +718,20 @@ function newTutorialSpace() { html = html + '' } if (nodeConfig.bulletListIntro !== undefined && nodeConfig.bulletListIntro !== '') { - html = html + '

    ' + addToolTips(nodeConfig.bulletListIntro) + '

    ' + html = html + '
    ' + addToolTips(nodeConfig.bulletListIntro) + '
    ' } if (nodeConfig.bulletArray !== undefined) { html = html + '
      ' for (let i = 0; i < nodeConfig.bulletArray.length; i++) { let bullet = nodeConfig.bulletArray[i] html = html + '
    • ' - html = html + '

      ' + addToolTips(bullet[0]) + ' ' + addToolTips(bullet[1]) + '

      ' + html = html + '
      ' + addToolTips(bullet[0]) + ' ' + addToolTips(bullet[1]) + '
      ' html = html + '
    • ' } html = html + '
    ' } if (nodeConfig.paragraph1 !== undefined && nodeConfig.paragraph1 !== '') { - html = html + '

    ' + addToolTips(nodeConfig.paragraph1) + '

    ' + html = html + '
    ' + addToolTips(nodeConfig.paragraph1) + '
    ' } if (nodeConfig.callOut !== undefined && nodeConfig.callOut !== '') { html = html + '
    ' + addToolTips(nodeConfig.callOut) + '' @@ -712,7 +767,9 @@ function newTutorialSpace() { for (let i = 0; i < splittedText.length; i = i + 2) { let firstPart = splittedText[i] let nodeType = splittedText[i + 1] - if (nodeType === undefined) { return resultingText + firstPart } + if (nodeType === undefined) { + return resultingText + firstPart + } let definitionNode = DOC_SCHEMA_MAP.get(nodeType) if (definitionNode === undefined) { currentNode.payload.uiObject.setErrorMessage(nodeType + ' not found at Doc Schema.') From d24e7065a1e0970a95016b656c65d6c442e14f99 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 23 Sep 2020 12:04:30 +0200 Subject: [PATCH 153/192] focus --- FloatingSpace/FloatingObject.js | 54 ++++++++++++++++++++++++++------- Spaces/TutorialSpace.js | 44 +++++++++++++++++++++++---- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index bb386c79d..7a717d583 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -29,6 +29,10 @@ function newFloatingObject() { isParentCollapsed: false, frozenManually: false, collapsedManually: false, + forceFocus: forceFocus, + removeForceFocus: removeForceFocus, + setFocus: setFocus, + removeFocus: removeFocus, unCollapseParent: unCollapseParent, getPinStatus: getPinStatus, getFreezeStatus: getFreezeStatus, @@ -78,6 +82,7 @@ function newFloatingObject() { let spaceMouseOverEventSubscriptionId let spaceFocusAquiredEventSubscriptionId let lastParentAngle + let forcedFocusCounter = 0 return thisObject @@ -291,6 +296,14 @@ function newFloatingObject() { thisObject.payload.uiObject.physics() } positionContraintsPhysics() + focusPhysics() + } + + function focusPhysics() { + forcedFocusCounter-- + if (forcedFocusCounter < 0) { + forcedFocusCounter = 0 + } } function frozenPhysics() { @@ -551,19 +564,11 @@ function newFloatingObject() { thisObject.payload.position.y = thisObject.container.frame.position.y } + + function onMouseOver(point) { if (thisObject.isOnFocus === false) { - thisObject.targetRadius = thisObject.rawRadius * 6.0 - thisObject.targetImageSize = thisObject.rawImageSize * 2.0 - thisObject.targetFontSize = thisObject.rawFontSize * 2.0 - thisObject.targetHierarchyRing = thisObject.rawHierarchyRing * 8.0 - - thisObject.payload.uiObject.container.eventHandler.raiseEvent('onFocus', point) - - thisObject.positionLocked = true - - canvas.floatingSpace.container.eventHandler.raiseEvent('onFocusAquired', thisObject) - thisObject.isOnFocus = true + setFocus(point) } } @@ -583,7 +588,34 @@ function newFloatingObject() { } } + function forceFocus() { + forcedFocusCounter = 10 + setFocus() + } + + function removeForceFocus() { + forcedFocusCounter = 0 + removeFocus() + } + + function setFocus(point) { + thisObject.targetRadius = thisObject.rawRadius * 6.0 + thisObject.targetImageSize = thisObject.rawImageSize * 2.0 + thisObject.targetFontSize = thisObject.rawFontSize * 2.0 + thisObject.targetHierarchyRing = thisObject.rawHierarchyRing * 8.0 + + thisObject.payload.uiObject.container.eventHandler.raiseEvent('onFocus', point) + + thisObject.positionLocked = true + + canvas.floatingSpace.container.eventHandler.raiseEvent('onFocusAquired', thisObject) + thisObject.isOnFocus = true + } + function removeFocus() { + if (forcedFocusCounter > 0) { + return + } if (thisObject.payload === undefined) { return } if (thisObject.isOnFocus === true) { thisObject.targetRadius = thisObject.rawRadius * 1 diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 2cd41acaf..b35a7c4dc 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -53,6 +53,8 @@ function newTutorialSpace() { let currentDocumentationURL let resumeModeActivated // In this mode, we skip all the node which status is 'Done' let lastExecutedAction = '' + let actionCounter = 0 + let forcingFocus = false return thisObject @@ -294,12 +296,25 @@ function newTutorialSpace() { ) { currentNode.payload.referenceParent.payload.uiObject.setStatus(config.setStatusReferenceParent) } + if ( + config.setFocusReferenceParent === true + ) { + currentNode.payload.referenceParent.payload.floatingObject.forceFocus() + forcingFocus = true + } if ( config.menuActionReferenceParent !== undefined ) { - if (config.menuActionReferenceParent + currentNode.id !== lastExecutedAction) { - currentNode.payload.referenceParent.payload.uiObject.menu.internalClick(config.menuActionReferenceParent) - lastExecutedAction = config.menuActionReferenceParent + currentNode.id + /* + Some actions needs a little delay because they depend on animations to happen. + For that reason, we will count until 10 before executing actions from tutorial. + */ + actionCounter++ + if (actionCounter > 10) { + if (config.menuActionReferenceParent + currentNode.id !== lastExecutedAction) { + currentNode.payload.referenceParent.payload.uiObject.menu.internalClick(config.menuActionReferenceParent) + lastExecutedAction = config.menuActionReferenceParent + currentNode.id + } } } else { lastExecutedAction = "" @@ -392,13 +407,16 @@ function newTutorialSpace() { } function stop() { + checkForceFocus() + resetActions() tutorialRootNode.payload.uiObject.isPlaying = false tutorialRootNode = undefined currentStatus = 'Stopped' } function skip() { - lastExecutedAction = "" + checkForceFocus() + resetActions() let tutorial = { status: 'Skipped' } @@ -407,7 +425,8 @@ function newTutorialSpace() { } function previous() { - lastExecutedAction = "" + checkForceFocus() + resetActions() if (navigationStack.length > 1) { let previousNode = navigationStack[navigationStack.length - 2] switch (previousNode.type) { @@ -437,7 +456,8 @@ function newTutorialSpace() { } function next() { - lastExecutedAction = "" + checkForceFocus() + resetActions() if (ckeckGoingToAnotherTutorial() === true) { return } let tutorial = { status: 'Done' @@ -446,6 +466,18 @@ function newTutorialSpace() { advance() } + function resetActions() { + lastExecutedAction = "" + actionCounter = 0 + } + + function checkForceFocus() { + if (forcingFocus === true) { + currentNode.payload.referenceParent.payload.floatingObject.removeForceFocus() + forcingFocus = false + } + } + function ckeckGoingToAnotherTutorial() { if (currentNode.payload !== undefined) { if (currentNode.payload.referenceParent !== undefined) { From 1023c8bc9fd7c282bd438ab3afd9b4b39fd432d7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 23 Sep 2020 13:02:15 +0200 Subject: [PATCH 154/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index b35a7c4dc..6230fc9b1 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -49,7 +49,6 @@ function newTutorialSpace() { let newImageName = 'Never Set' let currentConfig let newConfig - let newDocumentationURL let currentDocumentationURL let resumeModeActivated // In this mode, we skip all the node which status is 'Done' let lastExecutedAction = '' @@ -407,16 +406,16 @@ function newTutorialSpace() { } function stop() { + resetAfterButtonPressed() checkForceFocus() - resetActions() tutorialRootNode.payload.uiObject.isPlaying = false tutorialRootNode = undefined currentStatus = 'Stopped' } function skip() { + resetAfterButtonPressed() checkForceFocus() - resetActions() let tutorial = { status: 'Skipped' } @@ -425,8 +424,8 @@ function newTutorialSpace() { } function previous() { + resetAfterButtonPressed() checkForceFocus() - resetActions() if (navigationStack.length > 1) { let previousNode = navigationStack[navigationStack.length - 2] switch (previousNode.type) { @@ -456,8 +455,8 @@ function newTutorialSpace() { } function next() { + resetAfterButtonPressed() checkForceFocus() - resetActions() if (ckeckGoingToAnotherTutorial() === true) { return } let tutorial = { status: 'Done' @@ -466,11 +465,20 @@ function newTutorialSpace() { advance() } + function resetAfterButtonPressed() { + resetActions() + resetDocumentation() + } + function resetActions() { lastExecutedAction = "" actionCounter = 0 } + function resetDocumentation() { + currentDocumentationURL = '' + } + function checkForceFocus() { if (forcingFocus === true) { currentNode.payload.referenceParent.payload.floatingObject.removeForceFocus() From 806f83907f6bebe0a091adb0c7398362ed6ca192 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 23 Sep 2020 15:02:05 +0200 Subject: [PATCH 155/192] fixes --- DesignSpace/Workspace/Workspace.js | 16 ++++++---------- Spaces/TutorialSpace.js | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index bdf92afb8..747baf496 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -276,38 +276,34 @@ function newWorkspace() { switch (workingAtTask) { case 1: - stopAllRunningTasks() - workingAtTask++ - break - case 2: functionLibraryNodeDeleter.deleteWorkspace(thisObject.workspaceNode, thisObject.workspaceNode.rootNodes) workingAtTask++ break - case 3: + case 2: finalizeEventsServerClients() thisObject.eventsServerClients = new Map() workingAtTask++ break - case 4: + case 3: clearInterval(savingWorkspaceIntervalId) workingAtTask++ break - case 5: + case 4: thisObject.workspaceNode = loadedWorkspaceNode loadedWorkspaceNode = undefined workingAtTask++ break - case 6: + case 5: functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode) setupEventsServerClients() runTasksAndSessions(true) workingAtTask++ break - case 7: + case 6: canvas.chartingSpace.reset() workingAtTask++ break - case 8: + case 7: workingAtTask = 0 circularProgressBar.visible = false break diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 6230fc9b1..0670dd387 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -800,7 +800,7 @@ function newTutorialSpace() { tutorialDiv.innerHTML = html function addToolTips(text) { - const TOOL_TIP_HTML = '
    NODE_TYPENODE_DEFINITION
    ' + const TOOL_TIP_HTML = '
    NODE_TYPENODE_DEFINITION
    ' let resultingText = '' let splittedText = text.split('->') From 32432ac8d810ec52dc40ff986c2f53460ffddbfa Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 23 Sep 2020 19:23:48 +0200 Subject: [PATCH 156/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 0670dd387..7d948a6e1 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -781,7 +781,7 @@ function newTutorialSpace() { html = html + '
    ' } if (nodeConfig.paragraph2 !== undefined && nodeConfig.paragraph2 !== '') { - html = html + '

    ' + addToolTips(nodeConfig.paragraph2) + '

    ' + html = html + '
    ' + addToolTips(nodeConfig.paragraph2) + '
    ' } if (nodeConfig.note !== undefined && nodeConfig.note !== '') { html = html + '' From 16b6ece39d65b9ce5f212f048bfa80c1d715d803 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 09:35:02 +0200 Subject: [PATCH 157/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 49 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 7d948a6e1..51cadd3bd 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -420,7 +420,7 @@ function newTutorialSpace() { status: 'Skipped' } saveTutorial(currentNode.payload, tutorial) - advance() + advance(true) } function previous() { @@ -603,7 +603,7 @@ function newTutorialSpace() { } } - function advance() { + function advance(isSkipping) { let found let advanced @@ -615,7 +615,11 @@ function newTutorialSpace() { } case 'Playing Topic': { found = false - findNextNode(tutorialRootNode) + if (isSkipping === true) { + findNextTopic(tutorialRootNode) + } else { + findNextNode(tutorialRootNode) + } break } case 'Playing Step': { @@ -713,6 +717,45 @@ function newTutorialSpace() { findNextNode(tutorialTopic, found) } } + + function findNextTopic(node) { + for (let i = 0; i < node.tutorialTopics.length; i++) { + + if (advanced === true) { + return + } + + let tutorialTopic = node.tutorialTopics[i] + if (found === true) { + if (resumeModeActivated !== true) { + currentNode = tutorialTopic + currentStatus = 'Playing Topic' + advanced = true + navigationStack.push(currentNode) + findTutorialNode(currentNode) + return + } else { + let tutorial = { + status: undefined + } + loadTutorial(tutorialTopic.payload, tutorial) + if (tutorial.status !== 'Done') { + currentNode = tutorialTopic + currentStatus = 'Playing Topic' + advanced = true + navigationStack.push(currentNode) + findTutorialNode(currentNode) + return + } + } + } + if (tutorialTopic.id === currentNode.id) { + found = true + } else { + findNextTopic(tutorialTopic, found) + } + } + } } function buildHTML() { From 592f8fbc9717e7129f5728ee83e0a1b9f55f7b8f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 12:08:08 +0200 Subject: [PATCH 158/192] Zooming --- Scales/TimeFrameScale.js | 2 +- Spaces/ChartingSpace.js | 10 +++++++ Spaces/TutorialSpace.js | 57 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Scales/TimeFrameScale.js b/Scales/TimeFrameScale.js index 26442ef5d..0d4becfbe 100644 --- a/Scales/TimeFrameScale.js +++ b/Scales/TimeFrameScale.js @@ -219,7 +219,7 @@ function newTimeFrameScale() { function onViewportZoomChanged(event) { if (event !== undefined) { // it is undefined when the level is just being animated. - if (event.shiftKey === false) { return } // with no shft key pressed, no automatic change in scale + if (event.shiftKey === false || event.shiftKey === undefined) { return } // with no shft key pressed, no automatic change in scale let currentTimeFrame = thisObject.timeFrame let timeFrame = recalculatePeriod(event.newLevel) if (timeFrame !== currentTimeFrame) { diff --git a/Spaces/ChartingSpace.js b/Spaces/ChartingSpace.js index 6fcc122c5..647ea5a24 100644 --- a/Spaces/ChartingSpace.js +++ b/Spaces/ChartingSpace.js @@ -19,6 +19,7 @@ function newChartingSpace() { timeMachines: undefined, viewport: undefined, payload: undefined, + findTimeMachine: findTimeMachine, onKeyPressed: onKeyPressed, reset: reset, oneScreenUp: oneScreenUp, @@ -295,6 +296,15 @@ function newChartingSpace() { } } + function findTimeMachine(node) { + for (let i = 0; i < thisObject.timeMachines.length; i++) { + let timeMachine = thisObject.timeMachines[i] + if (timeMachine.payload.node.id === node.id) { + return timeMachine + } + } + } + function syncWithDesigner() { if (thisObject.payload === undefined) { return } if (thisObject.payload.node === undefined) { return } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 51cadd3bd..7d46e1a5a 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -54,6 +54,8 @@ function newTutorialSpace() { let lastExecutedAction = '' let actionCounter = 0 let forcingFocus = false + let currentZoomStep = 0 + let viewportCentered = false return thisObject @@ -119,8 +121,45 @@ function newTutorialSpace() { checkDocumentation() checkSlider() checkReference() + checkViewportZoom() + checkViewportZoomAtCenter() return + function checkViewportZoom() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if (config.viewportZoom !== undefined) { + let totalZoomSteps = config.viewportZoom + let delta + if (totalZoomSteps > 0) { + delta = 1 + } else { + delta = -1 + } + currentZoomStep = currentZoomStep + delta + let event = { + delta: delta + } + if (totalZoomSteps > 0) { + if (currentZoomStep < totalZoomSteps) { + canvas.chartingSpace.viewport.onMouseWheel(event) + } + } else { + if (currentZoomStep > totalZoomSteps) { + canvas.chartingSpace.viewport.onMouseWheel(event) + } + } + } + } + + function checkViewportZoomAtCenter() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if (config.viewportZoomAtCenter !== undefined) { + canvas.chartingSpace.viewport.zoomAtCenter(config.viewportZoomAtCenter) + } + } + function checkPressButton() { if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) @@ -239,7 +278,6 @@ function newTutorialSpace() { If there is a reference parent defined, we will highlight it and move the designer so that that node be at the center of the screen. */ - if (currentNode !== undefined) { if (currentNode.payload !== undefined) { if (currentNode.payload.referenceParent !== undefined) { @@ -318,6 +356,17 @@ function newTutorialSpace() { } else { lastExecutedAction = "" } + if ( + config.viewportCenterReferenceParent === true + ) { + if (currentNode.payload.referenceParent.type === 'Time Machine') { + let timeMachine = canvas.chartingSpace.findTimeMachine(currentNode.payload.referenceParent) + if (timeMachine !== undefined && viewportCentered === false) { + canvas.chartingSpace.viewport.displaceToContainer(timeMachine.container) + viewportCentered = true + } + } + } } } } @@ -466,6 +515,7 @@ function newTutorialSpace() { } function resetAfterButtonPressed() { + resetViewport() resetActions() resetDocumentation() } @@ -475,6 +525,11 @@ function newTutorialSpace() { actionCounter = 0 } + function resetViewport() { + currentZoomStep = 0 + viewportCentered = false + } + function resetDocumentation() { currentDocumentationURL = '' } From f427b49c2e0f121a44a32f824e2f837627d320a2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 12:40:51 +0200 Subject: [PATCH 159/192] Update CoordinateSystem.js --- ChartingSpace/CoordinateSystem.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ChartingSpace/CoordinateSystem.js b/ChartingSpace/CoordinateSystem.js index 3a9d3fcf4..de7f0eacf 100644 --- a/ChartingSpace/CoordinateSystem.js +++ b/ChartingSpace/CoordinateSystem.js @@ -23,10 +23,10 @@ function newCoordinateSystem() { autoMaxXScale: true, autoMinYScale: true, autoMaxYScale: true, - HORIZONTAL_MARGIN_FACTOR: 0.80, - VERTICAL_MARGIN_FACTOR: 0.90, - HORIZONTAL_MARGIN_INVERSE_FACTOR: 0.20, - VERTICAL_MARGIN_INVERSE_FACTOR: 0.10, + HORIZONTAL_MARGIN_FACTOR: 1, + VERTICAL_MARGIN_FACTOR: 1, + HORIZONTAL_MARGIN_INVERSE_FACTOR: 0, + VERTICAL_MARGIN_INVERSE_FACTOR: 0, physics: physics, reportParentXValue: reportParentXValue, reportParentYValue: reportParentYValue, From a0a1ae99d7e841611f753a169c00ddbb64c8d270 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 13:12:23 +0200 Subject: [PATCH 160/192] text styke to panels --- Panels/Layer.js | 2 +- Panels/PlotterPanel.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Panels/Layer.js b/Panels/Layer.js index db36f4226..ccc6163f2 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -187,7 +187,7 @@ function newLayer() { 'Polygon Vertex->Point->' + 'Image->Image Condition->Image Position->Point->' + 'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' + - 'Plotter Panel->Javascript Code->Panel Data->Data Formula->' + + 'Plotter Panel->Javascript Code->Panel Data->Data Formula->Text Style->' + 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Warnings->Nodes Infos->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) diff --git a/Panels/PlotterPanel.js b/Panels/PlotterPanel.js index 2b02913b5..65e873eac 100644 --- a/Panels/PlotterPanel.js +++ b/Panels/PlotterPanel.js @@ -167,8 +167,18 @@ function newPlotterPanel() { valuePosition = panelData.config.valuePosition } + let opacity = '1.00' + let fontSize = 14 + let paletteColor + + if (panelData.textStyle !== undefined) { + if (panelData.textStyle.config.fontSize !== undefined) { fontSize = panelData.textStyle.config.fontSize } + if (panelData.textStyle.config.opacity !== undefined) { opacity = panelData.textStyle.config.opacity } + if (panelData.textStyle.config.paletteColor !== undefined) { paletteColor = eval(panelData.textStyle.config.paletteColor) } + } + printLabel(labelText, X_AXIS, UI_PANEL.HEIGHT.NORMAL * labelPosition / 100 / heightFactor, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction) - printLabel(value, X_AXIS, UI_PANEL.HEIGHT.NORMAL * valuePosition / 100 / heightFactor, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction, false, true) + printLabel(value, X_AXIS, UI_PANEL.HEIGHT.NORMAL * valuePosition / 100 / heightFactor, opacity, fontSize, paletteColor, true, thisObject.container, thisObject.fitFunction, false, true) } } } From 30e974ae205d072900202e83ac138f6f84b56dad Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 16:38:50 +0200 Subject: [PATCH 161/192] concepts --- PostLoader.js | 8 ++++++++ Spaces/TutorialSpace.js | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/PostLoader.js b/PostLoader.js index f8e8307ef..45775dee7 100644 --- a/PostLoader.js +++ b/PostLoader.js @@ -5,6 +5,8 @@ let APP_SCHEMA_MAP = new Map() let APP_SCHEMA_ARRAY = [] let DOC_SCHEMA_MAP = new Map() let DOC_SCHEMA_ARRAY = [] +let CONCEPT_SCHEMA_MAP = new Map() +let CONCEPT_SCHEMA_ARRAY = [] function newDashboard() { const MODULE_NAME = 'Dashboard' @@ -39,6 +41,12 @@ function newDashboard() { let key = nodeDefinition.type DOC_SCHEMA_MAP.set(key, nodeDefinition) } + CONCEPT_SCHEMA_ARRAY = getConceptSchema() + for (let i = 0; i < CONCEPT_SCHEMA_ARRAY.length; i++) { + let nodeDefinition = CONCEPT_SCHEMA_ARRAY[i] + let key = nodeDefinition.type + CONCEPT_SCHEMA_MAP.set(key, nodeDefinition) + } startCanvas() } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 7d46e1a5a..bf9537ed8 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -910,8 +910,11 @@ function newTutorialSpace() { } let definitionNode = DOC_SCHEMA_MAP.get(nodeType) if (definitionNode === undefined) { - currentNode.payload.uiObject.setErrorMessage(nodeType + ' not found at Doc Schema.') - return + definitionNode = CONCEPT_SCHEMA_MAP.get(nodeType) + if (definitionNode === undefined) { + currentNode.payload.uiObject.setErrorMessage(nodeType + ' not found at Doc Schema or Concept Schema.') + return + } } let definition = definitionNode.definition if (definition === undefined || definition === "") { From d5a0d4ad8ae82df2cb12bd6e80e0f1759422a381 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 17:52:18 +0200 Subject: [PATCH 162/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index bf9537ed8..c49082f40 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -119,6 +119,7 @@ function newTutorialSpace() { checkGif() checkImage() checkDocumentation() + checkWorkspaces() checkSlider() checkReference() checkViewportZoom() @@ -238,6 +239,32 @@ function newTutorialSpace() { canvas.docSpace.navigateTo(currentDocumentationURL) } + function checkWorkspaces() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if (config.workspaces === undefined) { + /* + The worspaces panel will remain as it is, and the user will be free to open or close it at will. + */ + return + } + if (config.workspaces === "" || config.workspaces === "Close") { + /* + This forces the tutorial to close the documentation panel and to keep it closed. + */ + canvas.sideSpace.sidePanelTab.close() + return + } + if (config.workspaces === "Open") { + /* + This forces the tutorial to close the documentation panel and to keep it closed. + */ + canvas.sideSpace.sidePanelTab.open() + return + } + canvas.docSpace.sidePanelTab.open() + } + function checkSlider() { if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) From 76b68463ab0d30960ce90d36824bacf5af7cf65d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 17:54:18 +0200 Subject: [PATCH 163/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index c49082f40..6e1bdd7da 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -250,19 +250,18 @@ function newTutorialSpace() { } if (config.workspaces === "" || config.workspaces === "Close") { /* - This forces the tutorial to close the documentation panel and to keep it closed. + This forces the tutorial to close the workspaces panel and to keep it closed. */ canvas.sideSpace.sidePanelTab.close() return } if (config.workspaces === "Open") { /* - This forces the tutorial to close the documentation panel and to keep it closed. + This forces the tutorial to close the workspaces panel and to keep it closed. */ canvas.sideSpace.sidePanelTab.open() return } - canvas.docSpace.sidePanelTab.open() } function checkSlider() { From 3cf8e0a2ff7d3de197840aa4d0a2e31312b84057 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Sep 2020 19:06:21 +0200 Subject: [PATCH 164/192] getready --- .../FunctionLibraries/TaskFunctions.js | 37 ++++++++++++++++++- Spaces/TutorialSpace.js | 4 +- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index 24b0c3687..a7913454e 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -1,5 +1,7 @@ function newTaskFunctions() { thisObject = { + getReady: getReady, + runTask: runTask, stopTask: stopTask, runAllTasks: runAllTasks, @@ -33,6 +35,39 @@ function newTaskFunctions() { return thisObject + function getReady(node) { + let networkNode = validations(node) + if (networkNode === undefined) { + /* Nodes that do not belong to a network can not get ready. */ + return + } + + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + + /* First we setup everything so as to listen to the response from the Task Manger */ + let eventSubscriptionIdOnStatus + let key = 'Task Client - ' + node.id + eventsServerClient.listenToEvent(key, 'Task Status', undefined, node.id, onResponse, onStatus) + + function onResponse(message) { + eventSubscriptionIdOnStatus = message.eventSubscriptionId + } + + function onStatus(message) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnStatus, node.id) + if (message.event.status === 'Task Process Running' ) { + node.payload.uiObject.run() + } + } + + /* Second we ask the Task Manager if this Task has a process Running. */ + let event = { + taskId: node.id + } + + eventsServerClient.raiseEvent('Task Manager', 'Task Status', event) + } + function runTask(node, functionLibraryProtocolNode, isDebugging, callBackFunction) { let networkNode = validations(node) @@ -494,7 +529,7 @@ function newTaskFunctions() { let task = functionLibraryUiObjectsFromNodes.addUIObject(taskManager, 'Task') if (tradingSystem !== undefined) { - task.name = tradingSystem.name + task.name = tradingSystem.name } else { task.name = bot.name } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 6e1bdd7da..7acd8a6d5 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -914,10 +914,10 @@ function newTutorialSpace() { html = html + '' } if (nodeConfig.important !== undefined && nodeConfig.important !== '') { - html = html + '' + html = html + '' } if (nodeConfig.warning !== undefined && nodeConfig.warning !== '') { - html = html + '' + html = html + '' } html = html + '
    ' From 6ba3f70a0567510a571f4b79bbc89d0de64c0027 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 09:17:54 +0200 Subject: [PATCH 165/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 91 ++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 7acd8a6d5..429a76cdc 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -56,6 +56,8 @@ function newTutorialSpace() { let forcingFocus = false let currentZoomStep = 0 let viewportCentered = false + let repositionAtTimeMachineCounter = 0 + let positionAtNodeCounter = 0 return thisObject @@ -161,6 +163,14 @@ function newTutorialSpace() { } } + function checkViewportZoomAtCenter() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if (config.viewportZoomAtCenter !== undefined) { + canvas.chartingSpace.viewport.zoomAtCenter(config.viewportZoomAtCenter) + } + } + function checkPressButton() { if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) @@ -241,7 +251,7 @@ function newTutorialSpace() { function checkWorkspaces() { if (currentNode === undefined) { return } - let config = JSON.parse(currentNode.config) + let config = JSON.parse(currentNode.config) if (config.workspaces === undefined) { /* The worspaces panel will remain as it is, and the user will be free to open or close it at will. @@ -317,7 +327,13 @@ function newTutorialSpace() { /* This moves the Designs Space so that the referenced node is at the center of the screen. */ - canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) + positionAtNodeCounter++ + if (positionAtNodeCounter === 1) { + currentNode.payload.referenceParent.payload.floatingObject.unCollapseParent() + } + if (positionAtNodeCounter < 100) { + canvas.floatingSpace.positionAtNode(currentNode.payload.referenceParent) + } } if ( config.highlightReferenceParent === true @@ -393,6 +409,33 @@ function newTutorialSpace() { } } } + if ( + config.repositionAtTimeMachineReferenceParent === true + ) { + if (currentNode.payload.referenceParent.type === 'Time Machine') { + let timeMachine = canvas.chartingSpace.findTimeMachine(currentNode.payload.referenceParent) + if (timeMachine !== undefined) { + repositionAtTimeMachineCounter++ + switch (true) { + case (repositionAtTimeMachineCounter > 10 && repositionAtTimeMachineCounter < 20): { + let event = { + delta: -1 + } + canvas.chartingSpace.viewport.onMouseWheel(event) + break + } + case (repositionAtTimeMachineCounter === 30): { + canvas.chartingSpace.viewport.displaceToContainer(timeMachine.container) + break + } + case (repositionAtTimeMachineCounter === 40): { + canvas.chartingSpace.viewport.zoomAtCenter(8) + break + } + } + } + } + } } } } @@ -544,20 +587,30 @@ function newTutorialSpace() { resetViewport() resetActions() resetDocumentation() - } + resetRepositionAtTimeMachine() + resetPositionAtNode() - function resetActions() { - lastExecutedAction = "" - actionCounter = 0 - } + function resetActions() { + lastExecutedAction = "" + actionCounter = 0 + } + + function resetViewport() { + currentZoomStep = 0 + viewportCentered = false + } + + function resetDocumentation() { + currentDocumentationURL = '' + } - function resetViewport() { - currentZoomStep = 0 - viewportCentered = false - } + function resetRepositionAtTimeMachine() { + repositionAtTimeMachineCounter = 0 + } - function resetDocumentation() { - currentDocumentationURL = '' + function resetPositionAtNode() { + positionAtNodeCounter = 0 + } } function checkForceFocus() { @@ -718,16 +771,6 @@ function newTutorialSpace() { return } - /* - If there is a reference parent defined, we will uncollape the brach where it belongs. - */ - if (currentNode.payload.referenceParent !== undefined) { - if (currentNode.payload.referenceParent.payload !== undefined) { - if (currentNode.payload.referenceParent.payload.floatingObject !== undefined) { - currentNode.payload.referenceParent.payload.floatingObject.unCollapseParent() - } - } - } function findNextNode(node) { for (let i = 0; i < node.tutorialSteps.length; i++) { @@ -940,7 +983,7 @@ function newTutorialSpace() { if (definitionNode === undefined) { currentNode.payload.uiObject.setErrorMessage(nodeType + ' not found at Doc Schema or Concept Schema.') return - } + } } let definition = definitionNode.definition if (definition === undefined || definition === "") { From 1ecefe58132a579a9dfc44d320f5013a76b27181 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 10:07:32 +0200 Subject: [PATCH 166/192] Controling key pressed --- ChartingSpace/EdgeEditor.js | 7 +++++-- Spaces/TutorialSpace.js | 32 ++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/ChartingSpace/EdgeEditor.js b/ChartingSpace/EdgeEditor.js index d6d447ff1..1d85768ac 100644 --- a/ChartingSpace/EdgeEditor.js +++ b/ChartingSpace/EdgeEditor.js @@ -184,8 +184,11 @@ function newEdgeEditor() { } } - function onKeyPressed(event) { - if (whereIsMouseOver !== 'center' ) {return} + function onKeyPressed(event, forceExecution) { + if (forceExecution !== true) { + if (whereIsMouseOver !== 'center' ) {return} + } + const STEP = 10 if (event.shiftKey === false && event.ctrlKey === false && event.code === 'ArrowLeft') { diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 429a76cdc..8cbd07e7e 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -58,6 +58,7 @@ function newTutorialSpace() { let viewportCentered = false let repositionAtTimeMachineCounter = 0 let positionAtNodeCounter = 0 + let timeMachineKeyPressedCounter = 0 return thisObject @@ -321,8 +322,7 @@ function newTutorialSpace() { if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { let config = JSON.parse(currentNode.config) if ( - config.positionAtReferenceParent === true || - config.positionAtReferenceParent === undefined + config.positionAtReferenceParent === true ) { /* This moves the Designs Space so that the referenced node is at the center of the screen. @@ -398,6 +398,25 @@ function newTutorialSpace() { } else { lastExecutedAction = "" } + if ( + config.keyPressedTimeMachineReferenceParent !== undefined + ) { + if (currentNode.payload.referenceParent.type === 'Time Machine') { + let timeMachine = canvas.chartingSpace.findTimeMachine(currentNode.payload.referenceParent) + if (timeMachine !== undefined) { + timeMachineKeyPressedCounter++ + if (timeMachineKeyPressedCounter === 10) { + let event = { + shiftKey: config.keyPressedTimeMachineReferenceParent.shiftKey, + ctrlKey: config.keyPressedTimeMachineReferenceParent.ctrlKey, + code: config.keyPressedTimeMachineReferenceParent.code, + key: config.keyPressedTimeMachineReferenceParent.key + } + timeMachine.edgeEditor.onKeyPressed(event, true) + } + } + } + } if ( config.viewportCenterReferenceParent === true ) { @@ -589,17 +608,18 @@ function newTutorialSpace() { resetDocumentation() resetRepositionAtTimeMachine() resetPositionAtNode() + resetTimeMachineKeyPressed() function resetActions() { lastExecutedAction = "" actionCounter = 0 } - + function resetViewport() { currentZoomStep = 0 viewportCentered = false } - + function resetDocumentation() { currentDocumentationURL = '' } @@ -611,6 +631,10 @@ function newTutorialSpace() { function resetPositionAtNode() { positionAtNodeCounter = 0 } + + function resetTimeMachineKeyPressed() { + timeMachineKeyPressedCounter = 0 + } } function checkForceFocus() { From 0119673d92d0e05b64c960ce7426ab118354b988 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 11:11:42 +0200 Subject: [PATCH 167/192] keypressed --- Canvas.js | 5 ++- Spaces/TutorialSpace.js | 83 +++++++++++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/Canvas.js b/Canvas.js index 367429a5e..405509b6e 100644 --- a/Canvas.js +++ b/Canvas.js @@ -43,6 +43,7 @@ function newCanvas() { animation: undefined, mouse: undefined, shorcutNumbers: new Map(), + onKeyDown: onKeyDown, initialize: initialize, finalize: finalize } @@ -311,7 +312,9 @@ function newCanvas() { if (event.shiftKey === true && (event.ctrlKey === true || event.metaKey === true) && (event.key === 'S' || event.key === 's')) { canvas.designSpace.workspace.save() - event.preventDefault() + if (event.preventDefault !== undefined) { + event.preventDefault() + } return } diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 8cbd07e7e..56e1d5bcc 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -59,6 +59,8 @@ function newTutorialSpace() { let repositionAtTimeMachineCounter = 0 let positionAtNodeCounter = 0 let timeMachineKeyPressedCounter = 0 + let keyPressedCounter = 0 + let sliderPositioned = 0 return thisObject @@ -118,6 +120,7 @@ function newTutorialSpace() { } } + keyPressed() checkPressButton() checkGif() checkImage() @@ -129,6 +132,26 @@ function newTutorialSpace() { checkViewportZoomAtCenter() return + function keyPressed() { + if (currentNode === undefined) { return } + let config = JSON.parse(currentNode.config) + if ( + config.keyPressed !== undefined + ) { + keyPressedCounter++ + if (keyPressedCounter === 10) { + let event = { + metaKey: config.keyPressed.metaKey, + shiftKey: config.keyPressed.shiftKey, + ctrlKey: config.keyPressed.ctrlKey, + code: config.keyPressed.code, + key: config.keyPressed.key + } + canvas.onKeyDown(event, true) + } + } + } + function checkViewportZoom() { if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) @@ -284,28 +307,31 @@ function newTutorialSpace() { */ return } - switch (config.slider) { - case "toTop": { - /* - This forces the tutorial to close the charting space and to keep it closed. - */ - canvas.cockpitSpace.toTop() - return - } - case "toMiddle": { - /* - This forces the tutorial to share the screen half with the designer and half - with the charting space and force it in that way. - */ - canvas.cockpitSpace.toMiddle() - return - } - case "toBottom": { - /* - This forces the tutorial to fully open the charting space and to keep it open. - */ - canvas.cockpitSpace.toBottom() - return + if (sliderPositioned === false) { + sliderPositioned = true + switch (config.slider) { + case "toTop": { + /* + This forces the tutorial to close the charting space and to keep it closed. + */ + canvas.cockpitSpace.toTop() + return + } + case "toMiddle": { + /* + This forces the tutorial to share the screen half with the designer and half + with the charting space and force it in that way. + */ + canvas.cockpitSpace.toMiddle() + return + } + case "toBottom": { + /* + This forces the tutorial to fully open the charting space and to keep it open. + */ + canvas.cockpitSpace.toBottom() + return + } } } } @@ -322,7 +348,7 @@ function newTutorialSpace() { if (currentNode.payload.referenceParent.payload.uiObject !== undefined) { let config = JSON.parse(currentNode.config) if ( - config.positionAtReferenceParent === true + config.positionAtReferenceParent === true ) { /* This moves the Designs Space so that the referenced node is at the center of the screen. @@ -407,6 +433,7 @@ function newTutorialSpace() { timeMachineKeyPressedCounter++ if (timeMachineKeyPressedCounter === 10) { let event = { + metaKey: config.keyPressedTimeMachineReferenceParent.metaKey, shiftKey: config.keyPressedTimeMachineReferenceParent.shiftKey, ctrlKey: config.keyPressedTimeMachineReferenceParent.ctrlKey, code: config.keyPressedTimeMachineReferenceParent.code, @@ -609,6 +636,8 @@ function newTutorialSpace() { resetRepositionAtTimeMachine() resetPositionAtNode() resetTimeMachineKeyPressed() + resetKeyPressed() + resetSlider() function resetActions() { lastExecutedAction = "" @@ -635,6 +664,14 @@ function newTutorialSpace() { function resetTimeMachineKeyPressed() { timeMachineKeyPressedCounter = 0 } + + function resetKeyPressed() { + keyPressedCounter = 0 + } + + function resetSlider() { + sliderPositioned = false + } } function checkForceFocus() { From 89c4ad8780204cf74be6ef2399f70318ce69d8fd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 11:44:13 +0200 Subject: [PATCH 168/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 56e1d5bcc..0ea651583 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -61,6 +61,7 @@ function newTutorialSpace() { let timeMachineKeyPressedCounter = 0 let keyPressedCounter = 0 let sliderPositioned = 0 + let changeNodeConfigCounter = 0 return thisObject @@ -407,6 +408,18 @@ function newTutorialSpace() { currentNode.payload.referenceParent.payload.floatingObject.forceFocus() forcingFocus = true } + if ( + config.changeNodeConfigReferenceParent !== undefined + ) { + changeNodeConfigCounter++ + if (changeNodeConfigCounter === 5) { + let nodeConfig = JSON.parse(currentNode.payload.referenceParent.config) + for (const property in config.changeNodeConfigReferenceParent) { + nodeConfig[property] = config.changeNodeConfigReferenceParent[property] + } + currentNode.payload.referenceParent.config = JSON.stringify(nodeConfig) + } + } if ( config.menuActionReferenceParent !== undefined ) { @@ -638,6 +651,7 @@ function newTutorialSpace() { resetTimeMachineKeyPressed() resetKeyPressed() resetSlider() + changeNodeConfig() function resetActions() { lastExecutedAction = "" @@ -672,6 +686,10 @@ function newTutorialSpace() { function resetSlider() { sliderPositioned = false } + + function changeNodeConfig() { + changeNodeConfigCounter = 0 + } } function checkForceFocus() { From 584b721a8698d0ab7fbe700194098683ec8ed5e6 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 14:15:55 +0200 Subject: [PATCH 169/192] Task Syncronization with Backend --- .../FunctionLibraries/TaskFunctions.js | 6 ++--- .../FunctionLibraries/UiObjectsFromNodes.js | 26 ++++++++----------- DesignSpace/Workspace/Workspace.js | 4 +-- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js index a7913454e..615c8dd2a 100644 --- a/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js @@ -1,6 +1,6 @@ function newTaskFunctions() { thisObject = { - getReady: getReady, + syncronizeTaskWithBackEnd: syncronizeTaskWithBackEnd, runTask: runTask, stopTask: stopTask, @@ -35,7 +35,7 @@ function newTaskFunctions() { return thisObject - function getReady(node) { + function syncronizeTaskWithBackEnd(node) { let networkNode = validations(node) if (networkNode === undefined) { /* Nodes that do not belong to a network can not get ready. */ @@ -56,7 +56,7 @@ function newTaskFunctions() { function onStatus(message) { eventsServerClient.stopListening(key, eventSubscriptionIdOnStatus, node.id) if (message.event.status === 'Task Process Running' ) { - node.payload.uiObject.run() + node.payload.uiObject.menu.internalClick('Run Task') } } diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index c3f52c5a9..093bcef29 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -1,6 +1,6 @@ function newUiObjectsFromNodes() { thisObject = { - runTasks: runTasks, + syncronizeTasksFoundAtWorkspaceWithBackEnd: syncronizeTasksFoundAtWorkspaceWithBackEnd, runSessions: runSessions, playTutorials: playTutorials, recreateWorkspace: recreateWorkspace, @@ -13,7 +13,7 @@ function newUiObjectsFromNodes() { let mapOfReferenceChildren = new Map() let mapOfNodes - let tasksToRun + let tasksFoundAtWorkspace let sessionsToRun let tutorialsToPlay @@ -25,7 +25,7 @@ function newUiObjectsFromNodes() { function recreateWorkspace(node, callBackFunction) { mapOfNodes = new Map() - tasksToRun = [] + tasksFoundAtWorkspace = [] sessionsToRun = [] tutorialsToPlay = [] @@ -150,12 +150,12 @@ function newUiObjectsFromNodes() { } } - function runTasks() { - for (let i = 0; i < tasksToRun.length; i++) { - let node = tasksToRun[i] - node.payload.uiObject.menu.internalClick('Run Task') + function syncronizeTasksFoundAtWorkspaceWithBackEnd(functionLibraryTaskFunctions) { + for (let i = 0; i < tasksFoundAtWorkspace.length; i++) { + let node = tasksFoundAtWorkspace[i] + functionLibraryTaskFunctions.syncronizeTaskWithBackEnd(node) } - tasksToRun = undefined + tasksFoundAtWorkspace = undefined } function runSessions() { @@ -625,14 +625,10 @@ function newUiObjectsFromNodes() { /* This is the point where we build a map with all nodes present at the workspace */ mapOfNodes.set(node.id, node) - /* Check if there are tasks to run */ + /* We will collect all tasks at the workspace in order to later syncronize them with the backend */ if (userAddingNew === false && uiObjectType === 'Task' && node.savedPayload !== undefined) { - if (node.savedPayload.uiObject.isRunning === true) { - if (node.payload.parentNode !== undefined) { - if (tasksToRun !== undefined) { // it might be undefined when you are spawning a task that was running while backed up - tasksToRun.push(node) - } - } + if (tasksFoundAtWorkspace !== undefined) { // it might be undefined when you are spawning a task that was backed up + tasksFoundAtWorkspace.push(node) } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 747baf496..92f5aec44 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -137,13 +137,13 @@ function newWorkspace() { function runTasksAndSessions(replacingCurrentWorkspace) { if (replacingCurrentWorkspace === true) { // We need to wait all tasks that were potentially running to stop - setTimeout(functionLibraryUiObjectsFromNodes.runTasks, 70000) + setTimeout(functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd, 70000) // We give a few seconds for the tasks to start setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 80000) // We give a few seconds setTimeout(functionLibraryUiObjectsFromNodes.playTutorials, 3000) } else { - functionLibraryUiObjectsFromNodes.runTasks() + functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd(functionLibraryTaskFunctions) // We give a few seconds for the tasks to start setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 10000) // We give a few seconds From 80cd7cf54cc920c0631f9ce91dc7187811f0c562 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 18:22:08 +0200 Subject: [PATCH 170/192] Update Workspace.js --- DesignSpace/Workspace/Workspace.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 92f5aec44..9862ed205 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -136,8 +136,7 @@ function newWorkspace() { function runTasksAndSessions(replacingCurrentWorkspace) { if (replacingCurrentWorkspace === true) { - // We need to wait all tasks that were potentially running to stop - setTimeout(functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd, 70000) + functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd(functionLibraryTaskFunctions) // We give a few seconds for the tasks to start setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 80000) // We give a few seconds @@ -294,9 +293,11 @@ function newWorkspace() { workingAtTask++ break case 5: - functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode) - setupEventsServerClients() - runTasksAndSessions(true) + functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, finishInitialization) + function finishInitialization(){ + setupEventsServerClients() + runTasksAndSessions(true) + } workingAtTask++ break case 6: From 47e6a5e46811993740830225cd656e106cca1e7b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 25 Sep 2020 20:20:14 +0200 Subject: [PATCH 171/192] Session Syncronization --- .../FunctionLibraries/SessionFunctions.js | 35 ++++++++++++++++--- .../FunctionLibraries/UiObjectsFromNodes.js | 24 ++++++------- DesignSpace/Workspace/Workspace.js | 27 ++++++-------- FloatingSpace/UiObject.js | 3 +- 4 files changed, 52 insertions(+), 37 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 7a92aa824..6a53cd293 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -1,11 +1,41 @@ function newSessionFunctions() { thisObject = { + syncronizeSessionWithBackEnd: syncronizeSessionWithBackEnd, runSession: runSession, stopSession: stopSession } return thisObject + function syncronizeSessionWithBackEnd(node) { + let networkNode = validations(node) + if (networkNode === undefined) { + /* Nodes that do not belong to a network can not get ready. */ + return + } + + let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id) + + /* First we setup everything so as to listen to the response from the Task Server */ + let eventSubscriptionIdOnStatus + let key = node.name + '-' + node.type + '-' + node.id + eventsServerClient.listenToEvent(key, 'Status Response', undefined, node.id, onResponse, onStatus) + + function onResponse(message) { + eventSubscriptionIdOnStatus = message.eventSubscriptionId + } + + function onStatus(message) { + eventsServerClient.stopListening(key, eventSubscriptionIdOnStatus, node.id) + if (message.event.status === 'Session Runnning' ) { + node.payload.uiObject.menu.internalClick('Run Session') + } + } + + /* Second we ask the Task Server if this Session is Running. */ + eventsServerClient.raiseEvent(key, 'Session Status') + } + function runSession(node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, resume, callBackFunction) { let networkNode = validations(node) if (networkNode === undefined) { @@ -179,11 +209,6 @@ function newSessionFunctions() { let networkNode = taskManager.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode - if (node.payload.parentNode.payload.uiObject.isRunning !== true) { - node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running.') - return - } - if (node.tradingSystemReference === undefined) { node.payload.uiObject.setErrorMessage('Session needs a child Trading System Reference.') return diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 093bcef29..19c135c59 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -1,7 +1,7 @@ function newUiObjectsFromNodes() { thisObject = { syncronizeTasksFoundAtWorkspaceWithBackEnd: syncronizeTasksFoundAtWorkspaceWithBackEnd, - runSessions: runSessions, + syncronizeSessionsFoundAtWorkspaceWithBackEnd: syncronizeSessionsFoundAtWorkspaceWithBackEnd, playTutorials: playTutorials, recreateWorkspace: recreateWorkspace, getNodeById: getNodeById, @@ -14,7 +14,7 @@ function newUiObjectsFromNodes() { let mapOfReferenceChildren = new Map() let mapOfNodes let tasksFoundAtWorkspace - let sessionsToRun + let sessionsFoundAtWorkspace let tutorialsToPlay return thisObject @@ -26,7 +26,7 @@ function newUiObjectsFromNodes() { function recreateWorkspace(node, callBackFunction) { mapOfNodes = new Map() tasksFoundAtWorkspace = [] - sessionsToRun = [] + sessionsFoundAtWorkspace = [] tutorialsToPlay = [] removeNullRootNodes() @@ -158,12 +158,12 @@ function newUiObjectsFromNodes() { tasksFoundAtWorkspace = undefined } - function runSessions() { - for (let i = 0; i < sessionsToRun.length; i++) { - let node = sessionsToRun[i] - node.payload.uiObject.menu.internalClick('Run Session') + function syncronizeSessionsFoundAtWorkspaceWithBackEnd(functionLibrarySessionFunctions) { + for (let i = 0; i < sessionsFoundAtWorkspace.length; i++) { + let node = sessionsFoundAtWorkspace[i] + functionLibrarySessionFunctions.syncronizeSessionWithBackEnd(node) } - sessionsToRun = undefined + sessionsFoundAtWorkspace = undefined } function playTutorials() { @@ -635,12 +635,8 @@ function newUiObjectsFromNodes() { /* Check if there are sessions to run */ if (userAddingNew === false && node.savedPayload !== undefined) { if (uiObjectType === 'Live Trading Session' || uiObjectType === 'Forward Testing Session' || uiObjectType === 'Backtesting Session' || uiObjectType === 'Paper Trading Session') { - if (node.savedPayload.uiObject.isRunning === true) { - if (node.payload.parentNode !== undefined) { - if (sessionsToRun !== undefined) { // it might be undefined when you are spawning a session that was running while backed up - sessionsToRun.push(node) - } - } + if (sessionsFoundAtWorkspace !== undefined) { // it might be undefined when you are spawning a session that was running while backed up + sessionsFoundAtWorkspace.push(node) } } } diff --git a/DesignSpace/Workspace/Workspace.js b/DesignSpace/Workspace/Workspace.js index 9862ed205..705a02555 100644 --- a/DesignSpace/Workspace/Workspace.js +++ b/DesignSpace/Workspace/Workspace.js @@ -122,7 +122,7 @@ function newWorkspace() { function finishInitialization() { setupEventsServerClients() - runTasksAndSessions(false) + runTasksAndSessions() thisObject.enabled = true canvas.cockpitSpace.initializePosition() canvas.splashScreen.initialize() @@ -134,20 +134,13 @@ function newWorkspace() { } } - function runTasksAndSessions(replacingCurrentWorkspace) { - if (replacingCurrentWorkspace === true) { - functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd(functionLibraryTaskFunctions) - // We give a few seconds for the tasks to start - setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 80000) - // We give a few seconds - setTimeout(functionLibraryUiObjectsFromNodes.playTutorials, 3000) - } else { - functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd(functionLibraryTaskFunctions) - // We give a few seconds for the tasks to start - setTimeout(functionLibraryUiObjectsFromNodes.runSessions, 10000) - // We give a few seconds - setTimeout(functionLibraryUiObjectsFromNodes.playTutorials, 1000) - } + function runTasksAndSessions() { + + functionLibraryUiObjectsFromNodes.syncronizeTasksFoundAtWorkspaceWithBackEnd(functionLibraryTaskFunctions) + functionLibraryUiObjectsFromNodes.syncronizeSessionsFoundAtWorkspaceWithBackEnd(functionLibrarySessionFunctions) + + setTimeout(functionLibraryUiObjectsFromNodes.playTutorials, 5000) + } function setupEventsServerClients() { @@ -294,9 +287,9 @@ function newWorkspace() { break case 5: functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, finishInitialization) - function finishInitialization(){ + function finishInitialization() { setupEventsServerClients() - runTasksAndSessions(true) + runTasksAndSessions() } workingAtTask++ break diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index dfef9b09f..91a22d8c0 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -980,7 +980,7 @@ function newUiObject() { /* We will wait to hear the Running event in order to confirm the execution was really started */ let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning) - + onRunningCallBackFunction = callBackFunction function onResponse(message) { @@ -988,6 +988,7 @@ function newUiObject() { } function onRunning() { + if (thisObject.payload === undefined) { return } let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id From bd14dc510d0f616987d11c8bb74e1900857cb037 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 26 Sep 2020 11:14:45 +0200 Subject: [PATCH 172/192] Update Plotter.js --- Plotting/Plotter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index 96cb8c927..14da86ad7 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -216,6 +216,7 @@ function newPlotter() { } else { fileCursor = dailyFiles.getFileCursor(pTimeFrame) } + recalculate() } } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] setTimeFrame -> err = ' + err.stack) } From 4ec6ef2cde8c0ed58408d67feb501ec811723a25 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 26 Sep 2020 12:57:38 +0200 Subject: [PATCH 173/192] Gifs for Tutorial --- Canvas.js | 44 ++++++++++++++++++++++++++++++++++++++++- Spaces/TutorialSpace.js | 16 ++++++++++----- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Canvas.js b/Canvas.js index 405509b6e..65d8aff93 100644 --- a/Canvas.js +++ b/Canvas.js @@ -43,7 +43,7 @@ function newCanvas() { animation: undefined, mouse: undefined, shorcutNumbers: new Map(), - onKeyDown: onKeyDown, + onKeyDown: onKeyDown, initialize: initialize, finalize: finalize } @@ -216,12 +216,48 @@ function newCanvas() { browserCanvas.width = window.innerWidth browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN + browserCanvas.style = "position:absolute; top:0px; left:0px; z-index:1" } function checkMediaRecording(event) { if ((event.ctrlKey === true || event.metaKey === true)) { let constructorParams switch (event.keyCode) { + case 113: { // F2 + browserCanvas.width = 400 * 3 + browserCanvas.height = 580 * 3 + centerCanvar() + return + break + } + case 114: { // F2 + browserCanvas.width = 400 * 2 + browserCanvas.height = 580 * 2 + centerCanvar() + return + break + } + case 115: { // F3 + browserCanvas.width = 400 * 1.5 + browserCanvas.height = 580 * 1.5 + centerCanvar() + return + break + } + case 116: { // F5 + browserCanvas.width = 400 * 1 + browserCanvas.height = 580 * 1 + centerCanvar() + return + break + } + case 117: { // F6 + browserCanvas.width = window.innerWidth + browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN + centerCanvar() + return + break + } case 118: { // F7 downloadPanorama('Superalgos.Market.Panorama') return @@ -255,6 +291,12 @@ function newCanvas() { mediaRecorder.save() } } + + function centerCanvar() { + let top = (window.innerHeight - browserCanvas.height) / 2 + let left = (window.innerWidth - browserCanvas.width) / 2 + browserCanvas.style = "position:absolute; top:"+ top + "px; left:"+ left + "px; z-index:1" + } } function onKeyUp(event) { diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 0ea651583..b161f6d43 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -234,7 +234,7 @@ function newTutorialSpace() { currentGifName = newGifName htmlGif.src = 'Images/Tutorial/Gifs/' + currentGifName + '.gif' htmlGif.width = "400" - //htmlGif.height = "100" + htmlGif.height = "580" } function checkImage() { @@ -414,7 +414,7 @@ function newTutorialSpace() { changeNodeConfigCounter++ if (changeNodeConfigCounter === 5) { let nodeConfig = JSON.parse(currentNode.payload.referenceParent.config) - for (const property in config.changeNodeConfigReferenceParent) { + for (const property in config.changeNodeConfigReferenceParent) { nodeConfig[property] = config.changeNodeConfigReferenceParent[property] } currentNode.payload.referenceParent.config = JSON.stringify(nodeConfig) @@ -533,7 +533,13 @@ function newTutorialSpace() { const MARGIN = 100 const FORM_HEIGHT = 40 - let nodeConfig = JSON.parse(currentNode.config) + let nodeConfig + try { + nodeConfig = JSON.parse(currentNode.config) + } catch (err) { + return + } + switch (nodeConfig.position) { case 'Left': { tutorialPosition = { @@ -972,7 +978,7 @@ function newTutorialSpace() { if (nodeConfig.title !== undefined && nodeConfig.title !== '') { html = html + '

    ' + nodeConfig.title + '

    ' } else { - if (currentNode.name !== 'New ' + currentNode.type) { + if (currentNode.name !== 'New ' + currentNode.type && currentNode.name !== 'My ' + currentNode.type) { html = html + '

    ' + currentNode.name + '

    ' } } @@ -984,7 +990,7 @@ function newTutorialSpace() { html = html + '

    ' + nodeConfig.subTitle + '

    ' } if (nodeConfig.gif !== undefined && nodeConfig.gif !== '') { - html = html + '
    ' + html = html + '
    ' newGifName = nodeConfig.gif } From 2649139f7db3037463f2d1b8e25969536c5a9817 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 26 Sep 2020 20:32:06 +0200 Subject: [PATCH 174/192] fix --- Canvas.js | 18 ++++++++++++------ Globals.js | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Canvas.js b/Canvas.js index 65d8aff93..6272170dc 100644 --- a/Canvas.js +++ b/Canvas.js @@ -226,35 +226,40 @@ function newCanvas() { case 113: { // F2 browserCanvas.width = 400 * 3 browserCanvas.height = 580 * 3 - centerCanvar() + centerCanvas() + DISABLE_BROWSER_RESIZE_EVENT = true return break } case 114: { // F2 browserCanvas.width = 400 * 2 browserCanvas.height = 580 * 2 - centerCanvar() + centerCanvas() + DISABLE_BROWSER_RESIZE_EVENT = true return break } case 115: { // F3 browserCanvas.width = 400 * 1.5 browserCanvas.height = 580 * 1.5 - centerCanvar() + centerCanvas() + DISABLE_BROWSER_RESIZE_EVENT = true return break } case 116: { // F5 browserCanvas.width = 400 * 1 browserCanvas.height = 580 * 1 - centerCanvar() + centerCanvas() + DISABLE_BROWSER_RESIZE_EVENT = true return break } case 117: { // F6 browserCanvas.width = window.innerWidth browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN - centerCanvar() + centerCanvas() + DISABLE_BROWSER_RESIZE_EVENT = false return break } @@ -292,7 +297,8 @@ function newCanvas() { } } - function centerCanvar() { + function centerCanvas() { + return let top = (window.innerHeight - browserCanvas.height) / 2 let left = (window.innerWidth - browserCanvas.width) / 2 browserCanvas.style = "position:absolute; top:"+ top + "px; left:"+ left + "px; z-index:1" diff --git a/Globals.js b/Globals.js index 1d33cfb9b..35a75f364 100644 --- a/Globals.js +++ b/Globals.js @@ -48,6 +48,8 @@ const ZOOM_OUT_THRESHOLD_FOR_DISPLAYING_SCALES = 3 let FONT_ASPECT_RATIO = 0.32; let ANIMATION_FRAME_PER_SECONDS +let DISABLE_BROWSER_RESIZE_EVENT = false + const GET_CONTAINER_PURPOSE = { MOUSE_OVER: 1, MOUSE_WHEEL: 2, From 3635075629065314106b4700a57320cfac6609b6 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 27 Sep 2020 13:33:03 +0200 Subject: [PATCH 175/192] fix --- Canvas.js | 6 ++++-- Spaces/TutorialSpace.js | 6 +----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Canvas.js b/Canvas.js index 6272170dc..e86122018 100644 --- a/Canvas.js +++ b/Canvas.js @@ -274,11 +274,13 @@ function newCanvas() { break } case 120: { // F9 - constructorParams = { format: 'gif', workersPath: 'externalScripts/', framerate: 8, name: 'Superalgos.Video.Capture' } + console.log('Recording gid with framerate = ' + 24) + constructorParams = { format: 'gif', workersPath: 'externalScripts/', framerate: 24, name: 'Superalgos.Video.Capture' } break } case 121: { // F10 - constructorParams = { format: 'webm', framerate: 8, name: 'Superalgos.Video.Capture' } + console.log('Recording gid with framerate = ' + 24) + constructorParams = { format: 'webm', framerate: 24, name: 'Superalgos.Video.Capture' } break } default: return diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index b161f6d43..8e359c08a 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -977,11 +977,7 @@ function newTutorialSpace() { let html = '' if (nodeConfig.title !== undefined && nodeConfig.title !== '') { html = html + '

    ' + nodeConfig.title + '

    ' - } else { - if (currentNode.name !== 'New ' + currentNode.type && currentNode.name !== 'My ' + currentNode.type) { - html = html + '

    ' + currentNode.name + '

    ' - } - } + } html = html + '
    ' if (nodeConfig.summary !== undefined && nodeConfig.summary !== '') { html = html + '
    ' + addToolTips(nodeConfig.summary) + '
    ' From e36427fc344664e199d387871af32f497f9a9a85 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 27 Sep 2020 13:57:47 +0200 Subject: [PATCH 176/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 8e359c08a..8e9c4b36c 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -495,6 +495,29 @@ function newTutorialSpace() { } } } + if ( + config.repositionAtTimeMachineNoZoomReferenceParent === true + ) { + if (currentNode.payload.referenceParent.type === 'Time Machine') { + let timeMachine = canvas.chartingSpace.findTimeMachine(currentNode.payload.referenceParent) + if (timeMachine !== undefined) { + repositionAtTimeMachineCounter++ + switch (true) { + case (repositionAtTimeMachineCounter > 10 && repositionAtTimeMachineCounter < 20): { + let event = { + delta: -1 + } + canvas.chartingSpace.viewport.onMouseWheel(event) + break + } + case (repositionAtTimeMachineCounter === 30): { + canvas.chartingSpace.viewport.displaceToContainer(timeMachine.container) + break + } + } + } + } + } } } } From 6d955431dfec77eca999f1bfa3b761f6b1225e8c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 28 Sep 2020 18:18:08 +0200 Subject: [PATCH 177/192] Update FloatingObject.js --- FloatingSpace/FloatingObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 7a717d583..c598f0d88 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -322,7 +322,7 @@ function newFloatingObject() { function positionContraintsPhysics() { const MAX_DISTANCE_TO_PARENT = 5000 const MIN_DISTANCE_TO_PARENT = 100 - const DEFAULT_NODE_TO_NODE_DISTANCE = 400 + const DEFAULT_NODE_TO_NODE_DISTANCE = 500 if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) { let parent = thisObject.payload.chainParent From 6b9b6040ae8c2ab66e6b2de8e55d33879e2c99bf Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 29 Sep 2020 10:29:48 +0200 Subject: [PATCH 178/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 74 +++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 8e9c4b36c..496af8b75 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -62,6 +62,8 @@ function newTutorialSpace() { let keyPressedCounter = 0 let sliderPositioned = 0 let changeNodeConfigCounter = 0 + let documentationCounter = 0 + let batchConfigChangesCounter = 0 return thisObject @@ -254,24 +256,27 @@ function newTutorialSpace() { if (currentNode === undefined) { return } let config = JSON.parse(currentNode.config) let newDocumentationURL = config.documentationURL - if (newDocumentationURL === undefined) { - /* - The doc panel will remain as it is, and the user will be free to open or close it at will. - */ - return - } - if (newDocumentationURL === "") { - /* - This forces the tutorial to close the documentation panel and to keep it closed. - */ - canvas.docSpace.sidePanelTab.close() - return - } - canvas.docSpace.sidePanelTab.open() - if (newDocumentationURL === currentDocumentationURL) { return } + documentationCounter++ + if (documentationCounter === 10) { + if (newDocumentationURL === undefined) { + /* + The doc panel will remain as it is, and the user will be free to open or close it at will. + */ + return + } + if (newDocumentationURL === "") { + /* + This forces the tutorial to close the documentation panel and to keep it closed. + */ + canvas.docSpace.sidePanelTab.close() + return + } + canvas.docSpace.sidePanelTab.open() + if (newDocumentationURL === currentDocumentationURL) { return } - currentDocumentationURL = newDocumentationURL - canvas.docSpace.navigateTo(currentDocumentationURL) + currentDocumentationURL = newDocumentationURL + canvas.docSpace.navigateTo(currentDocumentationURL) + } } function checkWorkspaces() { @@ -408,6 +413,33 @@ function newTutorialSpace() { currentNode.payload.referenceParent.payload.floatingObject.forceFocus() forcingFocus = true } + if ( + config.batchConfigChangesReferenceParent !== undefined + ) { + batchConfigChangesCounter++ + if (batchConfigChangesCounter === 5) { + /* + Here we are going to process an array of different changes to descendents + of the reference parent. The end user needs to specify a nodePath to the + descendent and an object with the properties and new values that want to + change at each descendent. The nodePath route starts at the object + referenceParent. + */ + let referenceParent = currentNode.payload.referenceParent + for (let i = 0; i < config.batchConfigChangesReferenceParent.length; i++) { + let arrayItem = config.batchConfigChangesReferenceParent[i] + let nodePath = arrayItem.nodePath + let properties = arrayItem.properties + + let childNode = eval(nodePath) + let nodeConfig = JSON.parse(childNode.config) + for (const property in properties) { + nodeConfig[property] = properties[property] + } + childNode.config = JSON.stringify(nodeConfig, undefined, 5) + } + } + } if ( config.changeNodeConfigReferenceParent !== undefined ) { @@ -681,6 +713,7 @@ function newTutorialSpace() { resetKeyPressed() resetSlider() changeNodeConfig() + batchConfigChanges() function resetActions() { lastExecutedAction = "" @@ -694,6 +727,7 @@ function newTutorialSpace() { function resetDocumentation() { currentDocumentationURL = '' + documentationCounter = 0 } function resetRepositionAtTimeMachine() { @@ -719,6 +753,10 @@ function newTutorialSpace() { function changeNodeConfig() { changeNodeConfigCounter = 0 } + + function batchConfigChanges() { + batchConfigChangesCounter = 0 + } } function checkForceFocus() { @@ -1000,7 +1038,7 @@ function newTutorialSpace() { let html = '' if (nodeConfig.title !== undefined && nodeConfig.title !== '') { html = html + '

    ' + nodeConfig.title + '

    ' - } + } html = html + '
    ' if (nodeConfig.summary !== undefined && nodeConfig.summary !== '') { html = html + '
    ' + addToolTips(nodeConfig.summary) + '
    ' From 51d922332846d6c9de185730abae092774469113 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 29 Sep 2020 15:37:43 +0200 Subject: [PATCH 179/192] Viewport adjustments --- ChartingSpace/CoordinateSystem.js | 2 +- ChartingSpace/Viewport.js | 4 ++-- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChartingSpace/CoordinateSystem.js b/ChartingSpace/CoordinateSystem.js index de7f0eacf..4a085c3fa 100644 --- a/ChartingSpace/CoordinateSystem.js +++ b/ChartingSpace/CoordinateSystem.js @@ -24,7 +24,7 @@ function newCoordinateSystem() { autoMinYScale: true, autoMaxYScale: true, HORIZONTAL_MARGIN_FACTOR: 1, - VERTICAL_MARGIN_FACTOR: 1, + VERTICAL_MARGIN_FACTOR: 0.9, HORIZONTAL_MARGIN_INVERSE_FACTOR: 0, VERTICAL_MARGIN_INVERSE_FACTOR: 0, physics: physics, diff --git a/ChartingSpace/Viewport.js b/ChartingSpace/Viewport.js index 57d787c6d..15c6cf2ea 100644 --- a/ChartingSpace/Viewport.js +++ b/ChartingSpace/Viewport.js @@ -9,7 +9,7 @@ function newViewport() { let ANIMATION_STEPS = 5 let TOP_MARGIN = 40 + TOP_SPACE_HEIGHT - let BOTTOM_MARGIN = 42 + COCKPIT_SPACE_HEIGHT + let BOTTOM_MARGIN = 2 + COCKPIT_SPACE_HEIGHT let LEFT_MARGIN = 0 let RIGHT_MARGIN = 0 let MARGINS = { @@ -99,7 +99,7 @@ function newViewport() { function resize() { TOP_MARGIN = 40 + TOP_SPACE_HEIGHT - BOTTOM_MARGIN = 42 + browserCanvas.height - COCKPIT_SPACE_POSITION + BOTTOM_MARGIN = 2 + browserCanvas.height - COCKPIT_SPACE_POSITION LEFT_MARGIN = 0 RIGHT_MARGIN = 0 MARGINS = { diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index 6a53cd293..c82188239 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -135,7 +135,11 @@ function newSessionFunctions() { resume: resume } - eventsServerClient.raiseEvent(key, 'Run Session', event) + if (resume !== true) { + eventsServerClient.raiseEvent(key, 'Run Session', event) + } else { + eventsServerClient.raiseEvent(key, 'Resume Session', event) + } if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) From 2426cb06febb1a419082f95a233cebdc14b6b388 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 29 Sep 2020 15:44:10 +0200 Subject: [PATCH 180/192] Update Viewport.js --- ChartingSpace/Viewport.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChartingSpace/Viewport.js b/ChartingSpace/Viewport.js index 15c6cf2ea..393381514 100644 --- a/ChartingSpace/Viewport.js +++ b/ChartingSpace/Viewport.js @@ -9,7 +9,7 @@ function newViewport() { let ANIMATION_STEPS = 5 let TOP_MARGIN = 40 + TOP_SPACE_HEIGHT - let BOTTOM_MARGIN = 2 + COCKPIT_SPACE_HEIGHT + let BOTTOM_MARGIN = 10 + 2 + COCKPIT_SPACE_HEIGHT let LEFT_MARGIN = 0 let RIGHT_MARGIN = 0 let MARGINS = { @@ -99,7 +99,7 @@ function newViewport() { function resize() { TOP_MARGIN = 40 + TOP_SPACE_HEIGHT - BOTTOM_MARGIN = 2 + browserCanvas.height - COCKPIT_SPACE_POSITION + BOTTOM_MARGIN = 10 + 2 + browserCanvas.height - COCKPIT_SPACE_POSITION LEFT_MARGIN = 0 RIGHT_MARGIN = 0 MARGINS = { From b418005a8944db041890ec6edd4447a821f609b9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 30 Sep 2020 09:19:02 +0200 Subject: [PATCH 181/192] Update UiObjectsFromNodes.js --- DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js index 19c135c59..8a5e00c4d 100644 --- a/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js +++ b/DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js @@ -106,7 +106,7 @@ function newUiObjectsFromNodes() { for (let i = 0; i < node.rootNodes.length; i++) { let rootNode = node.rootNodes[i] if (rootNode.id === receivedNode.id) { - rootNodes.splice(i, 1) + node.rootNodes.splice(i, 1) break } } From e901e523482b69f792e2ea0eb8763562cb4169a5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 30 Sep 2020 13:07:40 +0200 Subject: [PATCH 182/192] Dynamic Indicators --- DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js index c82188239..9bf6c6c14 100644 --- a/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -52,9 +52,7 @@ function newSessionFunctions() { let lightingPath = '' + 'Trading System->' + - 'Parameters->' + - 'Base Asset->Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->' + - 'Exchange Account Asset->Asset->' + + 'Dynamic Indicators->Indicator Function->Formula->' + 'Trading Strategy->' + 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + 'Announcement->Announcement Formula->' + From 031cf03e36ba8d1031509e3d2115c7e91f12db89 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 30 Sep 2020 16:57:47 +0200 Subject: [PATCH 183/192] Error Messages Improved --- Canvas.js | 4 ++++ FloatingSpace/UiObject.js | 45 +++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Canvas.js b/Canvas.js index e86122018..e926c5acf 100644 --- a/Canvas.js +++ b/Canvas.js @@ -507,6 +507,7 @@ function newCanvas() { if (event.code === 'Period') { if (nodeOnFocus !== undefined) { + nodeOnFocus.payload.uiObject.valueAtAngle = false nodeOnFocus.payload.uiObject.setValue('Id: ' + nodeOnFocus.id) return } @@ -530,6 +531,7 @@ function newCanvas() { if (nodeUsingThisKey !== undefined && nodeOnFocus !== undefined) { if (nodeUsingThisKey.id === nodeOnFocus.id) { nodeOnFocus.payload.uiObject.shortcutKey = '' + nodeOnFocus.payload.uiObject.valueAtAngle = false nodeOnFocus.payload.uiObject.setValue('Shortcut Key Removed ') return } else { @@ -537,6 +539,7 @@ function newCanvas() { nodeUsingThisKey.payload.uiObject.shortcutKey = '' nodeUsingThisKey === undefined nodeOnFocus.payload.uiObject.shortcutKey = event.key + nodeOnFocus.payload.uiObject.valueAtAngle = false nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + event.key) } } @@ -546,6 +549,7 @@ function newCanvas() { if (event.ctrlKey === true && event.altKey === true && nodeOnFocus !== undefined) { if (nodeOnFocus.payload.uiObject.shortcutKey !== undefined && nodeOnFocus.payload.uiObject.shortcutKey !== '') { + nodeOnFocus.payload.uiObject.valueAtAngle = false nodeOnFocus.payload.uiObject.setValue('Shortcut Key: Ctrl + Alt + ' + nodeOnFocus.payload.uiObject.shortcutKey) } } diff --git a/FloatingSpace/UiObject.js b/FloatingSpace/UiObject.js index 91a22d8c0..9fa1f1cdc 100644 --- a/FloatingSpace/UiObject.js +++ b/FloatingSpace/UiObject.js @@ -619,7 +619,7 @@ function newUiObject() { let distance = nearby[0] let floatingObject = nearby[1] let nearbyNode = floatingObject.payload.node - if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0 || compatibleTypes === "->*Any Node*->" ) { + if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0 || compatibleTypes === "->*Any Node*->") { if (nodeDefinition.referenceAttachesTo.incompatibleTypes !== undefined) { if (nodeDefinition.referenceAttachesTo.incompatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) { continue @@ -982,26 +982,26 @@ function newUiObject() { eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning) onRunningCallBackFunction = callBackFunction - + function onResponse(message) { eventSubscriptionIdOnRunning = message.eventSubscriptionId } - + function onRunning() { if (thisObject.payload === undefined) { return } - + let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject') - + thisObject.isRunning = true - + if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) onRunningCallBackFunctionWasCalled = true } } - + /* While it is running, it can happen that it naturally stops or is stopped not from the UI but from other means. In those cases, the stop function would never be called (from the UI). So what we will do is to call it from @@ -1012,7 +1012,7 @@ function newUiObject() { If on the other side, it is executed from the UI, then we will be processing the Stopped event twice, which in both cases will reset the menu item to its default state. */ - + let event = { type: 'Secondary Action Already Executed' } @@ -1022,45 +1022,45 @@ function newUiObject() { function setupErrorEventListener(callBackFunction) { let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError) - + function onResponse(message) { eventSubscriptionIdOnError = message.eventSubscriptionId } - + function onError(message) { - + let uiObject = getTargetUiObject(message) uiObject.setErrorMessage(message.event.errorMessage, 10) - + let event = { type: 'Secondary Action Already Executed' } completeStop(callBackFunction, event) } } - + function setupWarningEventListener() { let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id eventsServerClient.listenToEvent(key, 'Warning', undefined, key, onResponse, onWarning) - + function onResponse(message) { eventSubscriptionIdOnWarning = message.eventSubscriptionId } - + function onWarning(message) { let uiObject = getTargetUiObject(message) uiObject.setWarningMessage(message.event.warningMessage, 10) } } - + function setupInfoEventListener() { let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id eventsServerClient.listenToEvent(key, 'Info', undefined, key, onResponse, onInfo) - + function onResponse(message) { eventSubscriptionIdOnInfo = message.eventSubscriptionId } - + function onInfo(message) { let uiObject = getTargetUiObject(message) uiObject.setInfoMessage(message.event.infoMessage, 10) @@ -1600,13 +1600,16 @@ function newUiObject() { let label if (radius > 6) { - const MAX_LABEL_LENGTH = 80 + const IDEAL_LABEL_LENGTH = 80 label = message if (label !== undefined && label !== null) { - if (label.length > MAX_LABEL_LENGTH) { - label = label.substring(0, MAX_LABEL_LENGTH) + '...' + if (label.length > IDEAL_LABEL_LENGTH) { + if (label.length > IDEAL_LABEL_LENGTH * 3) { + label = label.substring(0, IDEAL_LABEL_LENGTH * 3) + '...' + } + fontSize = thisObject.payload.floatingObject.currentFontSize * 2 / 4 } labelPoint = { From 123e2a0a1ad613ac14cd4219eccefe33e23d6b4b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Oct 2020 14:09:03 +0200 Subject: [PATCH 184/192] chat --- Canvas.js | 49 +++++++- FloatingSpace/CodeEditor.js | 2 +- FloatingSpace/ConditionEditor.js | 2 +- FloatingSpace/ConfigEditor.js | 2 +- FloatingSpace/FormulaEditor.js | 2 +- SideSpace/SidePanelTab.js | 12 +- Spaces/ChatSpace.js | 194 +++++++++++++++++++++++++++++++ Spaces/TutorialSpace.js | 37 +++++- 8 files changed, 288 insertions(+), 12 deletions(-) create mode 100644 Spaces/ChatSpace.js diff --git a/Canvas.js b/Canvas.js index e926c5acf..148ba2160 100644 --- a/Canvas.js +++ b/Canvas.js @@ -33,6 +33,7 @@ function newCanvas() { topSpace: undefined, sideSpace: undefined, docSpace: undefined, + chatSpace: undefined, tutorialSpace: undefined, chartingSpace: undefined, floatingSpace: undefined, @@ -66,6 +67,7 @@ function newCanvas() { try { thisObject.tutorialSpace.finalize() thisObject.docSpace.finalize() + //thisObject.chatSpace.finalize() thisObject.sideSpace.finalize() thisObject.chartingSpace.finalize() thisObject.floatingSpace.finalize() @@ -130,6 +132,9 @@ function newCanvas() { thisObject.docSpace = newDocSpace() thisObject.docSpace.initialize() + //thisObject.chatSpace = newChatSpace() + //thisObject.chatSpace.initialize() + thisObject.tutorialSpace = newTutorialSpace() thisObject.tutorialSpace.initialize() @@ -148,6 +153,7 @@ function newCanvas() { animation.addCallBackFunction('Panels Space Physics', thisObject.panelsSpace.physics) animation.addCallBackFunction('Side Space Physics', thisObject.sideSpace.physics) animation.addCallBackFunction('Doc Space Physics', thisObject.docSpace.physics) + //animation.addCallBackFunction('Chat Space Physics', thisObject.chatSpace.physics) animation.addCallBackFunction('Tutorial Space Physics', thisObject.tutorialSpace.physics) /* Spcaces Drawing */ @@ -159,6 +165,7 @@ function newCanvas() { animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw) animation.addCallBackFunction('Side Space Draw', thisObject.sideSpace.draw) animation.addCallBackFunction('Doc Space Draw', thisObject.docSpace.draw) + //animation.addCallBackFunction('Chat Space Draw', thisObject.chatSpace.draw) animation.addCallBackFunction('Tutorial Space Draw', thisObject.tutorialSpace.draw) animation.addCallBackFunction('Splash Screen Draw', thisObject.splashScreen.draw) animation.start() @@ -303,7 +310,7 @@ function newCanvas() { return let top = (window.innerHeight - browserCanvas.height) / 2 let left = (window.innerWidth - browserCanvas.width) / 2 - browserCanvas.style = "position:absolute; top:"+ top + "px; left:"+ left + "px; z-index:1" + browserCanvas.style = "position:absolute; top:" + top + "px; left:" + left + "px; z-index:1" } } @@ -664,6 +671,20 @@ function newCanvas() { return } + /* We check if the mouse is over an element of the Chat Space / */ + //container = thisObject.chatSpace.getContainer(point) + + if (container !== undefined && container.isDraggeable === true) { + containerBeingDragged = container + containerDragStarted = true + containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point) + return + } + + if (container !== undefined && container.isDraggeable === false) { + return + } + /* We check if the mouse is over an element of the Side Space / */ container = thisObject.sideSpace.getContainer(point) @@ -809,6 +830,14 @@ function newCanvas() { return } + /* We check if the mouse is over an element of the Chat Space / */ + //container = thisObject.chatSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) + + if (container !== undefined && container.isClickeable === true) { + container.eventHandler.raiseEvent('onMouseClick', point) + return + } + /* We check if the mouse is over an element of the Side Space / */ container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_CLICK) @@ -971,6 +1000,16 @@ function newCanvas() { } } + /* We check if the mouse is over an element of the Chat Space / */ + if (thisObject.chatSpace !== undefined) { + //container = thisObject.chatSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) + + if (container !== undefined && container.detectMouseOver === true) { + containerFound() + return + } + } + /* We check if the mouse is over an element of the Side Space / */ if (thisObject.sideSpace !== undefined) { container = thisObject.sideSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER) @@ -1095,6 +1134,14 @@ function newCanvas() { return false // This instructs the browser not to take the event and scroll the page. } + /* Chat Space */ + //container = canvas.chatSpace.getContainer({ x: point.x, y: point.y }) + + if (container !== undefined && container.isWheelable === true) { + container.eventHandler.raiseEvent('onMouseWheel', event) + return false // This instructs the browser not to take the event and scroll the page. + } + /* Side Space */ container = canvas.sideSpace.getContainer({ x: point.x, y: point.y }) diff --git a/FloatingSpace/CodeEditor.js b/FloatingSpace/CodeEditor.js index c490156c3..09d615a80 100644 --- a/FloatingSpace/CodeEditor.js +++ b/FloatingSpace/CodeEditor.js @@ -63,7 +63,7 @@ function newCodeEditor() { thisObject.rawRadius = 8 thisObject.targetRadius = thisObject.container.frame.radius thisObject.currentRadius = 0 - thisObject.payload.uiObject.setErrorMessage('', 0) + thisObject.payload.uiObject.resetErrorMessage() let textArea = document.getElementById('textArea') textArea.value = payload.node.code diff --git a/FloatingSpace/ConditionEditor.js b/FloatingSpace/ConditionEditor.js index 443c9f231..77ff9abed 100644 --- a/FloatingSpace/ConditionEditor.js +++ b/FloatingSpace/ConditionEditor.js @@ -80,7 +80,7 @@ function newConditionEditor() { function activate(payload) { thisObject.visible = true thisObject.payload = payload - thisObject.payload.uiObject.setErrorMessage('', 0) + thisObject.payload.uiObject.resetErrorMessage() conditionStructure = { code: '', diff --git a/FloatingSpace/ConfigEditor.js b/FloatingSpace/ConfigEditor.js index e8864a0e8..dee760f94 100644 --- a/FloatingSpace/ConfigEditor.js +++ b/FloatingSpace/ConfigEditor.js @@ -69,7 +69,7 @@ function newConfigEditor() { thisObject.rawRadius = 8 thisObject.targetRadius = thisObject.container.frame.radius thisObject.currentRadius = 0 - thisObject.payload.uiObject.setErrorMessage('', 0) + thisObject.payload.uiObject.resetErrorMessage() let textArea = document.getElementById('textArea') textArea.value = payload.node.config diff --git a/FloatingSpace/FormulaEditor.js b/FloatingSpace/FormulaEditor.js index 2a781b67c..e749b5c57 100644 --- a/FloatingSpace/FormulaEditor.js +++ b/FloatingSpace/FormulaEditor.js @@ -63,7 +63,7 @@ function newFormulaEditor() { thisObject.rawRadius = 8 thisObject.targetRadius = thisObject.container.frame.radius thisObject.currentRadius = 0 - thisObject.payload.uiObject.setErrorMessage('', 0) + thisObject.payload.uiObject.resetErrorMessage() let textArea = document.getElementById('textArea') textArea.value = payload.node.code diff --git a/SideSpace/SidePanelTab.js b/SideSpace/SidePanelTab.js index bd853f480..6c04ec2e5 100644 --- a/SideSpace/SidePanelTab.js +++ b/SideSpace/SidePanelTab.js @@ -4,6 +4,7 @@ function newSidePanelTab() { screenside: undefined, pointerDirection: undefined, container: undefined, + index: 0, open: open, close: close, resize: resize, @@ -30,8 +31,11 @@ function newSidePanelTab() { return thisObject - function initialize(screenside) { + function initialize(screenside, index) { thisObject.screenside = screenside + if (index !== undefined) [ + thisObject.index = index + ] switch (thisObject.screenside) { case 'left': { thisObject.pointerDirection = 'left' @@ -43,7 +47,7 @@ function newSidePanelTab() { } } thisObject.container.frame.width = TAB_WIDTH - thisObject.container.frame.height = TAB_HEIGHT + thisObject.container.frame.height = TAB_HEIGHT thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) resize() @@ -61,8 +65,8 @@ function newSidePanelTab() { break } } - - thisObject.container.frame.position.y = 69 + + thisObject.container.frame.position.y = 69 + 69 * thisObject.index ORIGINAL_PARENT_POSITON = thisObject.container.parentContainer.frame.position.x setClosed() } diff --git a/Spaces/ChatSpace.js b/Spaces/ChatSpace.js new file mode 100644 index 000000000..f429006f8 --- /dev/null +++ b/Spaces/ChatSpace.js @@ -0,0 +1,194 @@ +function newChatSpace() { + const MODULE_NAME = 'Chat Space' + let thisObject = { + sidePanelTab: undefined, + container: undefined, + navigateTo: navigateTo, + physics: physics, + draw: draw, + getContainer: getContainer, + initialize: initialize, + finalize: finalize + } + + let isInitialized = false + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + thisObject.container.isClickeable = true + thisObject.container.isDraggeable = false + thisObject.container.detectMouseOver = true + thisObject.container.status = 'hidden' + + resize() + + let browserResizedEventSubscriptionId + let openingEventSubscriptionId + let closingEventSubscriptionId + + const DEFAULT_URL = 'https://web.telegram.org/#/im?p=@superalgoscommunity' + return thisObject + + function initialize() { + + thisObject.sidePanelTab = newSidePanelTab() + thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false) + thisObject.sidePanelTab.initialize('right', 1) + openingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('opening', onOpening) + closingEventSubscriptionId = thisObject.sidePanelTab.container.eventHandler.listenToEvent('closing', onClosing) + + browserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize) + + isInitialized = true + } + + function finalize() { + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) + thisObject.sidePanelTab.container.eventHandler.stopListening(closingEventSubscriptionId) + } + + function onOpening() { + let docIFrame = document.getElementById('docIFrame') + if (docIFrame.src === "") { + docIFrame.src = DEFAULT_URL + } + } + + function onClosing() { + + } + + function navigateTo(url) { + let docIFrame = document.getElementById('docIFrame') + docIFrame.src = url + thisObject.sidePanelTab.open() + } + + function resize() { + thisObject.container.frame.width = 1200 + thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT + thisObject.container.frame.position.x = browserCanvas.width + thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT + + if (thisObject.sidePanelTab !== undefined) { + thisObject.sidePanelTab.resize() + } + } + + function getContainer(point, purpose) { + let container + + container = thisObject.sidePanelTab.getContainer(point, purpose) + if (container !== undefined) { return container } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + return thisObject.container + } else { + return undefined + } + } + + function physics() { + thisObject.sidePanelTab.physics() + chatAppDivPhysics() + iFramePhysics() + + function chatAppDivPhysics() { + let chatAppDiv = document.getElementById('chatApp') + chatAppDivPosition = { + x: 0, + y: 0 + } + chatAppDivPosition = thisObject.container.frame.frameThisPoint(chatAppDivPosition) + chatAppDiv.style = ' ' + + 'position:fixed; top:' + chatAppDivPosition.y + 'px; ' + + 'left:' + chatAppDivPosition.x + 'px; z-index:1; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + } + + function iFramePhysics() { + let docIFrame = document.getElementById('chatIFrame') + docIFrame.style = ' ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + } + } + + function draw() { + if (canWeDraw === false) { return } + if (isInitialized === false) { return } + borders() + thisObject.sidePanelTab.draw() + } + + function borders() { + let point1 + let point2 + let point3 + let point4 + + point1 = { + x: 0, + y: 0 + } + + point2 = { + x: thisObject.container.frame.width, + y: 0 + } + + point3 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + point4 = { + x: 0, + y: thisObject.container.frame.height + } + + point1 = thisObject.container.frame.frameThisPoint(point1) + point2 = thisObject.container.frame.frameThisPoint(point2) + point3 = thisObject.container.frame.frameThisPoint(point3) + point4 = thisObject.container.frame.frameThisPoint(point4) + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x, point2.y) + browserCanvasContext.lineTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() + + let opacity = 1 + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + '' + browserCanvasContext.fill() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + '' + browserCanvasContext.lineWidth = 0.3 + browserCanvasContext.stroke() + + /* Shadow */ + + if (thisObject.container.status !== 'hidden') { + for (let i = 0; i <= 30; i++) { + opacity = 1 - (i / 300) - 0.95 + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point2.x + i, point2.y) + browserCanvasContext.lineTo(point3.x + i, point3.y) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + '' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() + } + } + } +} diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 496af8b75..8f90e671b 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -425,13 +425,44 @@ function newTutorialSpace() { change at each descendent. The nodePath route starts at the object referenceParent. */ - let referenceParent = currentNode.payload.referenceParent + let referenceParent = currentNode.payload.referenceParent for (let i = 0; i < config.batchConfigChangesReferenceParent.length; i++) { let arrayItem = config.batchConfigChangesReferenceParent[i] - let nodePath = arrayItem.nodePath + let nodePath = arrayItem.nodePath let properties = arrayItem.properties - let childNode = eval(nodePath) + let childNode + try { + childNode = eval(nodePath) + } catch (err) { + console.log(MODULE_NAME + ' -> The nodePath provided is not good. -> nodePath = ' + nodePath) + let splittedPath = nodePath.split('.') + let partialPath = '' + let separator = '' + for (let j = 0; j < splittedPath.length; j++) { + let part = splittedPath[j] + let partialNode + let splittedParts = part.split('[') + if (splittedParts.length > 1) { + partialNode = eval(partialPath + separator + splittedParts[0]) + if (partialNode === undefined) { + console.log(MODULE_NAME + ' -> This part can not be undefined -> part = ' + splittedParts[0]) + currentNode.payload.uiObject.setErrorMessage('Node Path is incorrect. See console log for details.') + break + } + } + partialPath = partialPath + separator + part + separator = '.' + + partialNode = eval(partialPath) + if (partialNode === undefined) { + console.log(MODULE_NAME + ' -> This part can not be undefined -> part = ' + part) + currentNode.payload.uiObject.setErrorMessage('Node Path is incorrect. See console log for details.') + break + } + } + continue + } let nodeConfig = JSON.parse(childNode.config) for (const property in properties) { nodeConfig[property] = properties[property] From aa2f39821601a37bc5940afe2044ab06096fd01b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Oct 2020 14:56:47 +0200 Subject: [PATCH 185/192] More fixes --- ChartingSpace/CoordinateSystem.js | 2 +- Spaces/TutorialSpace.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChartingSpace/CoordinateSystem.js b/ChartingSpace/CoordinateSystem.js index 4a085c3fa..de7f0eacf 100644 --- a/ChartingSpace/CoordinateSystem.js +++ b/ChartingSpace/CoordinateSystem.js @@ -24,7 +24,7 @@ function newCoordinateSystem() { autoMinYScale: true, autoMaxYScale: true, HORIZONTAL_MARGIN_FACTOR: 1, - VERTICAL_MARGIN_FACTOR: 0.9, + VERTICAL_MARGIN_FACTOR: 1, HORIZONTAL_MARGIN_INVERSE_FACTOR: 0, VERTICAL_MARGIN_INVERSE_FACTOR: 0, physics: physics, diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 8f90e671b..76c290158 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -417,7 +417,7 @@ function newTutorialSpace() { config.batchConfigChangesReferenceParent !== undefined ) { batchConfigChangesCounter++ - if (batchConfigChangesCounter === 5) { + if (batchConfigChangesCounter === 5 || batchConfigChangesCounter === 10) { /* Here we are going to process an array of different changes to descendents of the reference parent. The end user needs to specify a nodePath to the From 06f5839ceb471ab69aa85078cd2472a4d4c79dcb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Oct 2020 16:48:20 +0200 Subject: [PATCH 186/192] Update Plotter.js --- Plotting/Plotter.js | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/Plotting/Plotter.js b/Plotting/Plotter.js index 14da86ad7..bcb956121 100644 --- a/Plotting/Plotter.js +++ b/Plotting/Plotter.js @@ -589,12 +589,21 @@ function newPlotter() { The information we store in files is independent from the charing system and its coordinate systems. That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline. */ - let dataPoint + let dataPoint dataPoint = coordinateSystem.transformThisPoint(rawPoint) dataPoint = transformThisPoint(dataPoint, thisObject.container) + let testPoint = { + x: dataPoint.x, + y: dataPoint.y + } dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) dataPoint = thisObject.fitFunction(dataPoint) + if (testPoint.x === dataPoint.x) { + dataPoint.isInViewPort = true + } else { + dataPoint.isInViewPort = false + } /* Store the data point at the local map */ dataPoint.rawPoint = rawPoint dataPoints.set(point.id, dataPoint) @@ -738,15 +747,11 @@ function newPlotter() { if (polygonVertex.referenceParent !== undefined) { let dataPointObject = dataPoints.get(polygonVertex.referenceParent.id) if (dataPointObject === undefined) { + polygonVertex.payload.uiObject.setErrorMessage('Vertex not referencing any Point') console.log('[WARN] You have a Polygon Vertex not referencing any Point.') continue } - /* Contributing to Auto-Scale */ - if (dataPointObject.rawPoint.y > 1 && dataPointObject.rawPoint.y !== undefined && isNaN(dataPointObject.rawPoint.y) === false) { - coordinateSystem.reportYValue(dataPointObject.rawPoint.y) - } - let dataPoint = { x: dataPointObject.x, y: dataPointObject.y @@ -754,6 +759,20 @@ function newPlotter() { /* We make sure the points do not fall outside the viewport visible area. This step allways need to be done. */ dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint) dataPoint = thisObject.fitFunction(dataPoint) + + /* + Contributing to Auto-Scale: A point will contribute to the y coordinate only if the x coordinate is plotted in the screen. + It can happen that objects that span through a long period of time could have its begin point inside the visible + viewport but not its end point. In those cases, the end point should not be reported. + */ + + if (dataPointObject.rawPoint.y > 1 && dataPointObject.rawPoint.y !== undefined && isNaN(dataPointObject.rawPoint.y) === false) { + let rawPoint = coordinateSystem.transformThisPoint(dataPointObject.rawPoint) + if (dataPointObject.isInViewPort === true) { + coordinateSystem.reportYValue(dataPointObject.rawPoint.y) + } + } + if (k === 0) { browserCanvasContext.moveTo(dataPoint.x, dataPoint.y) } else { @@ -828,7 +847,7 @@ function newPlotter() { browserCanvasContext.drawImage(imageToDraw, imagePosition.x - imageSize / 2 + offsetX, imagePosition.y - imageSize / 2 - offsetY, imageSize, imageSize) } } else { - console.log('Can not plot image named '+ imageName + ' of product ' + productDefinition.name + ' because it does not exist.') + console.log('Can not plot image named ' + imageName + ' of product ' + productDefinition.name + ' because it does not exist.') } } From 8152e65bdba30a01fb2e33b9ca5071a77e7d5e41 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Oct 2020 19:05:43 +0200 Subject: [PATCH 187/192] Update Layer.js --- Panels/Layer.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Panels/Layer.js b/Panels/Layer.js index ccc6163f2..7ffe83133 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -509,7 +509,7 @@ function newLayer() { if (storedValue !== undefined) { if (storedValue !== thisObject.status) { - if (storedValue === LAYER_STATUS.ON) { + if (storedValue === LAYER_STATUS.ON && thisObject.status === LAYER_STATUS.OFF) { resetProgressBars() changeStatusTo(LAYER_STATUS.LOADING) } @@ -526,7 +526,6 @@ function newLayer() { // we ignore errors here since most likely they will be parsing errors. } - /* Check when the loading finishes */ if ( thisObject.status === LAYER_STATUS.LOADING && marketFileProgressBar.value === 100 && From c2bc53a83b5b362e1595ad43fe4ea09965b0154c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 3 Oct 2020 14:45:33 +0200 Subject: [PATCH 188/192] Update TopSpace.js --- Spaces/TopSpace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spaces/TopSpace.js b/Spaces/TopSpace.js index b387d011e..169b9c498 100644 --- a/Spaces/TopSpace.js +++ b/Spaces/TopSpace.js @@ -101,7 +101,7 @@ function newTopSpace() { browserCanvasContext.drawImage( logoImage, imagePosition.x, imagePosition.y, - 150, + 215, TOP_SPACE_HEIGHT - 2) } } From f7790d593b93f6a7798c0bcd1a9f90b7151cfc4e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 5 Oct 2020 13:34:46 +0200 Subject: [PATCH 189/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 76c290158..698628223 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -62,6 +62,7 @@ function newTutorialSpace() { let keyPressedCounter = 0 let sliderPositioned = 0 let changeNodeConfigCounter = 0 + let changeNodeConfigCounterWithEval = 0 let documentationCounter = 0 let batchConfigChangesCounter = 0 @@ -483,6 +484,18 @@ function newTutorialSpace() { currentNode.payload.referenceParent.config = JSON.stringify(nodeConfig) } } + if ( + config.changeNodeConfigWithEvalReferenceParent !== undefined + ) { + changeNodeConfigCounterWithEval++ + if (changeNodeConfigCounterWithEval === 5) { + let nodeConfig = JSON.parse(currentNode.payload.referenceParent.config) + for (const property in config.changeNodeConfigWithEvalReferenceParent) { + nodeConfig[property] = eval(config.changeNodeConfigWithEvalReferenceParent[property]) + } + currentNode.payload.referenceParent.config = JSON.stringify(nodeConfig) + } + } if ( config.menuActionReferenceParent !== undefined ) { @@ -783,6 +796,7 @@ function newTutorialSpace() { function changeNodeConfig() { changeNodeConfigCounter = 0 + changeNodeConfigCounterWithEval = 0 } function batchConfigChanges() { From 629ded0ddebec5549dd256ea0985795b605f8584 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 5 Oct 2020 14:21:16 +0200 Subject: [PATCH 190/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 698628223..7c2ecc337 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -488,7 +488,7 @@ function newTutorialSpace() { config.changeNodeConfigWithEvalReferenceParent !== undefined ) { changeNodeConfigCounterWithEval++ - if (changeNodeConfigCounterWithEval === 5) { + if (changeNodeConfigCounterWithEval === 5 || batchConfigChangesCounter === 10) { let nodeConfig = JSON.parse(currentNode.payload.referenceParent.config) for (const property in config.changeNodeConfigWithEvalReferenceParent) { nodeConfig[property] = eval(config.changeNodeConfigWithEvalReferenceParent[property]) From 5c61423eb575c8a6f4570dd55f66b8008dc99d63 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 5 Oct 2020 15:37:44 +0200 Subject: [PATCH 191/192] Update TutorialSpace.js --- Spaces/TutorialSpace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spaces/TutorialSpace.js b/Spaces/TutorialSpace.js index 7c2ecc337..8e8cbba3e 100644 --- a/Spaces/TutorialSpace.js +++ b/Spaces/TutorialSpace.js @@ -488,7 +488,7 @@ function newTutorialSpace() { config.changeNodeConfigWithEvalReferenceParent !== undefined ) { changeNodeConfigCounterWithEval++ - if (changeNodeConfigCounterWithEval === 5 || batchConfigChangesCounter === 10) { + if (changeNodeConfigCounterWithEval === 5 || changeNodeConfigCounterWithEval === 10) { let nodeConfig = JSON.parse(currentNode.payload.referenceParent.config) for (const property in config.changeNodeConfigWithEvalReferenceParent) { nodeConfig[property] = eval(config.changeNodeConfigWithEvalReferenceParent[property]) From be406a48084680c3904593f3a3d4ab9636fc6b60 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 5 Oct 2020 17:11:25 +0200 Subject: [PATCH 192/192] doc --- Globals.js | 2 +- Spaces/DocSpace.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Globals.js b/Globals.js index 35a75f364..f06e3f55c 100644 --- a/Globals.js +++ b/Globals.js @@ -26,7 +26,7 @@ const UI_FONT = { SECONDARY: "Source Code Pro" }; -const DOCUMENTATION_URL_PREFIX = 'https://julian-molina.github.io/Documentation/' +const DOCUMENTATION_URL_PREFIX = 'https://docs.superalgos.org/' const MAC_AMOUNT_FACTOR = 5 const IS_MAC = navigator.platform.toUpperCase().indexOf('MAC') >= 0 diff --git a/Spaces/DocSpace.js b/Spaces/DocSpace.js index b073e4674..2a4daa9f5 100644 --- a/Spaces/DocSpace.js +++ b/Spaces/DocSpace.js @@ -27,7 +27,6 @@ function newDocSpace() { let openingEventSubscriptionId let closingEventSubscriptionId - const DEFAULT_URL = 'https://julian-molina.github.io/Documentation/' return thisObject function initialize() { @@ -51,7 +50,7 @@ function newDocSpace() { function onOpening() { let docIFrame = document.getElementById('docIFrame') if (docIFrame.src === "") { - docIFrame.src = DEFAULT_URL + docIFrame.src = DOCUMENTATION_URL_PREFIX } }