From a36f8992b62ce8170cf177ae5c53f1668d9ab708 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 19 May 2019 20:40:43 +0200 Subject: [PATCH 01/10] Reorganization of Strategy Space --- CockpitSpace/RestartSimulation.js | 2 +- Spaces/StrategySpace.js | 24 +- StrategySpace/StrategizerGateway.js | 349 ++++++++++++ StrategySpace/StrategyCollectionItem.js | 177 ------ StrategySpace/TradingSystem.js | 410 -------------- StrategySpace/Workspace.js | 715 +++++++++++++----------- 6 files changed, 749 insertions(+), 928 deletions(-) create mode 100644 StrategySpace/StrategizerGateway.js delete mode 100644 StrategySpace/StrategyCollectionItem.js delete mode 100644 StrategySpace/TradingSystem.js diff --git a/CockpitSpace/RestartSimulation.js b/CockpitSpace/RestartSimulation.js index 1aeb12543..0359ac40f 100644 --- a/CockpitSpace/RestartSimulation.js +++ b/CockpitSpace/RestartSimulation.js @@ -105,7 +105,7 @@ function newRestartSimulation () { } try { thisObject.status = 'Saving' - let result = await canvas.strategySpace.workplace.saveToStrategyzer() + let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer(canvas.strategySpace.workspace.tradingSystem) if (result === true) { thisObject.status = 'Restarting' await graphQlRestartSimulation(simulationParams) diff --git a/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index e4bfcca0c..999a9838d 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -3,10 +3,12 @@ function newStrategySpace () { const MODULE_NAME = 'Strategy Space' let thisObject = { sidePanel: undefined, - workplace: undefined, + strategizerGateway: undefined, container: undefined, iconCollection: undefined, iconByPartType: undefined, + workspace: undefined, + isDeployed: false, draw: draw, getContainer: getContainer, makeVisible: makeVisible, @@ -26,10 +28,10 @@ function newStrategySpace () { return thisObject async function initialize () { - thisObject.workplace = newWorkspace() + thisObject.strategizerGateway = newStrategizerGateway() - thisObject.workplace.initialize() - await thisObject.workplace.loadFromStrategyzer() + thisObject.strategizerGateway.initialize() + await thisObject.strategizerGateway.loadFromStrategyzer() loadIconCollection() buildIconByPartTypeMap() @@ -131,13 +133,19 @@ function newStrategySpace () { } function makeVisible () { - if (thisObject.workplace.isDeployed !== true) { - thisObject.workplace.deploydTradingSystem() + if (thisObject.isDeployed !== true) { + deploydTradingSystem() } canvas.floatingSpace.makeVisible() visible = true } + function deploydTradingSystem () { + thisObject.workspace = newWorkspace() + thisObject.workspace.initialize(thisObject.strategizerGateway.strategizerData) + thisObject.isDeployed = true + } + function makeInvisible () { visible = false } @@ -145,8 +153,8 @@ function newStrategySpace () { function getContainer (point) { let container - if (thisObject.workplace !== undefined) { - container = thisObject.workplace.getContainer(point) + if (thisObject.strategizerGateway !== undefined) { + container = thisObject.strategizerGateway.getContainer(point) if (container !== undefined) { return container } } diff --git a/StrategySpace/StrategizerGateway.js b/StrategySpace/StrategizerGateway.js new file mode 100644 index 000000000..36ff2214e --- /dev/null +++ b/StrategySpace/StrategizerGateway.js @@ -0,0 +1,349 @@ + +function newStrategizerGateway () { + const MODULE_NAME = 'Strategizer Gateway' + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME + + let thisObject = { + strategizerData: undefined, + container: undefined, + loadFromStrategyzer: loadFromStrategyzer, + saveToStrategyzer: saveToStrategyzer, + draw: draw, + getContainer: getContainer, + initialize: initialize + } + + let colletionItems = [] + + thisObject.container = newContainer() + thisObject.container.name = MODULE_NAME + thisObject.container.initialize() + + thisObject.container.frame.width = 0 + thisObject.container.frame.height = 0 + + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = 0 + + thisObject.container.isDraggeable = false + thisObject.container.isClickeable = false + + return thisObject + + function initialize () { + + } + + async function saveToStrategyzer (tradingSystem) { + try { + const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) + + let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY) + if (user === null) { + if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> Can not save because user is not logged in. ') } + return + } + + user = JSON.parse(user) + + const authId = user.authId + + const apolloClient = new Apollo.lib.ApolloClient({ + networkInterface: Apollo.lib.createNetworkInterface({ + uri: window.canvasApp.graphQL.masterAppApiUrl, + transportBatching: true + }), + connectToDevTools: true + }) + + /* Updating all Strategies */ + + const networkInterface = Apollo.lib.createNetworkInterface({ + uri: window.canvasApp.graphQL.masterAppApiUrl + }) + + networkInterface.use([{ + applyMiddleware (req, next) { + req.options.headers = { + authorization: `Bearer ${accessToken}` + } + next() + } + }]) + + let dataToSave = buildGraphQLDataToSave(tradingSystem) + + const updateStrategies = () => { + return new Promise((resolve, reject) => { + apolloClient.mutate({ + mutation: GRAPHQL_MUTATION_UPDATE_STRATEGIES, + variables: { + id: thisObject.strategizerData.id, + strategy: dataToSave.strategy + } + }) + .then(response => { + resolve(true) + }) + .catch(err => { + if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> ApolloClient error updating user strategies -> err = ' + err.stack) } + reject(err) + }) + }) + } + + let result = await updateStrategies() + + return result + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> err = ' + err.stack) } + } + } + + function buildGraphQLDataToSave (tradingSystem) { + let graphQL_Mutation = '' + + let dataToSave = { + strategy: { + subStrategies: [] + } + } + + for (m = 0; m < tradingSystem.strategies.length; m++) { + let strategizerGatewayStrategy = tradingSystem.strategies[m] + let strategy = { + name: strategizerGatewayStrategy.name, + active: strategizerGatewayStrategy.active, + entryPoint: { + situations: [] + }, + exitPoint: { + situations: [] + }, + sellPoint: { + situations: [] + }, + stopLoss: { + phases: [] + }, + buyOrder: { + phases: [] + } + } + + for (let k = 0; k < strategizerGatewayStrategy.entryPoint.situations.length; k++) { + let strategizerGatewaySituation = strategizerGatewayStrategy.entryPoint.situations[k] + let situation = { + name: strategizerGatewaySituation.name, + conditions: [] + } + + for (let m = 0; m < strategizerGatewaySituation.conditions.length; m++) { + let strategizerGatewayCondition = strategizerGatewaySituation.conditions[m] + let condition = { + name: strategizerGatewayCondition.name, + code: strategizerGatewayCondition.code + } + situation.conditions.push(condition) + } + strategy.entryPoint.situations.push(situation) + } + + for (let k = 0; k < strategizerGatewayStrategy.exitPoint.situations.length; k++) { + let strategizerGatewaySituation = strategizerGatewayStrategy.exitPoint.situations[k] + let situation = { + name: strategizerGatewaySituation.name, + conditions: [] + } + + for (let m = 0; m < strategizerGatewaySituation.conditions.length; m++) { + let strategizerGatewayCondition = strategizerGatewaySituation.conditions[m] + let condition = { + name: strategizerGatewayCondition.name, + code: strategizerGatewayCondition.code + } + situation.conditions.push(condition) + } + strategy.exitPoint.situations.push(situation) + } + + for (let k = 0; k < strategizerGatewayStrategy.sellPoint.situations.length; k++) { + let strategizerGatewaySituation = strategizerGatewayStrategy.sellPoint.situations[k] + let situation = { + name: strategizerGatewaySituation.name, + conditions: [] + } + + for (let m = 0; m < strategizerGatewaySituation.conditions.length; m++) { + let strategizerGatewayCondition = strategizerGatewaySituation.conditions[m] + let condition = { + name: strategizerGatewayCondition.name, + code: strategizerGatewayCondition.code + } + situation.conditions.push(condition) + } + strategy.sellPoint.situations.push(situation) + } + + for (let p = 0; p < strategizerGatewayStrategy.stopLoss.phases.length; p++) { + let strategizerGatewayPhase = strategizerGatewayStrategy.stopLoss.phases[p] + let phase = { + name: strategizerGatewayPhase.name, + code: strategizerGatewayPhase.code, + situations: [] + } + + for (let k = 0; k < strategizerGatewayPhase.situations.length; k++) { + let strategizerGatewaySituation = strategizerGatewayPhase.situations[k] + let situation = { + name: strategizerGatewaySituation.name, + conditions: [] + } + + for (let m = 0; m < strategizerGatewaySituation.conditions.length; m++) { + let strategizerGatewayCondition = strategizerGatewaySituation.conditions[m] + let condition = { + name: strategizerGatewayCondition.name, + code: strategizerGatewayCondition.code + } + situation.conditions.push(condition) + } + phase.situations.push(situation) + } + strategy.stopLoss.phases.push(phase) + } + + for (let p = 0; p < strategizerGatewayStrategy.buyOrder.phases.length; p++) { + let strategizerGatewayPhase = strategizerGatewayStrategy.buyOrder.phases[p] + let phase = { + name: strategizerGatewayPhase.name, + code: strategizerGatewayPhase.code, + situations: [] + } + + for (let k = 0; k < strategizerGatewayPhase.situations.length; k++) { + let strategizerGatewaySituation = strategizerGatewayPhase.situations[k] + let situation = { + name: strategizerGatewaySituation.name, + conditions: [] + } + + for (let m = 0; m < strategizerGatewaySituation.conditions.length; m++) { + let strategizerGatewayCondition = strategizerGatewaySituation.conditions[m] + let condition = { + name: strategizerGatewayCondition.name, + code: strategizerGatewayCondition.code + } + situation.conditions.push(condition) + } + phase.situations.push(situation) + } + strategy.buyOrder.phases.push(phase) + } + dataToSave.strategy.subStrategies.push(strategy) + } + + return dataToSave + } + + async function loadFromStrategyzer () { + try { + const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) + + let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY) + if (user === null) { + // if there is no user that means that we are logged off, which means this object can not be used. + return + } + + user = JSON.parse(user) + + const authId = user.authId + + let sessionToken + + const apolloClient = new Apollo.lib.ApolloClient({ + networkInterface: Apollo.lib.createNetworkInterface({ + uri: window.canvasApp.graphQL.masterAppApiUrl, + transportBatching: true + }), + connectToDevTools: true + }) + + /* Getting the FB that own the Strategies */ + + let tradingSystemSimulationClone = '' + let clones = window.localStorage.getItem('userClones') + if (clones === null || clones === '') { + if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> no user clones found at local storage. Can not get Strategies without them. ') } + return + } + clones = JSON.parse(clones) + for (let i = 0; i < clones.length; i++) { + let clone = clones[i] + if (clone.botType === 'Indicator') { + tradingSystemSimulationClone = clone.botSlug + } + } + /* Getting all Strategies */ + + const networkInterface = Apollo.lib.createNetworkInterface({ + uri: window.canvasApp.graphQL.masterAppApiUrl + }) + + networkInterface.use([{ + applyMiddleware (req, next) { + req.options.headers = { + authorization: `Bearer ${accessToken}` + } + next() + } + }]) + + const getStrategies = () => { + return new Promise((resolve, reject) => { + apolloClient.query({ + query: GRAPHQL_QUERY_GET_STRATEGIES, + variables: { fbSlug: tradingSystemSimulationClone} + }) + .then(response => { + window.localStorage.setItem('userStrategies', JSON.stringify(response.data.strategizer_StrategyByFb)) + thisObject.strategizerData = JSON.parse(JSON.stringify(response.data.strategizer_StrategyByFb)) + + resolve({ strategies: response.data.strategizer_StrategyByFb.subStrategies}) + }) + .catch(err => { + if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> ApolloClient error getting user strategies -> err = ' + err.stack) } + reject(err) + }) + }) + } + + // To avoid race conditions, add asynchronous fetches to array + let fetchDataPromises = [] + + fetchDataPromises.push(getStrategies()) + + // When all asynchronous fetches resolve, authenticate user or throw error. + await Promise.all(fetchDataPromises).then(result => { + + }, err => { + if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> GraphQL Fetch Error -> err = ' + err.stack) } + }) + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> err = ' + err.stack) } + } + } + + function getContainer (point) { + let container + + return undefined + } + + function draw () { + + } +} diff --git a/StrategySpace/StrategyCollectionItem.js b/StrategySpace/StrategyCollectionItem.js deleted file mode 100644 index 2b1b8c920..000000000 --- a/StrategySpace/StrategyCollectionItem.js +++ /dev/null @@ -1,177 +0,0 @@ -function newStrategyCollectionItem () { - const MODULE_NAME = 'Strategy Collection Item' - let thisObject = { - icon: undefined, - strategySource: undefined, - strategy: undefined, - container: undefined, - draw: draw, - getContainer: getContainer, - initialize: initialize - } - - let isInitialized = false - - thisObject.container = newContainer() - thisObject.container.name = MODULE_NAME - thisObject.container.initialize() - thisObject.container.isClickeable = true - thisObject.container.isDraggeable = false - - let status = 'off' - - return thisObject - - function initialize (strategy) { - thisObject.strategySource = strategy - - const ITEM_WIDTH = SIDE_PANEL_WIDTH - 20 - const ITEM_HEIGHT = 80 - - thisObject.container.frame.width = ITEM_WIDTH - thisObject.container.frame.height = ITEM_HEIGHT - - const LEFT_MARGIN = (thisObject.container.parentContainer.frame.width - thisObject.container.frame.width) / 2 - const TOP_MARGIN = 100 - - thisObject.container.frame.position.x = LEFT_MARGIN - thisObject.container.frame.position.y = TOP_MARGIN - - thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - isInitialized = true - } - - function onMouseClick (event) { - if (status === 'off') { - canvas.floatingSpace.makeVisible() - thisObject.strategy = newTradingSystem() - thisObject.strategy.initialize(thisObject.strategySource) - status = 'on' - } else { - canvas.floatingSpace.makeInvisible() - thisObject.strategy.finalize() - status = 'off' - } - } - - function getContainer (point) { - let container - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - - function draw () { - if (isInitialized === false) { return } - - borders() - text() - arrow() - icon() - } - - function text () { - if (thisObject.strategySource === undefined) { - return - } - - const LEFT_MARGIN = 80 - const TOP_MARGIN = 45 - - let strategy = thisObject.strategySource - - let labelpoint = { - x: LEFT_MARGIN, - y: TOP_MARGIN - } - - labelpoint = thisObject.container.frame.frameThisPoint(labelpoint) - - let labelToPrint = strategy.name - labelToPrint = '' - labelToPrint = labelToPrint.substring(0, 30) - let opacity = 1 - let fontSize = 15 - - printLabel(labelToPrint, labelpoint.x, labelpoint.y, opacity, fontSize) - } - - function borders () { - let params = { - cornerRadius: 8, - lineWidth: 0.1, - opacity: 1, - container: thisObject.container, - borderColor: UI_COLOR.DARK, - backgroundColor: UI_COLOR.WHITE, - castShadow: true - } - - roundedCornersBackground(params) - } - - function arrow () { - const X_OFFSET = 400 - const Y_OFFSET = 40 - const HEIGHT = 12 - const WIDTH = 6 - const LINE_WIDTH = 2 - const OPACITY = 0.6 - - point1 = { - x: X_OFFSET, - y: Y_OFFSET - HEIGHT / 2 - } - - point2 = { - x: X_OFFSET + WIDTH, - y: Y_OFFSET - } - - point3 = { - x: X_OFFSET, - y: Y_OFFSET + HEIGHT / 2 - } - - /* Now the transformations. */ - - point1 = thisObject.container.frame.frameThisPoint(point1) - point2 = thisObject.container.frame.frameThisPoint(point2) - point3 = thisObject.container.frame.frameThisPoint(point3) - - browserCanvasContext.setLineDash([0, 0]) - - /* The Arrow */ - - browserCanvasContext.beginPath() - - browserCanvasContext.moveTo(point1.x, point1.y) - browserCanvasContext.lineTo(point2.x, point2.y) - browserCanvasContext.lineTo(point3.x, point3.y) - - browserCanvasContext.lineWidth = LINE_WIDTH - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')' - browserCanvasContext.stroke() - } - - function icon () { - if (thisObject.icon === undefined) { return } - - const X_OFFSET = 45 - const Y_OFFSET = 40 - const IMAGE_SIZE = 40 - - point1 = { - x: X_OFFSET, - y: Y_OFFSET - } - - /* Now the transformations. */ - - point1 = thisObject.container.frame.frameThisPoint(point1) - - browserCanvasContext.drawImage(thisObject.icon, point1.x - IMAGE_SIZE / 2, point1.y - IMAGE_SIZE / 2, IMAGE_SIZE, IMAGE_SIZE) - } -} diff --git a/StrategySpace/TradingSystem.js b/StrategySpace/TradingSystem.js deleted file mode 100644 index 9cd76e864..000000000 --- a/StrategySpace/TradingSystem.js +++ /dev/null @@ -1,410 +0,0 @@ - -function newTradingSystem () { - const MODULE_NAME = 'Trading System' - - let thisObject = { - protocolData: undefined, - container: undefined, - getContainer: getContainer, - 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 - - return thisObject - - function finalize () { - destroyStrategyParts() - thisObject.protocolData = undefined - thisObject.container.finalize() - thisObject.container = undefined - } - - function initialize (protocolData) { - thisObject.protocolData = { - id: protocolData.id, - strategies: protocolData.subStrategies - } - generateStrategyParts() - } - - function getContainer (point) { - - } - - function createPart (partType, name, node, parentNode, chainParent, title) { - let payload = {} - if (chainParent === undefined) { - payload.targetPosition = { - x: canvas.floatingSpace.container.frame.width / 2, - y: canvas.floatingSpace.container.frame.height / 2 - } - } else { - payload.targetPosition = { - x: chainParent.payload.position.x, - y: chainParent.payload.position.y - } - } - - if (title !== undefined) { - payload.subTitle = title - } else { - payload.subTitle = partType - } - - payload.visible = true - payload.title = name - payload.node = node - payload.parentNode = parentNode - payload.chainParent = chainParent - payload.onMenuItemClick = onMenuItemClick - - if (node.id === undefined) { - node.id = newUniqueId() - } - node.payload = payload - node.type = partType - canvas.floatingSpace.strategyPartConstructor.createStrategyPart(payload) - } - - function destroyPart (node) { - canvas.floatingSpace.strategyPartConstructor.destroyStrategyPart(node.payload) - } - - function generateStrategyParts () { - let lastPhase - let tradingSystem = thisObject.protocolData - - createPart('Trading System', '', tradingSystem, undefined, undefined) - - for (m = 0; m < tradingSystem.strategies.length; m++) { - let strategy = tradingSystem.strategies[m] - createPart('Strategy', strategy.name, strategy, tradingSystem, tradingSystem) - - createPart('Strategy Entry Event', '', strategy.entryPoint, strategy, strategy) - for (let k = 0; k < strategy.entryPoint.situations.length; k++) { - let situation = strategy.entryPoint.situations[k] - createPart('Situation', situation.name, situation, strategy.entryPoint, strategy.entryPoint, 'Strategy Entry' + ' ' + 'Situation') - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - createPart('Condition', condition.name, condition, situation, situation, 'Condition') - } - } - - createPart('Strategy Exit Event', '', strategy.exitPoint, strategy, strategy) - for (let k = 0; k < strategy.exitPoint.situations.length; k++) { - let situation = strategy.exitPoint.situations[k] - createPart('Situation', situation.name, situation, strategy.exitPoint, strategy.exitPoint, 'Strategy Exit' + ' ' + 'Situation') - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - createPart('Condition', condition.name, condition, situation, situation, 'Condition') - } - } - - createPart('Trade Entry Event', '', strategy.sellPoint, strategy, strategy) - for (let k = 0; k < strategy.sellPoint.situations.length; k++) { - let situation = strategy.sellPoint.situations[k] - createPart('Situation', situation.name, situation, strategy.sellPoint, strategy.sellPoint, 'Trade Entry' + ' ' + 'Situation') - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - createPart('Condition', condition.name, condition, situation, situation, 'Condition') - } - } - - createPart('Stop', '', strategy.stopLoss, strategy, strategy) - for (let p = 0; p < strategy.stopLoss.phases.length; p++) { - let phase = strategy.stopLoss.phases[p] - - let chainParent - if (p === 0) { - chainParent = strategy.stopLoss - } else { - chainParent = lastPhase - } - lastPhase = phase - createPart('Phase', phase.name, phase, strategy.stopLoss, chainParent, 'Stop Phase') - - for (let k = 0; k < phase.situations.length; k++) { - let situation = phase.situations[k] - createPart('Situation', situation.name, situation, phase, phase, 'Situation') - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - createPart('Condition', condition.name, condition, situation, situation, 'Condition') - } - } - } - - createPart('Take Profit', '', strategy.buyOrder, strategy, strategy) - for (let p = 0; p < strategy.buyOrder.phases.length; p++) { - let phase = strategy.buyOrder.phases[p] - let chainParent - if (p === 0) { - chainParent = strategy.buyOrder - } else { - chainParent = lastPhase - } - lastPhase = phase - createPart('Phase', phase.name, phase, strategy.buyOrder, chainParent, 'Take Profit Phase') - - for (let k = 0; k < phase.situations.length; k++) { - let situation = phase.situations[k] - createPart('Situation', situation.name, situation, phase, phase, 'Situation') - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - createPart('Condition', condition.name, condition, situation, situation, 'Condition') - } - } - } - } - } - - function destroyStrategyParts () { - let strategy = thisObject.protocolData - destroyPart(strategy) - - destroyPart(strategy.entryPoint) - for (let k = 0; k < strategy.entryPoint.situations.length; k++) { - let situation = strategy.entryPoint.situations[k] - destroyPart(situation) - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - destroyPart(condition) - } - } - - destroyPart(strategy.exitPoint) - for (let k = 0; k < strategy.exitPoint.situations.length; k++) { - let situation = strategy.exitPoint.situations[k] - destroyPart(situation) - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - destroyPart(condition) - } - } - - destroyPart(strategy.sellPoint) - for (let k = 0; k < strategy.sellPoint.situations.length; k++) { - let situation = strategy.sellPoint.situations[k] - destroyPart(situation) - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - destroyPart(condition) - } - } - - destroyPart(strategy.stopLoss) - for (let p = 0; p < strategy.stopLoss.phases.length; p++) { - let phase = strategy.stopLoss.phases[p] - destroyPart(strategy.stopLoss) - - for (let k = 0; k < phase.situations.length; k++) { - let situation = phase.situations[k] - destroyPart(situation) - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - destroyPart(condition) - } - } - } - - destroyPart(strategy.buyOrder) - for (let p = 0; p < strategy.buyOrder.phases.length; p++) { - let phase = strategy.buyOrder.phases[p] - destroyPart(strategy.buyOrder) - - for (let k = 0; k < phase.situations.length; k++) { - let situation = phase.situations[k] - destroyPart(situation) - - for (let m = 0; m < situation.conditions.length; m++) { - let condition = situation.conditions[m] - destroyPart(condition) - } - } - } - } - - async function onMenuItemClick (payload, action) { - switch (action) { - case 'Save Trading System': - { - let result = await canvas.strategySpace.workplace.saveToStrategyzer() - return result - break - } - - case 'Open Settings': - break - case 'Delete Strategy': - - break - - case 'Reload Strategy': - - break - - case 'Save Strategy': - - break - - case 'Edit Code': - - break - case 'Add Phase': - { - let phaseParent = payload.node - let m = phaseParent.phases.length - let phase = { - name: 'New Phase', - code: '', - situations: [] - } - phaseParent.phases.push(phase) - let phaseChainParent - if (m > 0) { - phaseChainParent = phaseParent.phases[m - 1] - } else { - phaseChainParent = phaseParent - } - createPart('Phase', phase.name, phase, phaseParent, phaseChainParent, 'Phase') - } - break - case 'Add Situation': - { - let phase = payload.node - let m = phase.situations.length - let situation = { - name: 'New Situation', - conditions: [] - } - phase.situations.push(situation) - createPart('Situation', situation.name, situation, phase, phase, 'Situation') - } - break - case 'Add Condition': - { - let situation = payload.node - let m = situation.conditions.length - let condition = { - name: 'New Condition', - code: '' - } - situation.conditions.push(condition) - createPart('Condition', condition.name, condition, situation, situation, 'Condition') - } - break - case 'Delete Phase': { - deletePhase(payload.node) - break - } - case 'Delete Situation': { - deleteSituation(payload.node) - break - } - case 'Delete Condition': { - deleteCondition(payload.node) - break - } - default: - - } - } - - function deletePhase (node) { - let payload = node.payload - for (let k = 0; k < payload.parentNode.phases.length; k++) { - let phase = payload.parentNode.phases[k] - if (phase.id === node.id) { - for (let j = 0; j < phase.situations.length; j++) { - let situation = phase.situations[j] - for (let i = 0; i < situation.conditions.length; i++) { - let condition = situation.conditions[i] - destroyPart(condition) - cleanNode(condition) - } - situation.conditions = [] - destroyPart(situation) - phase.situations.splice(j, 1) - cleanNode(situation) - } - phase.situations = [] - /* Before deleting this phase we need to give its chainParent to the next phase down the chain */ - if (k < payload.parentNode.phases.length - 1) { - payload.parentNode.phases[k + 1].payload.chainParent = payload.chainParent - } - /* Continue destroying this phase */ - destroyPart(phase) - payload.parentNode.phases.splice(k, 1) - cleanNode(phase) - return - } - } - } - - function deleteSituation (node) { - let payload = node.payload - for (let j = 0; j < payload.parentNode.situations.length; j++) { - let situation = payload.parentNode.situations[j] - if (situation.id === node.id) { - for (let i = 0; i < situation.conditions.length; i++) { - let condition = situation.conditions[i] - destroyPart(condition) - cleanNode(condition) - } - situation.conditions = [] - destroyPart(situation) - payload.parentNode.situations.splice(j, 1) - cleanNode(situation) - return - } - } - } - - function deleteCondition (node) { - let payload = node.payload - for (let i = 0; i < payload.parentNode.conditions.length; i++) { - let condition = payload.parentNode.conditions[i] - if (condition.id === node.id) { - destroyPart(node) - payload.parentNode.conditions.splice(i, 1) - cleanNode(condition) - return - } - } - } - - function cleanNode (node) { - 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/StrategySpace/Workspace.js b/StrategySpace/Workspace.js index d533d8c14..4d2780a16 100644 --- a/StrategySpace/Workspace.js +++ b/StrategySpace/Workspace.js @@ -1,359 +1,410 @@ function newWorkspace () { const MODULE_NAME = 'Workspace' - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME let thisObject = { - isDeployed: false, - strategizerData: undefined, - container: undefined, tradingSystem: undefined, - loadFromStrategyzer: loadFromStrategyzer, - saveToStrategyzer: saveToStrategyzer, - deploydTradingSystem: deploydTradingSystem, - draw: draw, + container: undefined, getContainer: getContainer, - initialize: initialize + initialize: initialize, + finalize: finalize } - let colletionItems = [] - thisObject.container = newContainer() - thisObject.container.name = MODULE_NAME - thisObject.container.initialize() - + 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.frame.position.x = 0 - thisObject.container.frame.position.y = 0 - - thisObject.container.isDraggeable = false - thisObject.container.isClickeable = false - return thisObject - function initialize () { - + function finalize () { + destroyStrategyParts() + thisObject.tradingSystem = undefined + thisObject.container.finalize() + thisObject.container = undefined } - async function saveToStrategyzer () { - try { - const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) - - let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY) - if (user === null) { - if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> Can not save because user is not logged in. ') } - return - } - - user = JSON.parse(user) - - const authId = user.authId - - const apolloClient = new Apollo.lib.ApolloClient({ - networkInterface: Apollo.lib.createNetworkInterface({ - uri: window.canvasApp.graphQL.masterAppApiUrl, - transportBatching: true - }), - connectToDevTools: true - }) - - /* Updating all Strategies */ - - const networkInterface = Apollo.lib.createNetworkInterface({ - uri: window.canvasApp.graphQL.masterAppApiUrl - }) - - networkInterface.use([{ - applyMiddleware (req, next) { - req.options.headers = { - authorization: `Bearer ${accessToken}` - } - next() - } - }]) - - let dataToSave = buildGraphQLDataToSave() - - const updateStrategies = () => { - return new Promise((resolve, reject) => { - apolloClient.mutate({ - mutation: GRAPHQL_MUTATION_UPDATE_STRATEGIES, - variables: { - id: thisObject.strategizerData.id, - strategy: dataToSave.strategy - } - }) - .then(response => { - resolve(true) - }) - .catch(err => { - if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> ApolloClient error updating user strategies -> err = ' + err.stack) } - reject(err) - }) - }) - } - - let result = await updateStrategies() - - return result - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> err = ' + err.stack) } + function initialize (tradingSystem) { + thisObject.tradingSystem = { + id: tradingSystem.id, + strategies: tradingSystem.subStrategies } - } - - function buildGraphQLDataToSave () { - let graphQL_Mutation = '' - - let dataToSave = { - strategy: { - subStrategies: [] - } - } - - for (m = 0; m < thisObject.tradingSystem.protocolData.strategies.length; m++) { - let workspaceStrategy = thisObject.tradingSystem.protocolData.strategies[m] - let strategy = { - name: workspaceStrategy.name, - active: workspaceStrategy.active, - entryPoint: { - situations: [] - }, - exitPoint: { - situations: [] - }, - sellPoint: { - situations: [] - }, - stopLoss: { - phases: [] - }, - buyOrder: { - phases: [] - } - } - - for (let k = 0; k < workspaceStrategy.entryPoint.situations.length; k++) { - let workspaceSituation = workspaceStrategy.entryPoint.situations[k] - let situation = { - name: workspaceSituation.name, - conditions: [] - } - - for (let m = 0; m < workspaceSituation.conditions.length; m++) { - let workspaceCondition = workspaceSituation.conditions[m] - let condition = { - name: workspaceCondition.name, - code: workspaceCondition.code - } - situation.conditions.push(condition) - } - strategy.entryPoint.situations.push(situation) - } - - for (let k = 0; k < workspaceStrategy.exitPoint.situations.length; k++) { - let workspaceSituation = workspaceStrategy.exitPoint.situations[k] - let situation = { - name: workspaceSituation.name, - conditions: [] - } - - for (let m = 0; m < workspaceSituation.conditions.length; m++) { - let workspaceCondition = workspaceSituation.conditions[m] - let condition = { - name: workspaceCondition.name, - code: workspaceCondition.code - } - situation.conditions.push(condition) - } - strategy.exitPoint.situations.push(situation) - } - - for (let k = 0; k < workspaceStrategy.sellPoint.situations.length; k++) { - let workspaceSituation = workspaceStrategy.sellPoint.situations[k] - let situation = { - name: workspaceSituation.name, - conditions: [] - } - - for (let m = 0; m < workspaceSituation.conditions.length; m++) { - let workspaceCondition = workspaceSituation.conditions[m] - let condition = { - name: workspaceCondition.name, - code: workspaceCondition.code - } - situation.conditions.push(condition) - } - strategy.sellPoint.situations.push(situation) - } - - for (let p = 0; p < workspaceStrategy.stopLoss.phases.length; p++) { - let workspacePhase = workspaceStrategy.stopLoss.phases[p] - let phase = { - name: workspacePhase.name, - code: workspacePhase.code, - situations: [] - } - - for (let k = 0; k < workspacePhase.situations.length; k++) { - let workspaceSituation = workspacePhase.situations[k] - let situation = { - name: workspaceSituation.name, - conditions: [] - } - - for (let m = 0; m < workspaceSituation.conditions.length; m++) { - let workspaceCondition = workspaceSituation.conditions[m] - let condition = { - name: workspaceCondition.name, - code: workspaceCondition.code - } - situation.conditions.push(condition) - } - phase.situations.push(situation) - } - strategy.stopLoss.phases.push(phase) - } - - for (let p = 0; p < workspaceStrategy.buyOrder.phases.length; p++) { - let workspacePhase = workspaceStrategy.buyOrder.phases[p] - let phase = { - name: workspacePhase.name, - code: workspacePhase.code, - situations: [] - } - - for (let k = 0; k < workspacePhase.situations.length; k++) { - let workspaceSituation = workspacePhase.situations[k] - let situation = { - name: workspaceSituation.name, - conditions: [] - } - - for (let m = 0; m < workspaceSituation.conditions.length; m++) { - let workspaceCondition = workspaceSituation.conditions[m] - let condition = { - name: workspaceCondition.name, - code: workspaceCondition.code - } - situation.conditions.push(condition) - } - phase.situations.push(situation) - } - strategy.buyOrder.phases.push(phase) - } - dataToSave.strategy.subStrategies.push(strategy) - } - - return dataToSave - } - - async function loadFromStrategyzer () { - try { - const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) - - let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY) - if (user === null) { - // if there is no user that means that we are logged off, which means this object can not be used. - return - } - - user = JSON.parse(user) - - const authId = user.authId - - let sessionToken - - const apolloClient = new Apollo.lib.ApolloClient({ - networkInterface: Apollo.lib.createNetworkInterface({ - uri: window.canvasApp.graphQL.masterAppApiUrl, - transportBatching: true - }), - connectToDevTools: true - }) - - /* Getting the FB that own the Strategies */ - - let tradingSystemSimulationClone = '' - let clones = window.localStorage.getItem('userClones') - if (clones === null || clones === '') { - if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> no user clones found at local storage. Can not get Strategies without them. ') } - return - } - clones = JSON.parse(clones) - for (let i = 0; i < clones.length; i++) { - let clone = clones[i] - if (clone.botType === 'Indicator') { - tradingSystemSimulationClone = clone.botSlug - } - } - - /* Getting all Strategies */ - - const networkInterface = Apollo.lib.createNetworkInterface({ - uri: window.canvasApp.graphQL.masterAppApiUrl - }) - - networkInterface.use([{ - applyMiddleware (req, next) { - req.options.headers = { - authorization: `Bearer ${accessToken}` - } - next() - } - }]) - - const getStrategies = () => { - return new Promise((resolve, reject) => { - apolloClient.query({ - query: GRAPHQL_QUERY_GET_STRATEGIES, - variables: { fbSlug: tradingSystemSimulationClone} - }) - .then(response => { - window.localStorage.setItem('userStrategies', JSON.stringify(response.data.strategizer_StrategyByFb)) - thisObject.strategizerData = JSON.parse(JSON.stringify(response.data.strategizer_StrategyByFb)) - - resolve({ strategies: response.data.strategizer_StrategyByFb.subStrategies}) - }) - .catch(err => { - if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> ApolloClient error getting user strategies -> err = ' + err.stack) } - reject(err) - }) - }) - } - - // To avoid race conditions, add asynchronous fetches to array - let fetchDataPromises = [] - - fetchDataPromises.push(getStrategies()) - - // When all asynchronous fetches resolve, authenticate user or throw error. - await Promise.all(fetchDataPromises).then(result => { - - }, err => { - if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> GraphQL Fetch Error -> err = ' + err.stack) } - }) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> err = ' + err.stack) } - } - } - - function deploydTradingSystem () { - thisObject.tradingSystem = newTradingSystem() - thisObject.tradingSystem.initialize(thisObject.strategizerData) - thisObject.isDeployed = true + generateStrategyParts() } function getContainer (point) { - let container - return undefined } - function draw () { + function createPart (partType, name, node, parentNode, chainParent, title) { + let payload = {} + if (chainParent === undefined) { + payload.targetPosition = { + x: canvas.floatingSpace.container.frame.width / 2, + y: canvas.floatingSpace.container.frame.height / 2 + } + } else { + payload.targetPosition = { + x: chainParent.payload.position.x, + y: chainParent.payload.position.y + } + } + if (title !== undefined) { + payload.subTitle = title + } else { + payload.subTitle = partType + } + + payload.visible = true + payload.title = name + payload.node = node + payload.parentNode = parentNode + payload.chainParent = chainParent + payload.onMenuItemClick = onMenuItemClick + + if (node.id === undefined) { + node.id = newUniqueId() + } + node.payload = payload + node.type = partType + canvas.floatingSpace.strategyPartConstructor.createStrategyPart(payload) + } + + function destroyPart (node) { + canvas.floatingSpace.strategyPartConstructor.destroyStrategyPart(node.payload) + } + + function generateStrategyParts () { + let lastPhase + let tradingSystem = thisObject.tradingSystem + + createPart('Trading System', '', tradingSystem, undefined, undefined) + + for (m = 0; m < tradingSystem.strategies.length; m++) { + let strategy = tradingSystem.strategies[m] + createPart('Strategy', strategy.name, strategy, tradingSystem, tradingSystem) + + createPart('Strategy Entry Event', '', strategy.entryPoint, strategy, strategy) + for (let k = 0; k < strategy.entryPoint.situations.length; k++) { + let situation = strategy.entryPoint.situations[k] + createPart('Situation', situation.name, situation, strategy.entryPoint, strategy.entryPoint, 'Strategy Entry' + ' ' + 'Situation') + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + createPart('Condition', condition.name, condition, situation, situation, 'Condition') + } + } + + createPart('Strategy Exit Event', '', strategy.exitPoint, strategy, strategy) + for (let k = 0; k < strategy.exitPoint.situations.length; k++) { + let situation = strategy.exitPoint.situations[k] + createPart('Situation', situation.name, situation, strategy.exitPoint, strategy.exitPoint, 'Strategy Exit' + ' ' + 'Situation') + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + createPart('Condition', condition.name, condition, situation, situation, 'Condition') + } + } + + createPart('Trade Entry Event', '', strategy.sellPoint, strategy, strategy) + for (let k = 0; k < strategy.sellPoint.situations.length; k++) { + let situation = strategy.sellPoint.situations[k] + createPart('Situation', situation.name, situation, strategy.sellPoint, strategy.sellPoint, 'Trade Entry' + ' ' + 'Situation') + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + createPart('Condition', condition.name, condition, situation, situation, 'Condition') + } + } + + createPart('Stop', '', strategy.stopLoss, strategy, strategy) + for (let p = 0; p < strategy.stopLoss.phases.length; p++) { + let phase = strategy.stopLoss.phases[p] + + let chainParent + if (p === 0) { + chainParent = strategy.stopLoss + } else { + chainParent = lastPhase + } + lastPhase = phase + createPart('Phase', phase.name, phase, strategy.stopLoss, chainParent, 'Stop Phase') + + for (let k = 0; k < phase.situations.length; k++) { + let situation = phase.situations[k] + createPart('Situation', situation.name, situation, phase, phase, 'Situation') + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + createPart('Condition', condition.name, condition, situation, situation, 'Condition') + } + } + } + + createPart('Take Profit', '', strategy.buyOrder, strategy, strategy) + for (let p = 0; p < strategy.buyOrder.phases.length; p++) { + let phase = strategy.buyOrder.phases[p] + let chainParent + if (p === 0) { + chainParent = strategy.buyOrder + } else { + chainParent = lastPhase + } + lastPhase = phase + createPart('Phase', phase.name, phase, strategy.buyOrder, chainParent, 'Take Profit Phase') + + for (let k = 0; k < phase.situations.length; k++) { + let situation = phase.situations[k] + createPart('Situation', situation.name, situation, phase, phase, 'Situation') + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + createPart('Condition', condition.name, condition, situation, situation, 'Condition') + } + } + } + } + } + + function destroyStrategyParts () { + let strategy = thisObject.tradingSystem + destroyPart(strategy) + + destroyPart(strategy.entryPoint) + for (let k = 0; k < strategy.entryPoint.situations.length; k++) { + let situation = strategy.entryPoint.situations[k] + destroyPart(situation) + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + destroyPart(condition) + } + } + + destroyPart(strategy.exitPoint) + for (let k = 0; k < strategy.exitPoint.situations.length; k++) { + let situation = strategy.exitPoint.situations[k] + destroyPart(situation) + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + destroyPart(condition) + } + } + + destroyPart(strategy.sellPoint) + for (let k = 0; k < strategy.sellPoint.situations.length; k++) { + let situation = strategy.sellPoint.situations[k] + destroyPart(situation) + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + destroyPart(condition) + } + } + + destroyPart(strategy.stopLoss) + for (let p = 0; p < strategy.stopLoss.phases.length; p++) { + let phase = strategy.stopLoss.phases[p] + destroyPart(strategy.stopLoss) + + for (let k = 0; k < phase.situations.length; k++) { + let situation = phase.situations[k] + destroyPart(situation) + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + destroyPart(condition) + } + } + } + + destroyPart(strategy.buyOrder) + for (let p = 0; p < strategy.buyOrder.phases.length; p++) { + let phase = strategy.buyOrder.phases[p] + destroyPart(strategy.buyOrder) + + for (let k = 0; k < phase.situations.length; k++) { + let situation = phase.situations[k] + destroyPart(situation) + + for (let m = 0; m < situation.conditions.length; m++) { + let condition = situation.conditions[m] + destroyPart(condition) + } + } + } + } + + async function onMenuItemClick (payload, action) { + switch (action) { + case 'Save Trading System': + { + let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer(canvas.strategySpace.workspace.tradingSystem) + return result + break + } + + case 'Open Settings': + break + case 'Delete Strategy': + + break + + case 'Reload Strategy': + + break + + case 'Save Strategy': + + break + + case 'Edit Code': + + break + case 'Add Phase': + { + let phaseParent = payload.node + let m = phaseParent.phases.length + let phase = { + name: 'New Phase', + code: '', + situations: [] + } + phaseParent.phases.push(phase) + let phaseChainParent + if (m > 0) { + phaseChainParent = phaseParent.phases[m - 1] + } else { + phaseChainParent = phaseParent + } + createPart('Phase', phase.name, phase, phaseParent, phaseChainParent, 'Phase') + } + break + case 'Add Situation': + { + let phase = payload.node + let m = phase.situations.length + let situation = { + name: 'New Situation', + conditions: [] + } + phase.situations.push(situation) + createPart('Situation', situation.name, situation, phase, phase, 'Situation') + } + break + case 'Add Condition': + { + let situation = payload.node + let m = situation.conditions.length + let condition = { + name: 'New Condition', + code: '' + } + situation.conditions.push(condition) + createPart('Condition', condition.name, condition, situation, situation, 'Condition') + } + break + case 'Delete Phase': { + deletePhase(payload.node) + break + } + case 'Delete Situation': { + deleteSituation(payload.node) + break + } + case 'Delete Condition': { + deleteCondition(payload.node) + break + } + default: + + } + } + + function deletePhase (node) { + let payload = node.payload + for (let k = 0; k < payload.parentNode.phases.length; k++) { + let phase = payload.parentNode.phases[k] + if (phase.id === node.id) { + for (let j = 0; j < phase.situations.length; j++) { + let situation = phase.situations[j] + for (let i = 0; i < situation.conditions.length; i++) { + let condition = situation.conditions[i] + destroyPart(condition) + cleanNode(condition) + } + situation.conditions = [] + destroyPart(situation) + phase.situations.splice(j, 1) + cleanNode(situation) + } + phase.situations = [] + /* Before deleting this phase we need to give its chainParent to the next phase down the chain */ + if (k < payload.parentNode.phases.length - 1) { + payload.parentNode.phases[k + 1].payload.chainParent = payload.chainParent + } + /* Continue destroying this phase */ + destroyPart(phase) + payload.parentNode.phases.splice(k, 1) + cleanNode(phase) + return + } + } + } + + function deleteSituation (node) { + let payload = node.payload + for (let j = 0; j < payload.parentNode.situations.length; j++) { + let situation = payload.parentNode.situations[j] + if (situation.id === node.id) { + for (let i = 0; i < situation.conditions.length; i++) { + let condition = situation.conditions[i] + destroyPart(condition) + cleanNode(condition) + } + situation.conditions = [] + destroyPart(situation) + payload.parentNode.situations.splice(j, 1) + cleanNode(situation) + return + } + } + } + + function deleteCondition (node) { + let payload = node.payload + for (let i = 0; i < payload.parentNode.conditions.length; i++) { + let condition = payload.parentNode.conditions[i] + if (condition.id === node.id) { + destroyPart(node) + payload.parentNode.conditions.splice(i, 1) + cleanNode(condition) + return + } + } + } + + function cleanNode (node) { + 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 } } From 4fd842263d9549aa1ba2eb5e8be33d464929a9ac Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 01:06:46 +0200 Subject: [PATCH 02/10] Highlights working and connected to Conditions Plotter --- FloatingSpace/StrategyPart.js | 67 ++++++++++++++++++++++-- FloatingSpace/StrategyPartConstructor.js | 16 +++--- Spaces/StrategySpace.js | 4 +- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index aab937faa..b82f45be2 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -16,6 +16,9 @@ function newStrategyPart () { payload: undefined, codeEditor: undefined, partTitle: undefined, + isExecuting: undefined, + highlight: highlight, + unHighlight: unHighlight, physics: physics, drawBackground: drawBackground, drawMiddleground: drawMiddleground, @@ -35,11 +38,15 @@ function newStrategyPart () { thisObject.container.frame.position.y = 0 let icon + let executingIcon let selfFocusEventSubscriptionId let selfNotFocuskEventSubscriptionId let selfDisplaceEventSubscriptionId + let isHighlighted + let highlightCounter = 0 + return thisObject function finalize () { @@ -128,10 +135,30 @@ function newStrategyPart () { } iconPhysics() + highlightPhisycs() + } + + function highlightPhisycs () { + highlightCounter-- + if (highlightCounter < 0) { + highlightCounter = 0 + isHighlighted = false + } + } + + function highlight () { + isHighlighted = true + highlightCounter = 30 + } + + function unHighlight () { + // isHighlighted = false + // highlightCounter = 0 } function iconPhysics () { icon = canvas.strategySpace.iconByPartType.get(thisObject.payload.node.type) + executingIcon = canvas.strategySpace.iconByPartType.get('attractive') } function onFocus () { @@ -173,7 +200,6 @@ function newStrategyPart () { function drawOnFocus () { if (thisObject.isOnFocus === true) { drawConnectingLine() - thisObject.menu.drawBackground() if (thisObject.codeEditor !== undefined) { thisObject.codeEditor.drawBackground() @@ -186,10 +212,12 @@ function newStrategyPart () { if (thisObject.codeEditor !== undefined) { if (thisObject.codeEditor.visible === false) { drawBodyAndPicture() + thisObject.menu.drawBackground() thisObject.menu.drawForeground() } } else { drawBodyAndPicture() + thisObject.menu.drawBackground() thisObject.menu.drawForeground() } } @@ -253,7 +281,7 @@ function newStrategyPart () { let label if (radius > 6) { - const MAX_LABEL_LENGTH = 30 + const MAX_LABEL_LENGTH = 20 label = thisObject.payload.subTitle label = addIndexNumber(label) @@ -327,7 +355,7 @@ function newStrategyPart () { let radius = thisObject.container.frame.radius if (radius > 0.5) { - const VISIBLE_RADIUS = 5 + let VISIBLE_RADIUS = 5 let visiblePosition = { x: thisObject.container.frame.position.x, @@ -346,12 +374,27 @@ function newStrategyPart () { browserCanvasContext.fill() browserCanvasContext.beginPath() - browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS / 2, 0, Math.PI * 2, true) + 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() + + if (isHighlighted === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius + let OPACITY = highlightCounter / 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 = 10 + browserCanvasContext.setLineDash([4, 20]) + browserCanvasContext.stroke() + } } /* Image */ @@ -365,5 +408,21 @@ function newStrategyPart () { thisObject.payload.floatingObject.currentImageSize) } } + + if (executingIcon !== undefined) { + if (icon.canDrawIcon === true) { + if (thisObject.isExecuting) { + const DISTANCE_FROM_CENTER = 40 + const EXECUTING_ICON_SIZE = 20 + + browserCanvasContext.drawImage( + icon, 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/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index a4715cd3b..db121269f 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -186,8 +186,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'attractive', - iconPathOff: 'attractive', + iconPathOn: 'pyramid', + iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -216,8 +216,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'attractive', - iconPathOff: 'attractive', + iconPathOn: 'pyramid', + iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -246,8 +246,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'attractive', - iconPathOff: 'attractive', + iconPathOn: 'pyramid', + iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -353,8 +353,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'attractive', - iconPathOff: 'attractive', + iconPathOn: 'pyramid', + iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, diff --git a/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index 999a9838d..7a9c0d166 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -47,7 +47,7 @@ function newStrategySpace () { ['Stop', 'pixel'], ['Take Profit', 'competition'], ['Phase', 'placeholder'], - ['Situation', 'attractive'], + ['Situation', 'pyramid'], ['Condition', 'testing'] ] @@ -64,7 +64,7 @@ function newStrategySpace () { 'analysis-1', 'approve', 'attach', - 'attractive', + 'pyramid', 'brainstorming', 'broken-link', 'chat', From 18081ba6400db3627bcf46cc6f2c01cfcd703a4e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 01:45:53 +0200 Subject: [PATCH 03/10] IsExecuting Icon working --- CockpitSpace/RestartSimulation.js | 10 ++++++++-- FloatingSpace/StrategyPart.js | 15 +++++++++------ Spaces/StrategySpace.js | 1 + 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CockpitSpace/RestartSimulation.js b/CockpitSpace/RestartSimulation.js index 0359ac40f..db8c9d22d 100644 --- a/CockpitSpace/RestartSimulation.js +++ b/CockpitSpace/RestartSimulation.js @@ -41,8 +41,6 @@ function newRestartSimulation () { } function initialize () { - thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width * 80 / 100 - thisObject.container.frame.position.y = 6 thisObject.container.frame.width = 250 thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - 12 @@ -170,6 +168,13 @@ function newRestartSimulation () { } } } + + positionPhysics() + } + + function positionPhysics () { + thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width * 1.25 + thisObject.container.frame.position.y = 6 } function draw () { @@ -256,3 +261,4 @@ function newRestartSimulation () { browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } } + diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index b82f45be2..6202076d3 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -158,7 +158,7 @@ function newStrategyPart () { function iconPhysics () { icon = canvas.strategySpace.iconByPartType.get(thisObject.payload.node.type) - executingIcon = canvas.strategySpace.iconByPartType.get('attractive') + executingIcon = canvas.strategySpace.iconCollection.get('attractive') } function onFocus () { @@ -409,14 +409,17 @@ function newStrategyPart () { } } + if (thisObject.isExecuting === true) { + let a = 1 + } if (executingIcon !== undefined) { - if (icon.canDrawIcon === true) { - if (thisObject.isExecuting) { - const DISTANCE_FROM_CENTER = 40 - const EXECUTING_ICON_SIZE = 20 + if (executingIcon.canDrawIcon === true) { + if (thisObject.isExecuting === 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 - EXECUTING_ICON_SIZE / 2, + 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/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index 7a9c0d166..05a58780d 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -64,6 +64,7 @@ function newStrategySpace () { 'analysis-1', 'approve', 'attach', + 'attractive', 'pyramid', 'brainstorming', 'broken-link', From bf28b5ee3747cef9d97480fe78afd1378490657f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 11:25:25 +0200 Subject: [PATCH 04/10] Fullscreen Mode working --- Animation.js | 2 +- Canvas.js | 13 ++- CockpitSpace/FullScreen.js | 166 +++++++++++++++++++++++++++++ Dashboard.js | 2 +- FloatingSpace/CodeEditor.js | 2 +- FloatingSpace/StrategyPartTitle.js | 4 +- Globals.js | 2 + Spaces/CockpitSpace.js | 11 ++ 8 files changed, 190 insertions(+), 12 deletions(-) create mode 100644 CockpitSpace/FullScreen.js diff --git a/Animation.js b/Animation.js index 01ce1f6f5..95bf8a85d 100644 --- a/Animation.js +++ b/Animation.js @@ -57,7 +57,7 @@ function newAnimation () { /* We set the canvas to its normal width and height */ browserCanvas.width = window.innerWidth - browserCanvas.height = window.innerHeight - window.canvasApp.topMargin + browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN /* First thing is to clear the actual canvas */ diff --git a/Canvas.js b/Canvas.js index 44b0f8a15..f41ffc738 100644 --- a/Canvas.js +++ b/Canvas.js @@ -187,7 +187,7 @@ function newCanvas () { try { let point = { x: event.pageX, - y: event.pageY - window.canvasApp.topMargin + y: event.pageY - CURRENT_TOP_MARGIN } dragVector.downX = point.x @@ -290,7 +290,7 @@ function newCanvas () { } let point = { x: event.pageX, - y: event.pageY - window.canvasApp.topMargin + y: event.pageY - CURRENT_TOP_MARGIN } let container @@ -398,7 +398,7 @@ function newCanvas () { try { let point = { x: event.pageX, - y: event.pageY - window.canvasApp.topMargin + y: event.pageY - CURRENT_TOP_MARGIN } viewPort.mousePosition.x = point.x @@ -444,7 +444,7 @@ function newCanvas () { let point = { x: event.pageX, - y: event.pageY - window.canvasApp.topMargin + y: event.pageY - CURRENT_TOP_MARGIN } let container @@ -539,7 +539,7 @@ function newCanvas () { let point = { x: event.pageX, - y: event.pageY - window.canvasApp.topMargin + y: event.pageY - CURRENT_TOP_MARGIN } event.mousePosition = point @@ -593,7 +593,7 @@ function newCanvas () { if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) { let point = { x: event.pageX, - y: event.pageY - window.canvasApp.topMargin + y: event.pageY - CURRENT_TOP_MARGIN } browserCanvas.style.cursor = 'grabbing' @@ -646,4 +646,3 @@ function newCanvas () { } } } - diff --git a/CockpitSpace/FullScreen.js b/CockpitSpace/FullScreen.js new file mode 100644 index 000000000..f9caaf7e5 --- /dev/null +++ b/CockpitSpace/FullScreen.js @@ -0,0 +1,166 @@ + +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 productCardsToTurnOn = [] + 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 = 250 + 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 + } else { + thisObject.status = 'Off' + goOutFullscreen() + CURRENT_TOP_MARGIN = window.canvasApp.topMargin + } + } + + 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 * 0.70 + 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 - 25, + 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/Dashboard.js b/Dashboard.js index 63e3176af..663c7cfa6 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -80,7 +80,7 @@ function newDashboard () { browserCanvas = document.getElementById('canvas') browserCanvas.width = window.innerWidth - browserCanvas.height = window.innerHeight - window.canvasApp.topMargin + browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN viewPort.initialize() } catch (err) { diff --git a/FloatingSpace/CodeEditor.js b/FloatingSpace/CodeEditor.js index 0d3b28d1d..8df2e4311 100644 --- a/FloatingSpace/CodeEditor.js +++ b/FloatingSpace/CodeEditor.js @@ -140,7 +140,7 @@ function newCodeEditor () { if (thisObject.visible === true) { let checkPosition = { x: textAreaPosition.x, - y: textAreaPosition.y - window.canvasApp.topMargin + y: textAreaPosition.y - CURRENT_TOP_MARGIN } if (thisObject.isVisibleFunction(checkPosition) === false) { deactivate() diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index 8597bff14..99c027b60 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -121,12 +121,12 @@ function newStrategyPartTitle () { if (thisObject.editMode === true) { let inputPosition = { x: 0, - y: 0 + window.canvasApp.topMargin + y: 0 + CURRENT_TOP_MARGIN } inputPosition = thisObject.container.frame.frameThisPoint(inputPosition) - if (inputPosition.y < window.canvasApp.topMargin) { exitEditMode() } + 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; ' diff --git a/Globals.js b/Globals.js index d25a99d1c..b458ec7bc 100644 --- a/Globals.js +++ b/Globals.js @@ -165,6 +165,8 @@ let INITIAL_ZOOM_LEVEL = -28.25 // This is the zoom level at the view port let INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser. let VERY_LARGE_NUMBER = 100000000000 +let CURRENT_TOP_MARGIN = window.canvasApp.topMargin + let maxDate = new Date(); maxDate.setMilliseconds(0); maxDate.setDate(maxDate.getDate() + 365 * 1); // We might have charts that projects data into the future. diff --git a/Spaces/CockpitSpace.js b/Spaces/CockpitSpace.js index 36d5477ff..8b50c4038 100644 --- a/Spaces/CockpitSpace.js +++ b/Spaces/CockpitSpace.js @@ -7,6 +7,7 @@ status: 'BOTTOM', assetBalances: undefined, restartSimulation: undefined, + fullscreen: undefined, draw: draw, physics: physics, getContainer: getContainer, @@ -37,6 +38,7 @@ thisObject.container = undefined thisObject.assetBalances = undefined thisObject.restartSimulation = undefined + thisObject.fullscreen = undefined } function initialize () { @@ -49,6 +51,10 @@ thisObject.restartSimulation = newRestartSimulation() thisObject.restartSimulation.container.connectToParent(thisObject.container) thisObject.restartSimulation.initialize() + + thisObject.fullscreen = newFullScreen() + thisObject.fullscreen.container.connectToParent(thisObject.container) + thisObject.fullscreen.initialize() } function onMouseClick (event) { @@ -70,6 +76,7 @@ function childrenPhysics () { thisObject.restartSimulation.physics() + thisObject.fullscreen.physics() } function thisObjectPhysics () { /* Check the limits */ @@ -109,6 +116,9 @@ container = thisObject.restartSimulation.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) { return thisObject.container } else { @@ -123,6 +133,7 @@ thisObject.assetBalances.draw() thisObject.restartSimulation.draw() + thisObject.fullscreen.draw() } function drawBackground () { From 158c64273312cc95f387e51a31ec6cab13e4be91 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 11:35:52 +0200 Subject: [PATCH 05/10] Repositioning FS text --- CockpitSpace/FullScreen.js | 7 ++++--- CockpitSpace/RestartSimulation.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CockpitSpace/FullScreen.js b/CockpitSpace/FullScreen.js index f9caaf7e5..2218de0c0 100644 --- a/CockpitSpace/FullScreen.js +++ b/CockpitSpace/FullScreen.js @@ -41,7 +41,7 @@ function newFullScreen () { } function initialize () { - thisObject.container.frame.width = 250 + thisObject.container.frame.width = 50 thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - 12 selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) @@ -110,7 +110,7 @@ function newFullScreen () { } function positionPhysics () { - thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width * 0.70 + thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width thisObject.container.frame.position.y = 6 } @@ -155,7 +155,7 @@ function newFullScreen () { label = 'FS' let labelPoint = { - x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 25, + 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) @@ -164,3 +164,4 @@ function newFullScreen () { browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } } + diff --git a/CockpitSpace/RestartSimulation.js b/CockpitSpace/RestartSimulation.js index db8c9d22d..2a5776e23 100644 --- a/CockpitSpace/RestartSimulation.js +++ b/CockpitSpace/RestartSimulation.js @@ -173,7 +173,7 @@ function newRestartSimulation () { } function positionPhysics () { - thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width * 1.25 + thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width - 50 thisObject.container.frame.position.y = 6 } From b9cd4979ce816ebe3789a6fc333a7bf399dd7dd5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 11:43:57 +0200 Subject: [PATCH 06/10] COCKPIT Resize Bug Fixed --- Spaces/CockpitSpace.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Spaces/CockpitSpace.js b/Spaces/CockpitSpace.js index 8b50c4038..e22da9736 100644 --- a/Spaces/CockpitSpace.js +++ b/Spaces/CockpitSpace.js @@ -42,6 +42,9 @@ } function initialize () { + thisObject.container.frame.position.x = 0 + thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT + canvasBrowserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize) selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) @@ -62,9 +65,6 @@ } function resize () { - thisObject.container.frame.position.x = 0 - thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT - thisObject.container.frame.width = browserCanvas.width thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT } From 58e1fca1889806665b7b8911dafbe77b2084673f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 12:14:33 +0200 Subject: [PATCH 07/10] BUG FIXed: Resize event implemented on chart space --- Spaces/ChartSpace.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Spaces/ChartSpace.js b/Spaces/ChartSpace.js index 2973b1706..5820e17e2 100644 --- a/Spaces/ChartSpace.js +++ b/Spaces/ChartSpace.js @@ -32,6 +32,8 @@ function newChartSpace () { thisObject.container.isDraggeable = false thisObject.container.isWheelable = false + let canvasBrowserResizedEventSubscriptionId + return thisObject function finalize () { @@ -40,6 +42,8 @@ function newChartSpace () { timeMachine.finalize() } + thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId) + thisObject.container.finalize() thisObject.container = undefined } @@ -48,6 +52,8 @@ function newChartSpace () { let initializedCounter = 0 let toInitialize = 1 + canvasBrowserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize) + /* We create the first of many possible time machines that could live at the Chart Space. */ let timeMachine = newTimeMachine() @@ -101,6 +107,11 @@ function newChartSpace () { } } + function resize () { + thisObject.container.frame.width = browserCanvas.width + thisObject.container.frame.height = COCKPIT_SPACE_POSITION + } + function fitIntoVisibleArea (point) { /* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */ From adf8ed633611ec08104c23137d6188b499c76caf Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 12:34:48 +0200 Subject: [PATCH 08/10] BUG Fixed: on screen mode no edition of title --- FloatingSpace/StrategyPartTitle.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index 99c027b60..fa50f325f 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -90,6 +90,8 @@ function newStrategyPartTitle () { } function getContainer (point) { + if (CURRENT_TOP_MARGIN === 0) { return } // Fullscreen mode does not allow INPUT elements + let container if (thisObject.editMode === true) { From 797503d9fe0814cf1af9491be9d94c78a5aa8c0b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 12:41:48 +0200 Subject: [PATCH 09/10] Bug Fixed: Not showing Edit Code at fullscreen --- FloatingSpace/CircularMenu.js | 1 + FloatingSpace/CircularMenuItem.js | 9 +++++++++ FloatingSpace/StrategyPartConstructor.js | 6 ++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/FloatingSpace/CircularMenu.js b/FloatingSpace/CircularMenu.js index d79c9c099..89113c067 100644 --- a/FloatingSpace/CircularMenu.js +++ b/FloatingSpace/CircularMenu.js @@ -65,6 +65,7 @@ function newCircularMenu () { menuItem.angle = menuItemInitialValue.angle menuItem.currentStatus = menuItemInitialValue.currentStatus menuItem.relatedStrategyPart = menuItemInitialValue.relatedStrategyPart + menuItem.dontShowAtFullscreen = menuItemInitialValue.dontShowAtFullscreen if (menuItem.label === undefined) { menuItem.type = 'Icon Only' diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 30553ac7a..f7d2c21db 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -24,6 +24,7 @@ function newCircularMenuItem () { container: undefined, payload: undefined, relatedStrategyPart: undefined, + dontShowAtFullscreen: undefined, physics: physics, drawBackground: drawBackground, drawForeground: drawForeground, @@ -88,6 +89,8 @@ function newCircularMenuItem () { } function getContainer (point) { + if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + let container if (thisObject.isDeployed === true) { if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { @@ -99,6 +102,8 @@ function newCircularMenuItem () { } function physics () { + if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + const INCREASE_STEP = 0.25 if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= INCREASE_STEP) { @@ -183,6 +188,8 @@ function newCircularMenuItem () { } function drawBackground () { + if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) { if (thisObject.type === 'Icon & Text') { let params = { @@ -206,6 +213,8 @@ function newCircularMenuItem () { } function drawForeground () { + if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + let menuPosition = { x: thisObject.currentRadius * 1.5, y: thisObject.container.frame.height / 2 diff --git a/FloatingSpace/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index db121269f..55d8e1342 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -346,7 +346,8 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 40 + angle: 40, + dontShowAtFullscreen: true }, { action: 'Add Situation', @@ -447,7 +448,8 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 20 + angle: 20, + dontShowAtFullscreen: true }, { action: 'Delete Condition', From 05630a98f915e6a0e4e4c156ecda2e0ead354526 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 20 May 2019 13:02:36 +0200 Subject: [PATCH 10/10] Small adjustment --- FloatingSpace/StrategyPartTitle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index fa50f325f..0af02da79 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -252,7 +252,7 @@ function newStrategyPartTitle () { } function trimTitle (title) { - const MAX_LABEL_LENGTH = 25 + const MAX_LABEL_LENGTH = 15 if (title.length > MAX_LABEL_LENGTH) { title = title.substring(0, MAX_LABEL_LENGTH) + '...' }