Merge pull request #112 from AAMasters/develop

Beta 4
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2020-05-03 15:48:15 +02:00
commit 3488b32104
31 files changed
+1586 -324

No files matched your search

+20 -14
View File
@@ -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
}
+10
View File
@@ -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)
}
}
}
}
+75 -4
View File
@@ -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
View File
@@ -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()
}
+15 -7
View File
@@ -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)
}
-19
View File
@@ -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
View File
@@ -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)
}
}
}
}
-19
View File
@@ -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 () {
+1 -1
View File
@@ -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) {
-19
View File
@@ -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 () {
+220
View File
@@ -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
View File
@@ -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
+17 -6
View File
@@ -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) {
+1 -1
View File
@@ -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
View File
@@ -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)
+1 -1
View File
@@ -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)
}
}
}
+8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+3 -2
View File
@@ -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)
}