31 files changed
+1586
-324
No files matched your search
@@ -130,8 +130,6 @@ function newCanvas () {
|
||||
animation.initialize()
|
||||
|
||||
thisObject.animation = animation
|
||||
/* Low Level Infraestructure First */
|
||||
animation.addCallBackFunction('System Event Handler Physics', eventsServerClient.physics)
|
||||
|
||||
/* Spcaces Physics */
|
||||
animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics)
|
||||
@@ -401,36 +399,44 @@ function newCanvas () {
|
||||
|
||||
if ((event.ctrlKey === true || event.metaKey === true) && event.shiftKey === false && event.code === 'ArrowLeft') {
|
||||
let displaceVector = canvas.floatingSpace.oneScreenLeft()
|
||||
dragVector.downX = dragVector.downX + displaceVector.x
|
||||
dragVector.downY = dragVector.downY + displaceVector.y
|
||||
checkDrag()
|
||||
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()
|
||||
dragVector.downX = dragVector.downX + displaceVector.x
|
||||
dragVector.downY = dragVector.downY + displaceVector.y
|
||||
checkDrag()
|
||||
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()
|
||||
dragVector.downX = dragVector.downX + displaceVector.x
|
||||
dragVector.downY = dragVector.downY + displaceVector.y
|
||||
checkDrag()
|
||||
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()
|
||||
dragVector.downX = dragVector.downX + displaceVector.x
|
||||
dragVector.downY = dragVector.downY + displaceVector.y
|
||||
checkDrag()
|
||||
if (displaceVector !== undefined) {
|
||||
dragVector.downX = dragVector.downX + displaceVector.x
|
||||
dragVector.downY = dragVector.downY + displaceVector.y
|
||||
checkDrag()
|
||||
}
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -146,6 +146,13 @@ function newPlottersManager () {
|
||||
}
|
||||
}
|
||||
|
||||
let host = layer.networkNode.code.host
|
||||
let webPort = layer.networkNode.code.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,
|
||||
@@ -155,6 +162,9 @@ function newPlottersManager () {
|
||||
market,
|
||||
datetime,
|
||||
timeFrame,
|
||||
host,
|
||||
webPort,
|
||||
eventsServerClient,
|
||||
onProductStorageInitialized
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
function newDependenciesFilter () {
|
||||
thisObject = {
|
||||
createFilter: createFilter
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function createFilter (node) {
|
||||
let filters = new Map()
|
||||
recursiveFilter(node)
|
||||
|
||||
return Array.from(filters.keys())
|
||||
|
||||
function recursiveFilter (node) {
|
||||
filter(node.code)
|
||||
|
||||
let nodeDefinition = APP_SCHEMA_MAP.get(node.type)
|
||||
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
|
||||
}
|
||||
}
|
||||
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 }
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,23 +24,19 @@ function newProtocolNode () {
|
||||
|
||||
/* 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 (node[property.name] !== undefined) {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (lightingPath === undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includeReferencesInSavedPayload, includePayload)
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType)
|
||||
if (newLightingPath !== undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath)
|
||||
}
|
||||
if (lightingPath === undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includeReferencesInSavedPayload, includePayload)
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType)
|
||||
if (newLightingPath !== undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath)
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
@@ -19,8 +19,14 @@ function newReferenceAttachDetach () {
|
||||
}
|
||||
|
||||
function completeDetachment (node) {
|
||||
if (node.payload.referenceParent.payload !== undefined && node.payload.referenceParent.payload.uiObject !== undefined) {
|
||||
node.payload.referenceParent.payload.uiObject.isShowing = false
|
||||
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
|
||||
|
||||
@@ -6,27 +6,16 @@ function newSessionFunctions () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function runSession (node, functionLibraryProtocolNode, callBackFunction) {
|
||||
/* We can not run a sessionif its parent process is not running. Less if it does not have a parent. */
|
||||
if (node.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.')
|
||||
function runSession (node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, callBackFunction) {
|
||||
if (validations(node) !== true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.uiObject.isRunning !== true) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running to be able to run.')
|
||||
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)
|
||||
|
||||
if (node.payload.referenceParent === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Parent Process Instance need to reference a Process Definition.')
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
node.payload.uiObject.run(callBackFunction)
|
||||
node.payload.uiObject.run(eventsServerClient, callBackFunction)
|
||||
|
||||
let key = node.name + '-' + node.type + '-' + node.id
|
||||
|
||||
@@ -43,7 +32,7 @@ function newSessionFunctions () {
|
||||
'Initial Stop->Initial Take Profit->' +
|
||||
'Manage Stage->' +
|
||||
'Stop->Take Profit->' +
|
||||
'Phase->Formula->Next Phase Event->' +
|
||||
'Phase->Formula->Next Phase Event->Move to Phase Event->Phase->' +
|
||||
'Situation->Condition->Javascript Code->' +
|
||||
'Close Stage->Close Execution->' +
|
||||
'Announcement->Formula->'
|
||||
@@ -59,10 +48,13 @@ function newSessionFunctions () {
|
||||
|
||||
let session = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath)
|
||||
|
||||
let dependencyFilter = functionLibraryDependenciesFilter.createFilter(node.payload.referenceParent)
|
||||
|
||||
/* Raise event to run the session */
|
||||
let event = {
|
||||
session: JSON.stringify(session),
|
||||
tradingSystem: JSON.stringify(tradingSystem)
|
||||
tradingSystem: JSON.stringify(tradingSystem),
|
||||
dependencyFilter: JSON.stringify(dependencyFilter)
|
||||
}
|
||||
|
||||
eventsServerClient.raiseEvent(key, 'Run Session', event)
|
||||
@@ -74,9 +66,65 @@ function newSessionFunctions () {
|
||||
}
|
||||
|
||||
function stopSession (node, functionLibraryProtocolNode, callBackFunction) {
|
||||
if (validations(node) !== true) {
|
||||
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
|
||||
eventsServerClient.raiseEvent(key, 'Stop Session')
|
||||
|
||||
node.payload.uiObject.stop(callBackFunction)
|
||||
}
|
||||
|
||||
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 === 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.payload.referenceParent === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to reference a Trading System.')
|
||||
return
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,21 @@ function newTaskFunctions () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function runTask (node, functionLibraryProtocolNode, callBackFunction) {
|
||||
/* Check if it is possible to Run or not */
|
||||
if (node.bot === undefined) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
if (node.bot.processes.length === 0) {
|
||||
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()
|
||||
process.payload.uiObject.run(eventsServerClient)
|
||||
}
|
||||
|
||||
let lightingPath = '->Task->' +
|
||||
let taskLightingPath = '->Task->' +
|
||||
'Sensor Bot Instance->' +
|
||||
'Indicator Bot Instance->' +
|
||||
'Trading Bot Instance->' +
|
||||
@@ -58,25 +56,48 @@ function newTaskFunctions () {
|
||||
'Trading Bot->' +
|
||||
'Data Mine->'
|
||||
|
||||
let definition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath)
|
||||
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,
|
||||
definition: JSON.stringify(definition) // <- We need to do this workaround in order no to send unescaped charactars to the taskManager.
|
||||
taskDefinition: JSON.stringify(taskDefinition),
|
||||
networkDefinition: JSON.stringify(networkDefinition)
|
||||
}
|
||||
|
||||
if (node.payload.parentNode === undefined) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
if (isDebugging === true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
|
||||
eventsServerClient.raiseEvent('Task Server', 'Debug Task Started', event)
|
||||
return
|
||||
}
|
||||
|
||||
node.payload.uiObject.run(callBackFunction)
|
||||
node.payload.uiObject.run(eventsServerClient, callBackFunction)
|
||||
eventsServerClient.raiseEvent('Task Manager', 'Run Task', event)
|
||||
}
|
||||
|
||||
function stopTask (node, functionLibraryProtocolNode, 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)
|
||||
|
||||
let event = {
|
||||
taskId: node.id,
|
||||
taskName: node.name
|
||||
@@ -94,6 +115,60 @@ function newTaskFunctions () {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
function runAllTasks (taskManager, functionLibraryProtocolNode) {
|
||||
for (let i = 0; i < taskManager.tasks.length; i++) {
|
||||
let node = taskManager.tasks[i]
|
||||
|
||||
@@ -25,7 +25,7 @@ function newUiObjectsFromNodes () {
|
||||
blobService = newFileStorage()
|
||||
|
||||
// if (node.code === undefined) {
|
||||
node.code = '{ \n"includeDataMines": ["Masters", "Sparta", "TradingEngines"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Masters-WHB-ETH-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }'
|
||||
node.code = '{ \n"includeDataMines": ["Masters", "Sparta", "TradingEngines"],\n"includeTradingSystems": ["Sparta-WHB-BTC-USDT", "Example-ETH-USDT", "Sparta-BRR-BTC-USDT"],\n"includeSuperScripts": ["Masters"]\n }'
|
||||
// }
|
||||
|
||||
let code = JSON.parse(node.code)
|
||||
@@ -37,7 +37,7 @@ function newUiObjectsFromNodes () {
|
||||
|
||||
for (let i = 0; i < includeDataMines.length; i++) {
|
||||
let name = includeDataMines[i]
|
||||
blobService.getBlobToText('DataMines' + '/' + name, undefined, onFileReceived, true)
|
||||
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.')
|
||||
@@ -66,7 +66,7 @@ function newUiObjectsFromNodes () {
|
||||
|
||||
for (let i = 0; i < includeTradingSystems.length; i++) {
|
||||
let name = includeTradingSystems[i]
|
||||
blobService.getBlobToText('TradingSystems' + '/' + name, undefined, onFileReceived, true)
|
||||
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.')
|
||||
@@ -95,7 +95,7 @@ function newUiObjectsFromNodes () {
|
||||
|
||||
for (let i = 0; i < includeSuperScripts.length; i++) {
|
||||
let name = includeSuperScripts[i]
|
||||
blobService.getBlobToText('SuperScripts' + '/' + name, undefined, onFileReceived, true)
|
||||
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.')
|
||||
@@ -252,6 +252,10 @@ function newUiObjectsFromNodes () {
|
||||
}
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if (property.type === 'array') {
|
||||
node[property.name] = []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -547,7 +551,9 @@ function newUiObjectsFromNodes () {
|
||||
if (userAddingNew === false && uiObjectType === 'Task' && node.savedPayload !== undefined) {
|
||||
if (node.savedPayload.uiObject.isRunning === true) {
|
||||
if (node.payload.parentNode !== undefined) {
|
||||
tasksToRun.push(node)
|
||||
if (tasksToRun !== undefined) { // it might be undefined when you are spawning a task that was running while backed up
|
||||
tasksToRun.push(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -557,7 +563,9 @@ function newUiObjectsFromNodes () {
|
||||
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) {
|
||||
sessionsToRun.push(node)
|
||||
if (sessionsToRun !== undefined) { // it might be undefined when you are spawning a session that was running while backed up
|
||||
sessionsToRun.push(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
function newWebhookFunctions () {
|
||||
thisObject = {
|
||||
sendTestMessage: sendTestMessage
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function sendTestMessage (node, callBackFunction) {
|
||||
let testMessage = loadPropertyFromNodeConfig(node.payload, 'testMessage')
|
||||
let letURL = loadPropertyFromNodeConfig(node.payload, 'webhookURL')
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ function newWorkspace () {
|
||||
container: undefined,
|
||||
enabled: false,
|
||||
nodeChildren: undefined,
|
||||
eventsServerClients: new Map(),
|
||||
save: saveWorkspace,
|
||||
getHierarchyHeads: getHierarchyHeads,
|
||||
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
|
||||
@@ -59,6 +60,8 @@ function newWorkspace () {
|
||||
let functionLibraryOnFocus = newOnFocus()
|
||||
let functionLibrarySuperScripts = newSuperScriptsFunctions()
|
||||
let functionLibraryCCXTFunctions = newCCXTFunctions()
|
||||
let functionLibraryWebhookFunctions = newWebhookFunctions()
|
||||
let functionLibraryDependenciesFilter = newDependenciesFilter()
|
||||
|
||||
thisObject.nodeChildren = newNodeChildren()
|
||||
|
||||
@@ -82,14 +85,16 @@ function newWorkspace () {
|
||||
|
||||
function initialize () {
|
||||
try {
|
||||
let reset = window.localStorage.getItem('Reset')
|
||||
let savedWorkspace = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Workspace')
|
||||
|
||||
if (savedWorkspace === null) {
|
||||
if (savedWorkspace === null || reset !== null) {
|
||||
thisObject.workspaceNode = getWorkspace()
|
||||
} else {
|
||||
thisObject.workspaceNode = JSON.parse(savedWorkspace)
|
||||
}
|
||||
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
|
||||
setupEventsServerClients()
|
||||
thisObject.enabled = true
|
||||
|
||||
setInterval(saveWorkspace, 60000)
|
||||
@@ -98,6 +103,38 @@ function newWorkspace () {
|
||||
}
|
||||
}
|
||||
|
||||
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 code = JSON.parse(networkNode.code)
|
||||
host = code.host
|
||||
webSocketsPort = code.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)
|
||||
}
|
||||
@@ -115,6 +152,17 @@ function newWorkspace () {
|
||||
}
|
||||
|
||||
function saveWorkspace () {
|
||||
/* 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
|
||||
|
||||
for (let i = 0; i < workspace.rootNodes.length; i++) {
|
||||
let rootNode = workspace.rootNodes[i]
|
||||
if (rootNode === null) {
|
||||
canvas.cockpitSpace.setStatus('Could not save the Workspace. The state of the workspace in memory is corrupt, please reload the App.', 150, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -127,6 +175,19 @@ function newWorkspace () {
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -148,6 +209,7 @@ function newWorkspace () {
|
||||
break
|
||||
case 4:
|
||||
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, true)
|
||||
setupEventsServerClients()
|
||||
workingAtTask++
|
||||
break
|
||||
case 5:
|
||||
@@ -355,10 +417,15 @@ function newWorkspace () {
|
||||
downloadText(fileName, text)
|
||||
}
|
||||
|
||||
break
|
||||
case 'Debug Task':
|
||||
{
|
||||
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, true, callBackFunction)
|
||||
}
|
||||
break
|
||||
case 'Run Task':
|
||||
{
|
||||
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, callBackFunction)
|
||||
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, false, callBackFunction)
|
||||
}
|
||||
break
|
||||
case 'Stop Task':
|
||||
@@ -411,10 +478,14 @@ function newWorkspace () {
|
||||
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, callBackFunction)
|
||||
functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, callBackFunction)
|
||||
}
|
||||
break
|
||||
case 'Stop Session':
|
||||
|
||||
+13
-10
@@ -1,5 +1,5 @@
|
||||
|
||||
function newEventsServerClient () {
|
||||
function newEventsServerClient (host, port, hostName) {
|
||||
/* Web Sockets Connection */
|
||||
|
||||
const MODULE_NAME = 'System Event Handler'
|
||||
@@ -8,7 +8,10 @@ function newEventsServerClient () {
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
const WEB_SOCKETS_URL = 'ws://localhost:8080'
|
||||
if (host === '' || host === undefined) { host = 'localhost' }
|
||||
if (port === '' || port === undefined) { port = '8080' }
|
||||
|
||||
const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + ''
|
||||
let WEB_SOCKETS_CONNECTION
|
||||
|
||||
let thisObject = {
|
||||
@@ -56,12 +59,7 @@ function newEventsServerClient () {
|
||||
responseWaiters.set(command.callerId, responseCallBack)
|
||||
}
|
||||
|
||||
if (WEB_SOCKETS_CONNECTION.readyState === 1) {
|
||||
// 1 means connected and ready.
|
||||
sendToWebSocketServer(command)
|
||||
} else {
|
||||
console.log('WebSocket message could not be sent because the connection was not ready. Message = ' + JSON.stringify(command))
|
||||
}
|
||||
sendToWebSocketServer(command)
|
||||
}
|
||||
|
||||
function sendToWebSocketServer (command) {
|
||||
@@ -72,7 +70,12 @@ function newEventsServerClient () {
|
||||
commandsSentByTimestamp.set(stringNonce, timestamp)
|
||||
|
||||
let messageToWebSocketServer = 'Web Browser' + '|*|' + stringNonce + '|*|' + JSON.stringify(command)
|
||||
WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer)
|
||||
|
||||
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 createEventHandler (eventHandlerName, callerId, responseCallBack) {
|
||||
@@ -153,7 +156,7 @@ function newEventsServerClient () {
|
||||
}
|
||||
|
||||
if (thisObject.isConnected() !== true) {
|
||||
canvas.cockpitSpace.setStatus('Connection with the local backend lost. Please check that all localhost servers are running.', 100, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
canvas.cockpitSpace.setStatus('Connecting to ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
} else {
|
||||
retryCommandsPhysics()
|
||||
}
|
||||
|
||||
@@ -22,27 +22,35 @@ function newCircularProgressBar () {
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
let opacityCounters = []
|
||||
|
||||
let eventSubscriptionIdHeartbeat
|
||||
|
||||
let needToDrawRing = true
|
||||
let eventsServerClient
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
|
||||
if (eventSubscriptionIdHeartbeat !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat)
|
||||
}
|
||||
finalizeEventsServerClient()
|
||||
|
||||
thisObject.container = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.fitFunction = undefined
|
||||
}
|
||||
|
||||
function initialize (payload) {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ function newCodeEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
@@ -41,29 +39,12 @@ function newCodeEditor () {
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
|
||||
+786
-130
@@ -4,14 +4,9 @@ function newConditionEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
rawRadius: undefined,
|
||||
targetRadius: undefined,
|
||||
currentRadius: undefined,
|
||||
container: undefined,
|
||||
payload: undefined,
|
||||
deactivate: deactivate,
|
||||
@@ -25,93 +20,620 @@ function newConditionEditor () {
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
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.radius = 750
|
||||
thisObject.container.frame.containerName = MODULE_NAME
|
||||
|
||||
let isMouseOver = false
|
||||
let conditionStructure
|
||||
let scanResult
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
|
||||
conditionStructure = undefined
|
||||
scanResult = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
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.GREEN + ');' +
|
||||
'color:rgb(255, 255, 255);' +
|
||||
'width: ' + thisObject.container.frame.width + 'px;' +
|
||||
'height: ' + thisObject.container.frame.height + 'px'
|
||||
textArea.style.display = 'block'
|
||||
textArea.focus()
|
||||
conditionStructure = {
|
||||
code: thisObject.payload.node.code,
|
||||
orOperands: []
|
||||
}
|
||||
|
||||
scanDataMines()
|
||||
loadFromCode()
|
||||
EDITOR_ON_FOCUS = true
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
convertToCode()
|
||||
finalizePickers()
|
||||
|
||||
conditionStructure = undefined
|
||||
|
||||
if (thisObject.visible === true) {
|
||||
thisObject.visible = false
|
||||
}
|
||||
EDITOR_ON_FOCUS = false
|
||||
}
|
||||
|
||||
function loadFromCode () {
|
||||
if (thisObject.payload.node.code === undefined || thisObject.payload.node.code === '') { return }
|
||||
|
||||
/* LOGICAL ORs */
|
||||
let orArray = conditionStructure.code.split(' || ')
|
||||
for (let j = 0; j < orArray.length; j++) {
|
||||
let logicOperand = {
|
||||
code: orArray[j],
|
||||
index: j,
|
||||
comparison: {}
|
||||
}
|
||||
checkComparison(logicOperand, j)
|
||||
conditionStructure.orOperands.push(logicOperand)
|
||||
}
|
||||
|
||||
function checkComparison (logicOperand) {
|
||||
/* We are going to decompose the code into 2 comparison operators */
|
||||
logicOperand.comparison.operandA = { index: 0}
|
||||
logicOperand.comparison.operandB = { index: 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 = 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
|
||||
}
|
||||
|
||||
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.position.y = 0 - picker.container.frame.height / 2
|
||||
let optionsList = ['Greater Than', 'Less Than', 'Greater or Equal Than', 'Less or Equal Than', 'Equal To']
|
||||
picker.initialize(optionsList)
|
||||
|
||||
picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged)
|
||||
|
||||
/* Each comparison code may have one or more algebraic 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 Algebraic operation, meaning we will setup a Algebraic 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 = logicOperand.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 = logicOperand.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 = logicOperand.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 = logicOperand.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.operandA)
|
||||
updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA)
|
||||
updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA)
|
||||
}
|
||||
|
||||
function initializePickersSet (logicOperand, comparisonOperand, algebraOperand) {
|
||||
/* Get the ySign */
|
||||
let ySign
|
||||
if (algebraOperand.index === 0) {
|
||||
ySign = -1
|
||||
}
|
||||
if (algebraOperand.index === 1) {
|
||||
ySign = 1
|
||||
}
|
||||
|
||||
let properties
|
||||
let parent
|
||||
let current
|
||||
|
||||
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 * 1.0
|
||||
algebraOperand.whenPicker.container.frame.position.y = 0 - algebraOperand.whenPicker.container.frame.height / 2 + algebraOperand.whenPicker.container.frame.height * ySign
|
||||
current = ['Current', '1 Previous', '2 Previous', '3 Previous', '4 Previous', '5 Previous']
|
||||
algebraOperand.whenPicker.initialize(current, current)
|
||||
algebraOperand.whenPicker.visible = true
|
||||
|
||||
algebraOperand.algebraicPicker = newPicker()
|
||||
algebraOperand.algebraicPicker.name = 'Algebraic'
|
||||
algebraOperand.algebraicPicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.algebraicPicker.container.frame.position.x = 0 - algebraOperand.algebraicPicker.container.frame.width / 2 + algebraOperand.algebraicPicker.container.frame.width * 3.0
|
||||
algebraOperand.algebraicPicker.container.frame.position.y = 0 - algebraOperand.algebraicPicker.container.frame.height / 2 + algebraOperand.algebraicPicker.container.frame.height * ySign
|
||||
current = ['+ - * /', 'Plus', 'Minus', 'Times', 'Divided by']
|
||||
algebraOperand.algebraicPicker.initialize(current, current)
|
||||
algebraOperand.algebraicPicker.visible = true
|
||||
|
||||
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 * 3.0
|
||||
algebraOperand.dataMinePicker.container.frame.position.y = 0 - algebraOperand.dataMinePicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = scanResult
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.dataMinePicker.initialize(properties, current)
|
||||
parent = current
|
||||
algebraOperand.dataMinePicker.visible = true
|
||||
|
||||
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 * 2.0
|
||||
algebraOperand.botPicker.container.frame.position.y = 0 - algebraOperand.botPicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = parent[properties[0]]
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.botPicker.initialize(properties, current, parent)
|
||||
parent = current
|
||||
algebraOperand.botPicker.visible = true
|
||||
|
||||
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.0
|
||||
algebraOperand.productPicker.container.frame.position.y = 0 - algebraOperand.productPicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = parent[properties[0]]
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.productPicker.initialize(properties, current, parent)
|
||||
parent = current
|
||||
algebraOperand.productPicker.visible = true
|
||||
|
||||
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.0
|
||||
algebraOperand.propertyPicker.container.frame.position.y = 0 - algebraOperand.propertyPicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = productParent[productProperties[0]]
|
||||
current = current.properties
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.propertyPicker.initialize(properties, current, productParent, 'properties')
|
||||
parent = current
|
||||
algebraOperand.propertyPicker.visible = true
|
||||
|
||||
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.position.y = 0 - algebraOperand.valuePicker.container.frame.height / 2 + algebraOperand.valuePicker.container.frame.height * 1
|
||||
current = parent[properties[0]]
|
||||
properties = current.possibleValues
|
||||
algebraOperand.valuePicker.initialize(properties, current, parent, 'possibleValues')
|
||||
parent = current
|
||||
algebraOperand.valuePicker.visible = false
|
||||
|
||||
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 * 2.0
|
||||
algebraOperand.timeFramePicker.container.frame.position.y = 0 - algebraOperand.timeFramePicker.container.frame.height / 2 + algebraOperand.timeFramePicker.container.frame.height * ySign
|
||||
current = productParent[productProperties[0]]
|
||||
properties = current.validTimeFrames
|
||||
algebraOperand.timeFramePicker.initialize(properties, current, productParent, 'validTimeFrames')
|
||||
parent = current
|
||||
algebraOperand.timeFramePicker.visible = true
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
function updatePickers (logicOperand, comparisonOperand, algebraOperand) {
|
||||
let codeArray = algebraOperand.code.split('.')
|
||||
|
||||
let codeTimeFrame = codeArray[1].substring(2, 4) + '-' + codeArray[1].substring(4, 7)
|
||||
let 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 = codeArray[3 + propertyDisplacement]
|
||||
let codeValue = comparisonOperand.algebra.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 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
|
||||
}
|
||||
}
|
||||
scanResult = JSON.parse(JSON.stringify(selector))
|
||||
}
|
||||
|
||||
function convertToCode () {
|
||||
// if (comparisonOperatorA === undefined || comparisonOperatorB === undefined || comparisonPicker === undefined) { return }
|
||||
|
||||
// chart.at01hs.bollingerSubChannel.previous.previous.slope=== "Extreme"
|
||||
/*
|
||||
let code = ''
|
||||
|
||||
code = code + 'chart.at' + comparisonOperatorA.timeFramePicker.getSelected().replace('-', '')
|
||||
code = code + '.' + comparisonOperatorA.productPicker.getSelected()
|
||||
insertWhen(comparisonOperatorA)
|
||||
code = code + '.' + comparisonOperatorA.propertyPicker.getSelected()
|
||||
|
||||
switch (comparisonPicker.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 (comparisonPicker.getSelected() === 'Equal To') {
|
||||
code = code + '"' + comparisonOperatorA.valuePicker.getSelected() + '"'
|
||||
} else {
|
||||
code = code + 'chart.at' + comparisonOperatorB.timeFramePicker.getSelected().replace('-', '')
|
||||
code = code + '.' + comparisonOperatorB.productPicker.getSelected()
|
||||
insertWhen(comparisonOperatorB)
|
||||
code = code + '.' + comparisonOperatorB.propertyPicker.getSelected()
|
||||
}
|
||||
|
||||
thisObject.payload.node.code = code
|
||||
|
||||
function insertWhen (operator) {
|
||||
switch (operator.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.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[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)
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeOperator (operand) {
|
||||
if (operand === undefined) { return }
|
||||
|
||||
if (operand.whenPicker !== undefined) {
|
||||
operand.whenPicker.finalize()
|
||||
operand.whenPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
operand.algebraicPicker.finalize()
|
||||
operand.algebraicPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.dataMinePicker !== undefined) {
|
||||
operand.dataMinePicker.container.eventHandler.stopListening(operand.botPicker.eventSuscriptionId)
|
||||
operand.dataMinePicker.finalize()
|
||||
operand.dataMinePicker = undefined
|
||||
}
|
||||
|
||||
if (operand.botPicker !== undefined) {
|
||||
operand.botPicker.container.eventHandler.stopListening(operand.productPicker.eventSuscriptionId)
|
||||
operand.botPicker.finalize()
|
||||
operand.botPicker = undefined
|
||||
}
|
||||
|
||||
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 (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) {
|
||||
if (event.selected === 4) {
|
||||
// this means Equal To
|
||||
|
||||
comparisonOperatorA.valuePicker.visible = true
|
||||
comparisonOperatorB.whenPicker.visible = false
|
||||
comparisonOperatorB.algebraicPicker.visible = false
|
||||
comparisonOperatorB.dataMinePicker.visible = false
|
||||
comparisonOperatorB.botPicker.visible = false
|
||||
comparisonOperatorB.productPicker.visible = false
|
||||
comparisonOperatorB.propertyPicker.visible = false
|
||||
comparisonOperatorB.timeFramePicker.visible = false
|
||||
} else {
|
||||
comparisonOperatorA.valuePicker.visible = false
|
||||
comparisonOperatorB.whenPicker.visible = true
|
||||
comparisonOperatorB.algebraicPicker.visible = true
|
||||
comparisonOperatorB.dataMinePicker.visible = true
|
||||
comparisonOperatorB.botPicker.visible = true
|
||||
comparisonOperatorB.productPicker.visible = true
|
||||
comparisonOperatorB.propertyPicker.visible = true
|
||||
comparisonOperatorB.timeFramePicker.visible = 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 (conditionStructure === undefined) { return }
|
||||
|
||||
for (let i = 0; i < conditionStructure.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
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 (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
@@ -119,43 +641,139 @@ function newConditionEditor () {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * 2
|
||||
thisObject.container.frame.height = thisObject.container.frame.radius * 1 * 2
|
||||
|
||||
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 (operand.algebraicPicker !== undefined) {
|
||||
if (operand.algebraicPicker.visible === true) {
|
||||
container = operand.algebraicPicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
if (thisObject.visible === true) {
|
||||
let textAreaDiv = document.getElementById('textAreaDiv')
|
||||
textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; '
|
||||
|
||||
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.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
operandDrawBackground(logicOperand.comparison.operandA.algebra.operandA)
|
||||
operandDrawBackground(logicOperand.comparison.operandA.algebra.operandB)
|
||||
operandDrawBackground(logicOperand.comparison.operandB.algebra.operandA)
|
||||
operandDrawBackground(logicOperand.comparison.operandB.algebra.operandB)
|
||||
}
|
||||
}
|
||||
|
||||
function operandDrawBackground (operand) {
|
||||
if (operand === undefined) { return }
|
||||
|
||||
if (operand.whenPicker !== undefined) {
|
||||
if (operand.whenPicker.visible === true) {
|
||||
operand.whenPicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
if (operand.algebraicPicker.visible === true) {
|
||||
operand.algebraicPicker.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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function thisObjectDrawBackground () {
|
||||
if (thisObject.visible === true) {
|
||||
let position = {
|
||||
x: 0,
|
||||
@@ -164,54 +782,92 @@ function newConditionEditor () {
|
||||
|
||||
position = thisObject.container.frame.frameThisPoint(position)
|
||||
|
||||
let radius = thisObject.container.frame.radius * 2
|
||||
let radius = thisObject.container.frame.radius
|
||||
|
||||
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 + 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.GREEN + ', ' + 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.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
operandDrawForeground(logicOperand.comparison.operandA.algebra.operandA)
|
||||
operandDrawForeground(logicOperand.comparison.operandA.algebra.operandB)
|
||||
operandDrawForeground(logicOperand.comparison.operandB.algebra.operandA)
|
||||
operandDrawForeground(logicOperand.comparison.operandB.algebra.operandB)
|
||||
}
|
||||
}
|
||||
|
||||
function operandDrawForeground (operand) {
|
||||
if (operand === undefined) { return }
|
||||
|
||||
if (operand.whenPicker !== undefined) {
|
||||
if (operand.whenPicker.visible === true) {
|
||||
operand.whenPicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
if (operand.algebraicPicker.visible === true) {
|
||||
operand.algebraicPicker.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 drawForeground () {
|
||||
let iconPosition = {
|
||||
x: 0,
|
||||
y: thisObject.currentRadius * 1.5
|
||||
}
|
||||
|
||||
iconPosition = thisObject.container.frame.frameThisPoint(iconPosition)
|
||||
function thisObjectDrawForeground () {
|
||||
|
||||
/* 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,6 @@ function newConfigEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
@@ -41,29 +39,12 @@ function newConfigEditor () {
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
|
||||
@@ -285,7 +285,7 @@ function newFloatingObject () {
|
||||
}
|
||||
|
||||
function positionContraintsPhysics () {
|
||||
const MAX_DISTANCE_TO_PARENT = 3000
|
||||
const MAX_DISTANCE_TO_PARENT = 5000
|
||||
const MIN_DISTANCE_TO_PARENT = 100
|
||||
|
||||
if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) {
|
||||
|
||||
@@ -4,8 +4,6 @@ function newFormulaEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
@@ -41,29 +39,12 @@ function newFormulaEditor () {
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
|
||||
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 = 200
|
||||
thisObject.container.frame.height = 120
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
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 = 20
|
||||
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 - 10
|
||||
opacity = 0.4
|
||||
break
|
||||
case 1:
|
||||
fontSize = FONT_SIZE - 5
|
||||
opacity = 0.5
|
||||
break
|
||||
case 2:
|
||||
fontSize = FONT_SIZE - 0
|
||||
fontColor = UI_COLOR.BLACK
|
||||
opacity = 1
|
||||
break
|
||||
case 3:
|
||||
fontSize = FONT_SIZE - 5
|
||||
opacity = 0.5
|
||||
break
|
||||
case 4:
|
||||
fontSize = FONT_SIZE - 10
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
-14
@@ -117,17 +117,12 @@ function newUiObject () {
|
||||
let referenceLineCounter = 0
|
||||
let chainLineCounter = 0
|
||||
|
||||
let eventsServerClient
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
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')
|
||||
}
|
||||
finalizeEventsServerClient()
|
||||
|
||||
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfNotFocusEventSubscriptionId)
|
||||
@@ -173,6 +168,19 @@ function newUiObject () {
|
||||
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')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (payload, menuItemsInitialValues) {
|
||||
thisObject.payload = payload
|
||||
|
||||
@@ -257,7 +265,7 @@ function newUiObject () {
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
@@ -750,14 +758,17 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function run (callBackFunction) {
|
||||
function run (pEventsServerClient, callBackFunction) {
|
||||
finalizeEventsServerClient()
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
/* We setup the circular progress bar. */
|
||||
if (thisObject.circularProgressBar !== undefined) {
|
||||
thisObject.circularProgressBar.finalize()
|
||||
}
|
||||
|
||||
thisObject.circularProgressBar = newCircularProgressBar()
|
||||
thisObject.circularProgressBar.initialize(thisObject.payload)
|
||||
thisObject.circularProgressBar.initialize(thisObject.payload, eventsServerClient)
|
||||
thisObject.circularProgressBar.fitFunction = thisObject.fitFunction
|
||||
thisObject.circularProgressBar.container = thisObject.container
|
||||
|
||||
@@ -876,7 +887,11 @@ function newUiObject () {
|
||||
thisObject.isOnFocus = true
|
||||
|
||||
if (thisObject.payload !== undefined && thisObject.isOnFocus === true && thisObject.payload.referenceParent !== undefined) {
|
||||
thisObject.payload.referenceParent.payload.uiObject.isShowing = true
|
||||
if (thisObject.payload.referenceParent.payload !== undefined) {
|
||||
if (thisObject.payload.referenceParent.payload.uiObject !== undefined) {
|
||||
thisObject.payload.referenceParent.payload.uiObject.isShowing = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,7 +910,11 @@ function newUiObject () {
|
||||
thisObject.formulaEditor.deactivate()
|
||||
}
|
||||
|
||||
if (thisObject.payload !== undefined && thisObject.isOnFocus === false && thisObject.payload.referenceParent !== undefined) {
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1405,7 +1424,7 @@ function newUiObject () {
|
||||
let label
|
||||
|
||||
if (radius > 6) {
|
||||
const MAX_LABEL_LENGTH = 65
|
||||
const MAX_LABEL_LENGTH = 100
|
||||
|
||||
label = currentStatus
|
||||
|
||||
|
||||
@@ -157,6 +157,17 @@ function newUiObjectConstructor () {
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -243,7 +254,7 @@ function newUiObjectConstructor () {
|
||||
)
|
||||
menuItemsInitialValues.push(
|
||||
{
|
||||
action: 'change Distance to Paarent',
|
||||
action: 'Change Distance to Paarent',
|
||||
actionFunction: floatingObject.distanceToParentToggle,
|
||||
actionStatus: floatingObject.getDistanceToParent,
|
||||
currentStatus: true,
|
||||
@@ -258,7 +269,7 @@ function newUiObjectConstructor () {
|
||||
)
|
||||
menuItemsInitialValues.push(
|
||||
{
|
||||
action: 'change Arrangement Style',
|
||||
action: 'Change Arrangement Style',
|
||||
actionFunction: floatingObject.arrangementStyleToggle,
|
||||
actionStatus: floatingObject.getArrangementStyle,
|
||||
currentStatus: true,
|
||||
@@ -401,26 +412,26 @@ function newUiObjectConstructor () {
|
||||
if (nodeDefinition.editors.config === true) {
|
||||
uiObject.configEditor = newConfigEditor()
|
||||
uiObject.configEditor.isVisibleFunction = uiObject.isVisibleFunction
|
||||
uiObject.configEditor.initialize()
|
||||
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.initialize()
|
||||
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.initialize()
|
||||
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()
|
||||
uiObject.conditionEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false)
|
||||
}
|
||||
}
|
||||
if (nodeDefinition.addLeftIcons === true) {
|
||||
|
||||
@@ -211,7 +211,7 @@ function newFrame () {
|
||||
/* 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 - point.x, 2) + Math.pow(thisObject.position.y - point.y, 2))
|
||||
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
|
||||
|
||||
+74
-7
@@ -20,6 +20,7 @@ function newLayer () {
|
||||
plotterTypeIcon: undefined,
|
||||
baseAssetIcon: undefined,
|
||||
quotedAssetIcon: undefined,
|
||||
networkNode: undefined,
|
||||
checkStatusAtShutDown: checkStatusAtShutDown,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
@@ -128,6 +129,7 @@ function newLayer () {
|
||||
thisObject.plotterTypeIcon = undefined
|
||||
thisObject.baseAssetIcon = undefined
|
||||
thisObject.quotedAssetIcon = undefined
|
||||
thisObject.networkNode = undefined
|
||||
}
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
@@ -151,9 +153,10 @@ function newLayer () {
|
||||
let functionLibraryProtocolNode = newProtocolNode()
|
||||
let lightingPath =
|
||||
'->Layer->' +
|
||||
'Data Product->Single Market Data->' +
|
||||
'Session Independent Data->Session Based Data->' +
|
||||
'Session Reference->Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
|
||||
'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->' +
|
||||
'Market->Market Base Asset->Asset->' +
|
||||
'Market Quoted Asset->Asset->' +
|
||||
'Exchange Markets->Crypto Exchange->' +
|
||||
@@ -186,6 +189,10 @@ function newLayer () {
|
||||
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)
|
||||
@@ -195,6 +202,26 @@ function newLayer () {
|
||||
thisObject.quotedAsset = thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent
|
||||
thisObject.market = thisObject.baseAsset.code.codeName + '/' + thisObject.quotedAsset.code.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)
|
||||
@@ -206,6 +233,12 @@ 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 = APP_SCHEMA_MAP.get(node.type)
|
||||
let iconName
|
||||
@@ -525,7 +558,7 @@ function newLayer () {
|
||||
let label3 = thisObject.status.toUpperCase()
|
||||
|
||||
if (label1 !== undefined) {
|
||||
label1 = label1.substring(0, 22)
|
||||
label1 = label1.substring(0, 30)
|
||||
}
|
||||
|
||||
let backgroundColor = UI_COLOR.BLACK
|
||||
@@ -545,9 +578,43 @@ function newLayer () {
|
||||
|
||||
roundedCornersBackground(params)
|
||||
|
||||
drawLabel(label1, 1 / 2, 6 / 10, -5, 0, 17, thisObject.container)
|
||||
drawLabel(label2, 1 / 2, 8.2 / 10, -5, 0, 9, thisObject.container)
|
||||
drawLabel(label3, 1 / 2, 9.5 / 10, -5, 0, 9, thisObject.container)
|
||||
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)
|
||||
|
||||
@@ -172,7 +172,7 @@ function newPlotterPanel () {
|
||||
}
|
||||
|
||||
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)
|
||||
printLabel(value, X_AXIS, UI_PANEL.HEIGHT.NORMAL * valuePosition / 100 / heightFactor, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction, false, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +202,8 @@ function newPlotter () {
|
||||
if (newMarketFile !== undefined) {
|
||||
marketFile = newMarketFile
|
||||
recalculate()
|
||||
} else {
|
||||
logger.write('[WARN] setTimeFrame -> Could not change to market file for timeFrame = ' + pTimeFrame)
|
||||
}
|
||||
} else {
|
||||
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame)
|
||||
@@ -209,6 +211,8 @@ function newPlotter () {
|
||||
if (newFileCursor !== undefined) {
|
||||
fileCursor = newFileCursor
|
||||
recalculate()
|
||||
} else {
|
||||
logger.write('[WARN] setTimeFrame -> Could not change to market file for timeFrame = ' + pTimeFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -716,6 +720,10 @@ function newPlotter () {
|
||||
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
|
||||
}
|
||||
let dataPoint = {
|
||||
x: dataPointObject.x,
|
||||
y: dataPointObject.y
|
||||
|
||||
+17
-7
@@ -1,6 +1,5 @@
|
||||
let canvas
|
||||
let markets
|
||||
let eventsServerClient
|
||||
|
||||
let APP_SCHEMA_MAP = new Map()
|
||||
let APP_SCHEMA_ARRAY = []
|
||||
@@ -23,9 +22,7 @@ function newDashboard () {
|
||||
function start () {
|
||||
try {
|
||||
setBrowserEvents()
|
||||
|
||||
eventsServerClient = newEventsServerClient()
|
||||
eventsServerClient.initialize(setUpAppSchema)
|
||||
setUpAppSchema()
|
||||
|
||||
function setUpAppSchema () {
|
||||
APP_SCHEMA_ARRAY = getAppSchema()
|
||||
@@ -73,9 +70,22 @@ function newDashboard () {
|
||||
}
|
||||
|
||||
function setBrowserEvents () {
|
||||
window.onbeforeunload = onBrowserClosed
|
||||
function onBrowserClosed () {
|
||||
// canvas.designSpace.workspace.stopAllRunningTasks()
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', window.manageBackRefresh)
|
||||
|
||||
function saveWorkspace () {
|
||||
canvas.designSpace.workspace.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -74,7 +74,7 @@ function newProductStorage (name) {
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, callBackFunction) {
|
||||
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, callBackFunction) {
|
||||
try {
|
||||
datetime = pDatetime
|
||||
timeFrame = pTimeFrame
|
||||
@@ -90,7 +90,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let marketFiles = newMarketFiles()
|
||||
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, onMarketFileReady)
|
||||
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onMarketFileReady)
|
||||
thisObject.marketFiles.push(marketFiles)
|
||||
}
|
||||
break
|
||||
@@ -99,7 +99,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let dailyFiles = newDailyFiles()
|
||||
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, onDailyFileReady)
|
||||
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, onDailyFileReady)
|
||||
thisObject.dailyFiles.push(dailyFiles)
|
||||
}
|
||||
break
|
||||
@@ -108,7 +108,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let singleFile = newSingleFile()
|
||||
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, onSingleFileReady)
|
||||
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onSingleFileReady)
|
||||
thisObject.singleFile.push(singleFile)
|
||||
}
|
||||
break
|
||||
@@ -117,7 +117,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let fileSequences = newFileSequence()
|
||||
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, onFileSequenceReady)
|
||||
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onFileSequenceReady)
|
||||
thisObject.fileSequences.push(fileSequences)
|
||||
}
|
||||
break
|
||||
|
||||
+1
-4
@@ -347,17 +347,14 @@ function newRateScale () {
|
||||
|
||||
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 newMinDate = getDateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem)
|
||||
let newMaxRate = getRateFromPointAtContainer(point, rateCalculationsContainer, coordinateSystem)
|
||||
let xDifferenceMaxMin = coordinateSystem.max.x - coordinateSystem.min.x
|
||||
let yDifferenceMaxMin = coordinateSystem.max.y - coordinateSystem.min.y
|
||||
coordinateSystem.min.x = newMinDate.valueOf()
|
||||
coordinateSystem.max.x = newMinDate.valueOf() + xDifferenceMaxMin
|
||||
coordinateSystem.min.y = newMaxRate - yDifferenceMaxMin
|
||||
coordinateSystem.max.y = newMaxRate
|
||||
|
||||
|
||||
@@ -284,7 +284,8 @@ function newDesignSpace () {
|
||||
'arrangement-horizontal-bottom',
|
||||
'arrangement-vertical-right',
|
||||
'arrangement-vertical-left',
|
||||
'arrangement-concave'
|
||||
'arrangement-concave',
|
||||
'move-to-phase-event'
|
||||
]
|
||||
|
||||
for (let i = 0; i < iconsNames.length; i++) {
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ function newSplashScreen () {
|
||||
|
||||
fontSize = 35
|
||||
|
||||
title = 'Beta'
|
||||
title = 'Beta 4'
|
||||
|
||||
titlePoint = {
|
||||
x: thisObject.container.frame.width / 2 - title.length / 2 * fontSize * FONT_ASPECT_RATIO - 20,
|
||||
|
||||
+4
-2
@@ -244,7 +244,7 @@ function removeTime (datetime) {
|
||||
return dateOnly
|
||||
}
|
||||
|
||||
function printLabel (labelToPrint, x, y, opacity, fontSize, color, center, container, fitFunction, noDecimals) {
|
||||
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 }
|
||||
@@ -253,7 +253,9 @@ function printLabel (labelToPrint, x, y, opacity, fontSize, color, center, conta
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
let label = labelToPrint
|
||||
if (isNaN(label) === false && label !== '') {
|
||||
label = dynamicDecimals(labelToPrint)
|
||||
if (fixedDecimals !== true) {
|
||||
label = dynamicDecimals(labelToPrint)
|
||||
}
|
||||
label = label.toLocaleString()
|
||||
if (noDecimals === true) {
|
||||
label = Math.trunc(label)
|
||||
|
||||
@@ -105,10 +105,11 @@ function roundedCornersBackground (params) {
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, container, fontColor, noFrameX, noFrameY) {
|
||||
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,
|
||||
@@ -126,7 +127,7 @@ function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, contain
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + fontColor + ', 1)'
|
||||
browserCanvasContext.fillStyle = 'rgba(' + fontColor + ', ' + opacity + ')'
|
||||
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user