Merge pull request #104 from AAMasters/develop

Release #4
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2019-12-09 11:53:31 +01:00
commit 797e5b6e58
37 files changed
+2937 -846

No files matched your search

+35 -18
View File
@@ -47,6 +47,7 @@ function newCanvas () {
let splashScreen
let lastContainerMouseOver
let lastShortcutKeyRejection
return thisObject
@@ -80,7 +81,7 @@ function newCanvas () {
}
}
async function initialize () {
function initialize () {
try {
initializeBrowserCanvas()
@@ -92,10 +93,10 @@ function newCanvas () {
thisObject.floatingSpace.initialize()
thisObject.topSpace = newTopSpace()
await thisObject.topSpace.initialize()
thisObject.topSpace.initialize()
thisObject.designerSpace = newDesignerSpace()
await thisObject.designerSpace.initialize()
thisObject.designerSpace.initialize()
thisObject.cockpitSpace = newCockpitSpace()
thisObject.cockpitSpace.initialize()
@@ -104,17 +105,10 @@ function newCanvas () {
thisObject.panelsSpace.initialize()
thisObject.chartSpace = newChartSpace()
thisObject.chartSpace.initialize(onCharSpaceInitialized)
thisObject.chartSpace.initialize()
thisObject.bottomSpace = thisObject.cockpitSpace
function onCharSpaceInitialized (err) {
try {
viewPort.raiseEvents() // These events will impacts on objects just initialized.
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onCharSpaceInitialized -> err = ' + err.stack) }
}
}
splashScreen = newSplashScreen()
splashScreen.initialize()
@@ -225,12 +219,27 @@ function newCanvas () {
return
}
if (event.shiftKey === true && event.code === 'ArrowLeft') {
if (event.altKey === true && event.code === 'ArrowLeft' || event.altKey === true && event.code === 'ArrowRight') {
thisObject.cockpitSpace.toMiddle()
return
}
if (event.shiftKey === true && event.ctrlKey && event.code === 'ArrowUp') {
thisObject.cockpitSpace.moveUp()
return
}
if (event.shiftKey === true && event.ctrlKey && event.code === 'ArrowDown') {
thisObject.cockpitSpace.moveDown()
return
}
if (event.shiftKey === true && event.ctrlKey === false && event.code === 'ArrowLeft') {
canvas.chartSpace.oneScreenLeft()
return
}
if (event.shiftKey === true && event.code === 'ArrowRight') {
if (event.shiftKey === true && event.ctrlKey === false && event.code === 'ArrowRight') {
canvas.chartSpace.oneScreenRight()
return
}
@@ -245,7 +254,7 @@ function newCanvas () {
return
}
if ((event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowLeft') {
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
@@ -253,7 +262,7 @@ function newCanvas () {
return
}
if ((event.ctrlKey === true || event.metaKey === true) && event.code === 'ArrowRight') {
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
@@ -285,7 +294,7 @@ function newCanvas () {
}
if ((event.ctrlKey === true || event.metaKey === true) && event.altKey === true) {
if (event.keyCode >= 65 && event.keyCode <= 90) {
if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 65 && event.keyCode <= 90)) {
/* From here we prevent the default behaviour */
event.preventDefault()
@@ -304,8 +313,16 @@ function newCanvas () {
nodeOnFocus.payload.uiObject.setValue('Shortcut Key Removed ')
return
} else {
nodeOnFocus.payload.uiObject.setErrorMessage('Key already in use by ' + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name)
return
if (lastShortcutKeyRejection !== event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name) {
/* The first time we show a warning that this key is in use. */
nodeOnFocus.payload.uiObject.setErrorMessage('Key already in use by ' + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name)
lastShortcutKeyRejection = event.key + nodeUsingThisKey.type + ' ' + nodeUsingThisKey.name
return
} else {
/* After the warning, we allow the key to be re-assigned */
nodeUsingThisKey.payload.uiObject.shortcutKey = ''
nodeUsingThisKey === undefined
}
}
}
/* If there is not node using this key and a node in focus, we assign this key to this node */
+67 -26
View File
@@ -21,40 +21,48 @@ function newPlottersManager () {
finalize: finalize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
let initializationReady = false
let productsPanel
let exchange
let market
setupContainer()
return thisObject
function finalize (callBackFunction) {
try {
for (let i = 0; i < productPlotters.length; i++) {
if (productPlotters[i].profile !== undefined) {
canvas.floatingSpace.profileBalls.destroyProfileBall(productPlotters[i].profile)
}
/* Destroyd the Note Set */
canvas.floatingSpace.noteSets.destroyNoteSet(productPlotters[i].noteSet)
/* Then the panels. */
for (let j = 0; j < productPlotters[i].panels.length; j++) {
canvas.panelsSpace.destroyPanel(productPlotters[i].panels[j])
}
/* Finally the Storage Objects */
productPlotters[i].storage.finalize()
if (productPlotters[i].plotter.finalize !== undefined) {
productPlotters[i].plotter.finalize()
}
productPlotters.splice(i, 1) // Delete item from array.
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
}
function finalize () {
for (let i = 0; i < productPlotters.length; i++) {
/* Then the panels. */
for (let j = 0; j < productPlotters[i].panels.length; j++) {
canvas.panelsSpace.destroyPanel(productPlotters[i].panels[j])
productPlotters[i].panels[j] = undefined
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
productPlotters[i].panels = undefined
/* Finalize the plotters */
if (productPlotters[i].plotter.finalize !== undefined) {
productPlotters[i].plotter.finalize()
}
productPlotters[i].plotter = undefined
/* Finally the Storage Objects */
productPlotters[i].storage.finalize()
productPlotters[i].storage = undefined
productPlotters[i] = undefined
}
productPlotters = []
productsPanel = undefined
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
}
function initialize (pProductsPanel, pExchange, pMarket, callBackFunction) {
@@ -168,13 +176,24 @@ function newPlottersManager () {
}
}
/* Now we have all the initial data loaded and ready to be delivered to the new instance of the plotter. */
let plotter = getNewPlotter(pProductCard.product.plotter.devTeam, pProductCard.product.plotter.codeName, pProductCard.product.plotter.moduleName)
let plotter
let productDefinition
if (pProductCard.product.plotter.legacy === false) {
plotter = newPlotter()
/* We take a snapwhot of the current product definition to be used by the plotter. */
let functionLibraryProtocolNode = newProtocolNode()
productDefinition = functionLibraryProtocolNode.getProtocolNode(pProductCard.product.node, false, true, true, false, false, true)
} else {
plotter = getNewPlotter(pProductCard.product.plotter.devTeam, pProductCard.product.plotter.codeName, pProductCard.product.plotter.moduleName)
}
plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true)
plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2
plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2
plotter.fitFunction = thisObject.fitFunction
plotter.initialize(storage, exchange, market, datetime, timePeriod, onPlotterInizialized)
plotter.initialize(storage, exchange, market, datetime, timePeriod, onPlotterInizialized, productDefinition)
function onPlotterInizialized () {
try {
@@ -190,6 +209,7 @@ function newPlottersManager () {
/* Lets load now this plotter panels. */
productPlotter.panels = []
/* Here is where we instantiate the legacy panels */
for (let i = 0; i < pProductCard.product.plotter.module.panels.length; i++) {
let panelConfig = pProductCard.product.plotter.module.panels[i]
@@ -209,6 +229,27 @@ function newPlottersManager () {
productPlotter.panels.push(plotterPanelHandle)
}
/* Here we instantiate the UI Defined Panels. */
if (productDefinition !== undefined) {
for (let i = 0; i < productDefinition.referenceParent.panels.length; i++) {
let panel = productDefinition.referenceParent.panels[i]
let parameters = {
devTeam: pProductCard.product.plotter.devTeam,
plotterCodeName: pProductCard.product.plotter.codeName,
moduleCodeName: pProductCard.product.plotter.moduleName,
panelCodeName: panel.id
}
let panelOwner = exchange + ' ' + market.assetB + '/' + market.assetA
let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, panelOwner, pProductCard.session, panel)
let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle, panelOwner)
/* Connect Panel to the Plotter via an Event. */
productPlotter.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange)
productPlotter.panels.push(plotterPanelHandle)
}
}
productPlotters.push(productPlotter)
callBack(GLOBAL.DEFAULT_OK_RESPONSE)
} catch (err) {
+28 -15
View File
@@ -28,17 +28,6 @@ function newTimeMachine () {
finalize: finalize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.detectMouseOver = true
thisObject.container.frame.width = TIME_MACHINE_WIDTH
thisObject.container.frame.height = TIME_MACHINE_HEIGHT
thisObject.container.frame.position.x = browserCanvas.width / 2 - TIME_MACHINE_WIDTH / 2
thisObject.container.frame.position.y = browserCanvas.height / 2 - TIME_MACHINE_HEIGHT / 2
let controlPanelHandle // We need this to destroy the Panel when this object is itself destroyed or no longer needs it...
// ... also to request a reference to the object for the cases we need it.
const SEPARATION_BETWEEN_TIMELINE_CHARTS = 1.5
@@ -52,21 +41,38 @@ function newTimeMachine () {
}
}
setupContainer()
return thisObject
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.detectMouseOver = true
thisObject.container.frame.width = TIME_MACHINE_WIDTH
thisObject.container.frame.height = TIME_MACHINE_HEIGHT
thisObject.container.frame.position.x = browserCanvas.width / 2 - TIME_MACHINE_WIDTH / 2
thisObject.container.frame.position.y = browserCanvas.height / 2 - TIME_MACHINE_HEIGHT / 2
}
function finalize () {
for (let i = 0; i < thisObject.charts.length; i++) {
let chart = thisObject.charts[i]
chart.finalize()
}
thisObject.container.finalize()
thisObject.container = undefined
thisObject.charts = []
thisObject.timeScale.finalize()
thisObject.timeScale = undefined
thisObject.rateScale.finalize()
thisObject.rateScale = undefined
thisObject.fitFunction = undefined
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
}
function initialize (callBackFunction) {
@@ -235,8 +241,12 @@ function newTimeMachine () {
} else {
if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) {
thisObject.container.eventHandler.raiseEvent('onMouseNotOver')
thisObject.timeScale.visible = false
thisObject.rateScale.visible = false
if (thisObject.timeScale !== undefined) {
thisObject.timeScale.visible = false
}
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.visible = false
}
}
return
}
@@ -261,6 +271,9 @@ function newTimeMachine () {
}
function childrenPhysics () {
if (thisObject.timeScale === undefined) { return }
if (thisObject.rateScale === undefined) { return }
thisObject.timeScale.physics()
thisObject.rateScale.physics()
+16 -11
View File
@@ -23,10 +23,6 @@ function newTimelineChart () {
finalize: finalize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.detectMouseOver = true
thisObject.fitFunction = canvas.chartSpace.fitIntoVisibleArea
let initializationReady = false
@@ -50,16 +46,25 @@ function newTimelineChart () {
let productsPanelHandle
let timePeriodScale
setupContainer()
return thisObject
function finalize () {
try {
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.detectMouseOver = true
}
plotterManager.finalize()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
}
function finalize () {
plotterManager.finalize()
plotterManager = undefined
timePeriodScale.finalize()
timePeriodScale = undefined
canvas.panelsSpace.destroyPanel(productsPanelHandle)
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
}
function initialize (pExchange, pMarket, pTimeLineCoordinateSystem, callBackFunction) {
+2 -2
View File
@@ -85,8 +85,8 @@ function newViewPort () {
function resize () {
TOP_MARGIN = 30 + TOP_SPACE_HEIGHT
BOTTOM_MARGIN = 30 + browserCanvas.height - COCKPIT_SPACE_POSITION
LEFT_MARGIN = 50
RIGHT_MARGIN = 50
LEFT_MARGIN = 0
RIGHT_MARGIN = 0
MARGINS = {
TOP: TOP_MARGIN,
BOTTOM: BOTTOM_MARGIN,
+19 -2
View File
@@ -3,6 +3,8 @@ let markets
let ecosystem = newEcosystem()
let systemEventHandler
let viewPort
let APP_SCHEMA_MAP = new Map()
let APP_SCHEMA_ARRAY = []
function newDashboard () {
const MODULE_NAME = 'Dashboard'
@@ -29,7 +31,23 @@ function newDashboard () {
viewPort = newViewPort()
systemEventHandler = newSystemEventHandler()
systemEventHandler.initialize(startCanvas)
systemEventHandler.initialize(setUpAppSchema)
function setUpAppSchema () {
APP_SCHEMA_ARRAY = getAppSchema()
for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) {
let nodeDefinition = APP_SCHEMA_ARRAY[i]
let key
if (nodeDefinition.subType !== undefined) {
key = nodeDefinition.type + '-' + nodeDefinition.subType
} else {
key = nodeDefinition.type
}
APP_SCHEMA_MAP.set(key, nodeDefinition)
}
console.log(APP_SCHEMA_MAP)
startCanvas()
}
function startCanvas () {
/* If this method is executed for a second time, it should finalize the current execution structure */
@@ -110,4 +128,3 @@ function newDashboard () {
}
}
}
-95
View File
@@ -1,95 +0,0 @@
function newStrategizerGateway () {
const MODULE_NAME = 'Strategizer Gateway'
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
idAtStrategizer: undefined,
strategizerData: undefined,
container: undefined,
loadFromStrategyzer: loadFromStrategyzer
}
let colletionItems = []
thisObject.container = newContainer()
thisObject.container.name = MODULE_NAME
thisObject.container.initialize()
thisObject.container.frame.width = 0
thisObject.container.frame.height = 0
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = false
let graphQLServer
return thisObject
async function loadFromStrategyzer () {
try {
const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY)
if (accessToken === null) {
logger.write('[ERROR] loadFromStrategyzer -> Can load from strategizer because the accessToken is missing.')
return
}
let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY)
if (user === null) {
logger.write('[ERROR] saveToStrategyzer -> Can not load from strategizer because user is not logged in. ')
return
}
user = JSON.parse(user)
if (window.canvasApp.executingAt === 'Local') {
window.localStorage.setItem(CANVAS_APP_NAME + '.' + MODULE_NAME + '.' + user.alias, 'Local File')
thisObject.strategizerData = JSON.parse('{"type":"Definition"}')
thisObject.idAtStrategizer = 'Local File'
return true
} else {
let fbSlug = 'simulator-bot-' + user.alias.replace('.', '')
graphQLServer = await axios({
url: window.canvasApp.graphQL.masterAppApiUrl,
method: 'post',
data: {
query:
`
query($fbSlug: String!){
strategizer_TradingSystemByFb(fbSlug: $fbSlug){
id
fbSlug
data
}
}
`,
variables: {
fbSlug: fbSlug
}
},
headers: {
authorization: 'Bearer ' + accessToken
}
})
if (graphQLServer.data.errors) {
logger.write('[ERROR] loadFromStrategyzer -> GraphQL Error: ' + JSON.stringify(graphQLServer.data.errors))
return false
} else {
thisObject.strategizerData = JSON.parse(JSON.stringify(graphQLServer.data.data.strategizer_TradingSystemByFb.data))
thisObject.idAtStrategizer = graphQLServer.data.data.strategizer_TradingSystemByFb.id
window.localStorage.setItem(CANVAS_APP_NAME + '.' + MODULE_NAME + '.' + user.alias, thisObject.idAtStrategizer)
return true
}
}
} catch (err) {
logger.write('[ERROR] loadFromStrategyzer -> err = ' + err.stack)
}
}
}
@@ -501,8 +501,8 @@ function newChainAttachDetach () {
completeDetachment(node, rootNodes)
return
}
case 'Code': {
node.payload.parentNode.code = undefined
case 'Javascript Code': {
node.payload.parentNode.javascriptCode = undefined
completeDetachment(node, rootNodes)
return
}
@@ -1100,10 +1100,10 @@ function newChainAttachDetach () {
completeAttachment(node, rootNodes)
}
break
case 'Code': {
case 'Javascript Code': {
node.payload.parentNode = attachToNode
node.payload.chainParent = attachToNode
node.payload.parentNode.code = node
node.payload.parentNode.javascriptCode = node
completeAttachment(node, rootNodes)
}
break
@@ -227,8 +227,8 @@ function newNodeChildren () {
case 'Condition': {
return countChildrenCondition(parentNode, childNode)
}
case 'Code': {
return countChildrenCode(parentNode, childNode)
case 'Javascript Code': {
return countChildrenJavascriptCode(parentNode, childNode)
}
default: {
console.log('WARNING this parentNode type is not listed at NodeChildren: ' + parentNode.type)
@@ -1483,7 +1483,7 @@ function newNodeChildren () {
return response
}
function countChildrenCode (parentNode, childNode) {
function countChildrenJavascriptCode (parentNode, childNode) {
let response = {
childrenCount: 0,
childIndex: undefined
@@ -69,7 +69,7 @@ function newNodeDeleter () {
deleteFormula: deleteFormula,
deleteSituation: deleteSituation,
deleteCondition: deleteCondition,
deleteCode: deleteCode
deleteJavascriptCode: deleteJavascriptCode
}
return thisObject
@@ -372,8 +372,8 @@ function newNodeDeleter () {
deleteCondition(rootNode, rootNodes)
break
}
case 'Code': {
deleteCode(rootNode, rootNodes)
case 'Javascript Code': {
deleteJavascriptCode(rootNode, rootNodes)
break
}
@@ -733,8 +733,8 @@ function newNodeDeleter () {
payload.parentNode.loop = undefined
}
if (node.code !== undefined) {
deleteCode(node.code, rootNodes)
if (node.javascriptCode !== undefined) {
deleteJavascriptCode(node.javascriptCode, rootNodes)
}
completeDeletion(node, rootNodes)
@@ -919,8 +919,8 @@ function newNodeDeleter () {
}
}
if (node.code !== undefined) {
deleteCode(node.code, rootNodes)
if (node.javascriptCode !== undefined) {
deleteJavascriptCode(node.javascriptCode, rootNodes)
}
if (node.panels !== undefined) {
@@ -946,8 +946,8 @@ function newNodeDeleter () {
}
}
if (node.code !== undefined) {
deleteCode(node.code, rootNodes)
if (node.javascriptCode !== undefined) {
deleteJavascriptCode(node.javascriptCode, rootNodes)
}
completeDeletion(node, rootNodes)
@@ -1697,17 +1697,17 @@ function newNodeDeleter () {
} else {
completeDeletion(node, rootNodes)
}
if (node.code !== undefined) {
deleteCode(node.code, rootNodes)
if (node.javascriptCode !== undefined) {
deleteJavascriptCode(node.javascriptCode, rootNodes)
}
destroyUiObject(node)
cleanNode(node)
}
function deleteCode (node, rootNodes) {
function deleteJavascriptCode (node, rootNodes) {
let payload = node.payload
if (payload.parentNode !== undefined) {
payload.parentNode.code = undefined
payload.parentNode.javascriptCode = undefined
} else {
completeDeletion(node, rootNodes)
}
@@ -7,7 +7,7 @@ function newOnFocus () {
function getNodeThatIsOnFocus (node) {
if (node === undefined) { return }
switch (node.type) {
case 'Code':
case 'Javascript Code':
{
if (node.payload.uiObject.isOnFocus === true) {
return node
@@ -7,7 +7,7 @@ function newProtocolNode () {
function getProtocolNode (node, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType) {
if (node === undefined) { return }
switch (node.type) {
case 'Code':
case 'Javascript Code':
{
let object = {
type: node.type,
@@ -29,7 +29,7 @@ function newProtocolNode () {
type: node.type,
subType: node.subType,
name: node.name,
code: getProtocolNode(node.code, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
javascriptCode: getProtocolNode(node.javascriptCode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
if (includeIds) {
object.id = node.id
@@ -1402,7 +1402,7 @@ function newProtocolNode () {
type: node.type,
subType: node.subType,
name: node.name,
code: getProtocolNode(node.code, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
javascriptCode: getProtocolNode(node.javascriptCode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
if (includeIds) {
object.id = node.id
@@ -1417,7 +1417,7 @@ function newProtocolNode () {
type: node.type,
subType: node.subType,
name: node.name,
code: getProtocolNode(node.code, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
javascriptCode: getProtocolNode(node.javascriptCode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
if (includeIds) {
object.id = node.id
@@ -1518,6 +1518,9 @@ function newProtocolNode () {
if (includePayload) {
object.savedPayload = getSavedPayload(node, includeReferences)
}
if (followReferenceParent) {
object.referenceParent = getProtocolNode(node.payload.referenceParent, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
return object
}
case 'Record Definition': {
@@ -1590,16 +1593,20 @@ function newProtocolNode () {
type: node.type,
subType: node.subType,
name: node.name,
code: node.code,
modules: []
}
if (node.modules !== undefined) {
for (let m = 0; m < node.modules.length; m++) {
let module = getProtocolNode(node.modules[m], removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
if (module !== undefined) {
object.modules.push(module)
if (excludeChildren !== true) {
if (node.modules !== undefined) {
for (let m = 0; m < node.modules.length; m++) {
let module = getProtocolNode(node.modules[m], removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
if (module !== undefined) {
object.modules.push(module)
}
}
}
}
if (includeIds) {
object.id = node.id
}
@@ -1613,9 +1620,16 @@ function newProtocolNode () {
type: node.type,
subType: node.subType,
name: node.name,
code: getProtocolNode(node.code, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType),
code: node.code,
javascriptCode: getProtocolNode(node.javascriptCode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType),
shapes: getProtocolNode(node.shapes, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType),
panels: []
}
if (includeParent) {
followAncestors = true
excludeChildren = true
object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
if (node.panels !== undefined) {
for (let m = 0; m < node.panels.length; m++) {
let panel = getProtocolNode(node.panels[m], removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
@@ -1637,7 +1651,7 @@ function newProtocolNode () {
type: node.type,
subType: node.subType,
name: node.name,
code: getProtocolNode(node.code, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
javascriptCode: getProtocolNode(node.javascriptCode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
if (includeIds) {
object.id = node.id
@@ -1648,6 +1662,90 @@ function newProtocolNode () {
return object
}
default: {
let nodeDefinition = APP_SCHEMA_MAP.get(node.type)
if (nodeDefinition !== undefined) {
if (removePersonalData === true && nodeDefinition.isPersonalData === true) { return }
let object = {
type: node.type,
subType: node.subType,
name: node.name,
code: node.code
}
if (excludeChildren !== true) {
/* Children Nodes */
if (nodeDefinition.properties !== undefined) {
for (i = 0; i < nodeDefinition.properties.length; i++) {
let property = nodeDefinition.properties[i]
switch (property.type) {
case 'node': {
if (node[property.name] !== undefined) {
if (excludeType !== property.childType) {
object[property.name] = getProtocolNode(node.payload.parentNode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
}
break
}
case 'array': {
if (node[property.name] !== undefined) {
if (excludeType !== property.childType) {
let nodePropertyArray = node[property.name]
object[property.name] = []
for (let m = 0; m < nodePropertyArray.length; m++) {
let protocolNode = getProtocolNode(nodePropertyArray[m], removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
if (protocolNode !== undefined) {
object[property.name].push(protocolNode)
}
}
}
}
break
}
}
}
}
}
/* Ancestors Nodes */
if (includeParent) {
if (nodeDefinition.followAncestors !== undefined) {
followAncestors = nodeDefinition.followAncestors
}
if (nodeDefinition.excludeChildren !== undefined) {
excludeChildren = nodeDefinition.excludeChildren
}
if (nodeDefinition.excludeType !== undefined) {
excludeType = nodeDefinition.excludeType
}
object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
/* Ancestors Nodes */
if (followAncestors) {
if (nodeDefinition.excludeChildren !== undefined) {
excludeChildren = nodeDefinition.excludeChildren
}
object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
if (parseCode) {
object.code = JSON.parse(node.code)
}
if (includeIds) {
object.id = node.id
}
if (includePayload) {
object.savedPayload = getSavedPayload(node, includeReferences)
}
if (followReferenceParent) {
object.referenceParent = getProtocolNode(node.payload.referenceParent, removePersonalData, parseCode, includeIds, includePayload, includeReferences, followReferenceParent, includeParent, followAncestors, excludeChildren, excludeType)
}
return object
}
}
}
}
@@ -44,6 +44,10 @@ function newReferenceAttachDetach () {
completeDetachment(node)
return
}
case 'Product Definition': {
completeDetachment(node)
return
}
}
}
@@ -85,6 +89,10 @@ function newReferenceAttachDetach () {
completeAttachment(node, attachToNode)
}
break
case 'Product Definition': {
completeAttachment(node, attachToNode)
}
break
}
}
@@ -7,7 +7,7 @@ function newShortcutKeys () {
function getNodeByShortcutKey (node, searchingKey) {
if (node === undefined) { return }
switch (node.type) {
case 'Code':
case 'Javascript Code':
{
if (node.payload.uiObject.shortcutKey === searchingKey) {
return node
File diff suppressed because it is too large. Load diff
+23 -32
View File
@@ -67,44 +67,23 @@ function newWorkspace () {
thisObject.workspaceNode = undefined
}
async function initialize () {
function initialize () {
try {
let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY)
if (user === null) {
return
}
user = JSON.parse(user)
let savedWorkspace = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Workspace')
let idAtStrategizer = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Strategizer Gateway' + '.' + user.alias)
let savedWorkspace = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Workspace' + '.' + user.alias)
if (savedWorkspace === null || idAtStrategizer === null) {
if (savedWorkspace === null) {
thisObject.workspaceNode.type = 'Workspace'
thisObject.workspaceNode.name = 'My Workspace'
functionLibraryUiObjectsFromNodes.createUiObjectFromNode(thisObject.workspaceNode, undefined, undefined)
spawnPosition.y = spawnPosition.y + 250
initializeLoadingFromStrategizer()
} else {
thisObject.workspaceNode = JSON.parse(savedWorkspace)
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
thisObject.enabled = true
}
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
thisObject.enabled = true
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
}
}
async function initializeLoadingFromStrategizer () {
let result = await canvas.designerSpace.strategizerGateway.loadFromStrategyzer()
if (result === true) {
thisObject.definition = canvas.designerSpace.strategizerGateway.strategizerData
thisObject.workspaceNode.rootNodes.push(thisObject.definition)
functionLibraryUiObjectsFromNodes.createUiObjectFromNode(thisObject.definition, undefined, undefined)
thisObject.enabled = true
}
}
function chainDetachNode (node) {
functionLibraryChainAttachDetach.chainDetachNode(node, thisObject.workspaceNode.rootNodes)
}
@@ -131,7 +110,7 @@ function newWorkspace () {
user = JSON.parse(user)
let textToSave = stringifyWorkspace()
window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace' + '.' + user.alias, textToSave)
window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave)
}
function stringifyWorkspace (removePersonalData) {
@@ -181,8 +160,12 @@ function newWorkspace () {
let taskManager = networkNode.taskManagers[i]
for (k = 0; k < taskManager.tasks.length; k++) {
let task = taskManager.tasks[k]
if (task.bot.type === 'Trading Bot Instance') {
tradingBotInstances.push(task.bot)
if (task.bot !== undefined) {
if (task.bot.type === 'Trading Bot Instance') {
if (task.bot.payload.floatingObject.isCollapsed !== true) {
tradingBotInstances.push(task.bot)
}
}
}
}
}
@@ -222,8 +205,11 @@ function newWorkspace () {
if (droppedNode.type === 'Workspace') {
stopAllRunningTasks()
functionLibraryNodeDeleter.deleteWorkspace(thisObject.workspaceNode, thisObject.workspaceNode.rootNodes)
canvas.floatingSpace.warmUp()
thisObject.workspaceNode = droppedNode
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
canvas.chartSpace.finalize()
canvas.chartSpace.initialize()
return
} else {
if (
@@ -262,8 +248,13 @@ function newWorkspace () {
}
}
async function onMenuItemClick (payload, action, callBackFunction) {
async function onMenuItemClick (payload, action, relatedUiObject, callBackFunction) {
switch (action) {
case 'Add UI Object':
{
functionLibraryUiObjectsFromNodes.addUIObject(payload.node, relatedUiObject)
}
break
case 'Share Workspace':
{
let text = stringifyWorkspace(true)
@@ -651,7 +642,7 @@ function newWorkspace () {
break
case 'Add Code':
{
functionLibraryUiObjectsFromNodes.addCode(payload.node)
functionLibraryUiObjectsFromNodes.addJavascriptCode(payload.node)
}
break
case 'Add Exchange Account':
@@ -936,7 +927,7 @@ function newWorkspace () {
break
}
case 'Delete Code': {
functionLibraryNodeDeleter.deleteCode(payload.node, thisObject.workspaceNode.rootNodes)
functionLibraryNodeDeleter.deleteJavascriptCode(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Exchange Account': {
+2
View File
@@ -76,6 +76,8 @@ function newCircularMenu () {
menuItem.dontShowAtFullscreen = menuItemInitialValue.dontShowAtFullscreen
menuItem.askConfirmation = menuItemInitialValue.askConfirmation
menuItem.confirmationLabel = menuItemInitialValue.confirmationLabel
menuItem.disableIfPropertyIsDefined = menuItemInitialValue.disableIfPropertyIsDefined
menuItem.propertyToCheckFor = menuItemInitialValue.propertyToCheckFor
if (menuItem.label === undefined) {
menuItem.type = 'Icon Only'
+26 -6
View File
@@ -10,6 +10,8 @@ function newCircularMenuItem () {
iconOn: undefined,
iconOff: undefined,
currentIcon: undefined,
disableIfPropertyIsDefined: undefined,
propertyToCheckFor: undefined,
action: undefined,
actionFunction: undefined,
actionStatus: undefined,
@@ -35,6 +37,7 @@ function newCircularMenuItem () {
payload: undefined,
relatedUiObject: undefined,
dontShowAtFullscreen: undefined,
isEnabled: true,
internalClick: internalClick,
physics: physics,
drawBackground: drawBackground,
@@ -93,6 +96,8 @@ function newCircularMenuItem () {
thisObject.payload = undefined
thisObject.actionFunction = undefined
thisObject.actionStatus = undefined
thisObject.disableIfPropertyIsDefined = undefined
thisObject.propertyToCheckFor = undefined
}
function initialize (pPayload) {
@@ -143,7 +148,6 @@ function newCircularMenuItem () {
thisObject.container.frame.position.y = thisObject.container.frame.radius * 3 / 7 * Math.sin(toRadians(thisObject.angle)) - thisObject.container.frame.height / 2
/* Temporary Status impacts on the label to use and the background of that label */
if (temporaryStatusCounter > 0) {
temporaryStatusCounter--
}
@@ -155,6 +159,16 @@ function newCircularMenuItem () {
thisObject.nextAction = thisObject.action
}
/* Here we will check if we need to monitor a property that influences the status of the Menu Item. */
if (thisObject.disableIfPropertyIsDefined === true) {
if (thisObject.payload.node[thisObject.propertyToCheckFor] === undefined) {
/* This menu item is enabled. */
thisObject.isEnabled = true
} else {
/* This menu item is disabled. */
thisObject.isEnabled = false
}
}
iconPhysics()
}
@@ -211,9 +225,11 @@ function newCircularMenuItem () {
}
function onMouseClick () {
if (thisObject.isEnabled === false) { return }
if (thisObject.label === undefined) {
/* This is what we have in the case of menu items that are only Icons. In this situation there is no complex logic, just execute the specified action. */
thisObject.actionFunction(thisObject.payload, thisObject.action)
thisObject.actionFunction(thisObject.payload, thisObject.action, thisObject.relatedUiObject)
return
}
@@ -245,7 +261,7 @@ function newCircularMenuItem () {
}
/* Execute the action and wait for callbacks to update our statuus. */
thisObject.actionFunction(thisObject.payload, thisObject.action, onPrimaryCallBack)
thisObject.actionFunction(thisObject.payload, thisObject.action, thisObject.relatedUiObject, onPrimaryCallBack)
return
}
if (temporaryStatus === STATUS_PRIMARY_WORK_DONE && thisObject.secondaryAction !== undefined) {
@@ -255,7 +271,7 @@ function newCircularMenuItem () {
}
/* Execute the action and wait for callbacks to update our statuus. */
thisObject.actionFunction(thisObject.payload, thisObject.secondaryAction, onSecondaryCallBack)
thisObject.actionFunction(thisObject.payload, thisObject.secondaryAction, thisObject.relatedUiObject, onSecondaryCallBack)
return
}
@@ -322,12 +338,16 @@ function newCircularMenuItem () {
if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) {
if (thisObject.type === 'Icon & Text') {
let backgroundColor = backgroundColorToUse
if (thisObject.isEnabled === false) {
backgroundColor = UI_COLOR.GREY
}
let params = {
cornerRadius: 3,
lineWidth: 0.1,
container: thisObject.container,
borderColor: UI_COLOR.DARK,
backgroundColor: backgroundColorToUse,
backgroundColor: backgroundColor,
castShadow: false,
xOffset: 40
}
@@ -362,6 +382,7 @@ function newCircularMenuItem () {
iconSize = thisObject.currentRadius
}
if (thisObject.icon === undefined) { return }
if (thisObject.icon.canDrawIcon === true && thisObject.currentRadius > 1 && thisObject.isDeployed === true) {
browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - iconSize, menuPosition.y - iconSize, iconSize * 2, iconSize * 2)
@@ -387,4 +408,3 @@ function newCircularMenuItem () {
}
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
function newCodeEditor () {
const MODULE_NAME = 'Circular Menu Iem'
const MODULE_NAME = 'Code Editor'
let thisObject = {
isVisibleFunction: undefined,
@@ -80,6 +80,7 @@ function newCodeEditor () {
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
@@ -90,7 +91,7 @@ function newCodeEditor () {
'overflow:hidden;' +
'font-family: ' + UI_FONT.PRIMARY + ';' +
'font-size: 12px;' +
'background-color: rgb(204, 88, 53);' +
'background-color: rgb(' + UI_COLOR.RUSTED_RED + ');' +
'color:rgb(255, 255, 255);' +
'width: ' + thisObject.container.frame.width + 'px;' +
'height: ' + thisObject.container.frame.height + 'px'
@@ -212,4 +213,3 @@ function newCodeEditor () {
}
}
}
+215
View File
@@ -0,0 +1,215 @@
function newConditionEditor () {
const MODULE_NAME = 'Condition Editor'
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,
activate: activate,
physics: physics,
drawBackground: drawBackground,
drawForeground: drawForeground,
getContainer: getContainer,
finalize: finalize,
initialize: initialize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isClickeable = false
thisObject.container.isDraggeable = false
thisObject.container.detectMouseOver = false
thisObject.container.frame.radius = 0
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
let isMouseOver = false
return thisObject
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 () {
if (thisObject.visible === true) {
thisObject.visible = false
let textArea = document.getElementById('textArea')
textArea.style.display = 'none'
thisObject.payload.node.code = textArea.value
}
}
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: 12px;' +
'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()
}
function getContainer (point) {
let container
if (thisObject.visible === true) {
if (point.x === VERY_LARGE_NUMBER) {
/* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that
anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is
triggered. We compensate recognizing this coordinate and returning our container. */
return thisObject.container
}
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
return thisObject.container
} else {
return undefined
}
}
}
function physics () {
if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) {
if (thisObject.currentRadius < thisObject.targetRadius) {
thisObject.currentRadius = thisObject.currentRadius + 0.5
} else {
thisObject.currentRadius = thisObject.currentRadius - 0.5
}
}
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 (thisObject.visible === true) {
let textAreaDiv = document.getElementById('textAreaDiv')
textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; '
}
}
function drawBackground () {
if (thisObject.visible === true) {
let position = {
x: 0,
y: 0
}
position = thisObject.container.frame.frameThisPoint(position)
let radius = thisObject.container.frame.radius * 2
if (radius > 0.5) {
browserCanvasContext.beginPath()
browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')'
browserCanvasContext.fill()
browserCanvasContext.beginPath()
browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + 1 + ')'
browserCanvasContext.fill()
}
}
}
function drawForeground () {
let iconPosition = {
x: 0,
y: thisObject.currentRadius * 1.5
}
iconPosition = thisObject.container.frame.frameThisPoint(iconPosition)
/* Menu Item */
if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) {
browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2)
/* Menu Label */
let label = 'Code looks good!'
let labelPoint
let fontSize = 10
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) {
labelPoint = {
x: iconPosition.x + thisObject.currentRadius + 10,
y: iconPosition.y + fontSize * FONT_ASPECT_RATIO
}
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
}
}
+221
View File
@@ -0,0 +1,221 @@
function newConfigEditor () {
const MODULE_NAME = 'Config Editor'
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,
activate: activate,
physics: physics,
drawBackground: drawBackground,
drawForeground: drawForeground,
getContainer: getContainer,
finalize: finalize,
initialize: initialize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isClickeable = false
thisObject.container.isDraggeable = false
thisObject.container.detectMouseOver = false
thisObject.container.frame.radius = 0
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
let isMouseOver = false
return thisObject
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 () {
if (thisObject.visible === true) {
thisObject.visible = false
let textArea = document.getElementById('textArea')
textArea.style.display = 'none'
thisObject.payload.node.code = textArea.value
try {
let code = JSON.parse(thisObject.payload.node.code)
} catch (err) {
thisObject.payload.uiObject.setErrorMessage(err.message, 10)
}
}
}
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: 12px;' +
'background-color: rgb(' + UI_COLOR.DARK_TURQUOISE + ');' +
'color:rgb(255, 255, 255);' +
'width: ' + thisObject.container.frame.width + 'px;' +
'height: ' + thisObject.container.frame.height + 'px'
textArea.style.display = 'block'
textArea.focus()
}
function getContainer (point) {
let container
if (thisObject.visible === true) {
if (point.x === VERY_LARGE_NUMBER) {
/* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that
anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is
triggered. We compensate recognizing this coordinate and returning our container. */
return thisObject.container
}
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
return thisObject.container
} else {
return undefined
}
}
}
function physics () {
if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) {
if (thisObject.currentRadius < thisObject.targetRadius) {
thisObject.currentRadius = thisObject.currentRadius + 0.5
} else {
thisObject.currentRadius = thisObject.currentRadius - 0.5
}
}
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 (thisObject.visible === true) {
let textAreaDiv = document.getElementById('textAreaDiv')
textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; '
}
}
function drawBackground () {
if (thisObject.visible === true) {
let position = {
x: 0,
y: 0
}
position = thisObject.container.frame.frameThisPoint(position)
let radius = thisObject.container.frame.radius * 2
if (radius > 0.5) {
browserCanvasContext.beginPath()
browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')'
browserCanvasContext.fill()
browserCanvasContext.beginPath()
browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + 1 + ')'
browserCanvasContext.fill()
}
}
}
function drawForeground () {
let iconPosition = {
x: 0,
y: thisObject.currentRadius * 1.5
}
iconPosition = thisObject.container.frame.frameThisPoint(iconPosition)
/* Menu Item */
if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) {
browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2)
/* Menu Label */
let label = 'Code looks good!'
let labelPoint
let fontSize = 10
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) {
labelPoint = {
x: iconPosition.x + thisObject.currentRadius + 10,
y: iconPosition.y + fontSize * FONT_ASPECT_RATIO
}
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
}
}
+10 -6
View File
@@ -170,11 +170,6 @@ function newFloatingLayer () {
let floatingObject = invisibleFloatingObjects[invisibleFloatingObjects.length - i - 1]
floatingObject.drawForeground()
}
for (let i = 0; i < invisibleFloatingObjects.length; i++) {
let floatingObject = invisibleFloatingObjects[i]
floatingObject.drawOnFocus()
}
}
function drawVisibleObjects () {
@@ -193,6 +188,12 @@ function newFloatingLayer () {
floatingObject.drawForeground()
}
/* Invisible objects on focus (freezed) should still have some priority */
for (let i = 0; i < invisibleFloatingObjects.length; i++) {
let floatingObject = invisibleFloatingObjects[i]
floatingObject.drawOnFocus()
}
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i]
floatingObject.drawOnFocus()
@@ -206,6 +207,7 @@ function newFloatingLayer () {
if (floatingObject.isFrozen === false && floatingObject.isParentCollapsed === false) {
visibleFloatingObjects.push(floatingObject)
invisibleFloatingObjects.splice(i, 1) // Delete item from array.
makeVisible()
return // Only one at the time.
}
}
@@ -218,6 +220,7 @@ function newFloatingLayer () {
if (floatingObject.isFrozen === true || floatingObject.isParentCollapsed === true) {
invisibleFloatingObjects.push(floatingObject)
visibleFloatingObjects.splice(i, 1) // Delete item from array.
makeInvisible()
return // Only one at the time.
}
}
@@ -261,6 +264,8 @@ function newFloatingLayer () {
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i]
if (canvas.floatingSpace.isItFar(floatingObject.payload)) { continue }
if (floatingObject.positionLocked === false) {
floatingObject.container.frame.position.x = floatingObject.container.frame.position.x + floatingObject.currentSpeed.x
floatingObject.container.frame.position.y = floatingObject.container.frame.position.y + floatingObject.currentSpeed.y
@@ -747,4 +752,3 @@ function newFloatingLayer () {
}
}
}
+56 -45
View File
@@ -176,78 +176,86 @@ function newFloatingObject () {
}
function physics () {
collapsePhysics()
if (canvas.floatingSpace.isItFar(thisObject.payload)) { return }
thisObjectPhysics()
thisObject.payload.uiObject.physics()
frozenPhysics()
collapsePhysics()
tensionPhysics()
}
function frozenPhysics () {
if (thisObject.frozenManually === false) {
let parent = thisObject.payload.chainParent
if (parent !== undefined && parent.payload !== undefined) {
thisObject.isFrozen = parent.payload.floatingObject.isFrozen
}
if (thisObject.frozenManually !== false) { return }
if (thisObject.payload === undefined) { return }
let parent = thisObject.payload.chainParent
if (parent !== undefined && parent.payload !== undefined) {
thisObject.isFrozen = parent.payload.floatingObject.isFrozen
}
}
function collapsePhysics () {
let parent = thisObject.payload.chainParent
if (parent !== undefined) {
thisObject.isParentCollapsed = parent.payload.floatingObject.isCollapsed
if (thisObject.collapsedManually === false) {
thisObject.isCollapsed = parent.payload.floatingObject.isCollapsed
}
if (parent === undefined) { return }
if (parent.payload === undefined) { return }
if (parent.payload.floatingObject === undefined) { return }
thisObject.isParentCollapsed = parent.payload.floatingObject.isCollapsed
if (thisObject.collapsedManually === false) {
thisObject.isCollapsed = parent.payload.floatingObject.isCollapsed
}
}
function tensionPhysics () {
/* Tension Effect */
if (thisObject.isTensed === true) {
let parent = thisObject.payload.chainParent
if (parent !== undefined) {
let distanceToChainParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ...
let parentChildren = canvas.designerSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node)
let axisCount = parentChildren.childrenCount
let axisIndex = parentChildren.childIndex
let baseAngle = 0
if (parent === undefined) { return }
if (parent.payload === undefined) { return }
if (parent.payload.position === undefined) { return }
if (axisIndex === undefined) {
axisCount = 1
axisIndex = axisCount
}
let distanceToChainParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ...
let parentChildren = canvas.designerSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node)
let axisCount = parentChildren.childrenCount
let axisIndex = parentChildren.childIndex
let baseAngle = 0
if (parent.payload.chainParent !== undefined && parent.payload.angle !== undefined) {
if (axisIndex === undefined) {
axisCount = 1
axisIndex = axisCount
}
if (parent.payload.chainParent !== undefined && parent.payload.angle !== undefined) {
axisCount++
axisIndex++
baseAngle = parent.payload.angle + 180
lastParentAngle = parent.payload.angle
} else {
if (lastParentAngle !== undefined) {
axisCount++
axisIndex++
baseAngle = parent.payload.angle + 180
lastParentAngle = parent.payload.angle
} else {
if (lastParentAngle !== undefined) {
axisCount++
axisIndex++
baseAngle = lastParentAngle + 180
}
baseAngle = lastParentAngle + 180
}
}
let angleStep = 360 / axisCount
let angleStep = 360 / axisCount
thisObject.payload.angle = baseAngle + (axisIndex - 1) * angleStep
if (thisObject.payload.angle >= 360) {
thisObject.payload.angle = thisObject.payload.angle - 360
}
thisObject.payload.angle = baseAngle + (axisIndex - 1) * angleStep
if (thisObject.payload.angle >= 360) {
thisObject.payload.angle = thisObject.payload.angle - 360
}
newPosition = {
x: parent.payload.position.x + distanceToChainParent * Math.cos(toRadians(thisObject.payload.angle)),
y: parent.payload.position.y + distanceToChainParent * Math.sin(toRadians(thisObject.payload.angle))
}
if (isNaN(newPosition.x) === false) {
thisObject.container.frame.position.x = newPosition.x
}
if (isNaN(newPosition.y) === false) {
thisObject.container.frame.position.y = newPosition.y
}
if (distanceToChainParent > 1000) { return } // this is introduced to avoid edges cases when importing workspaces.
newPosition = {
x: parent.payload.position.x + distanceToChainParent * Math.cos(toRadians(thisObject.payload.angle)),
y: parent.payload.position.y + distanceToChainParent * Math.sin(toRadians(thisObject.payload.angle))
}
if (isNaN(newPosition.x) === false) {
thisObject.container.frame.position.x = newPosition.x
}
if (isNaN(newPosition.y) === false) {
thisObject.container.frame.position.y = newPosition.y
}
}
}
@@ -339,16 +347,19 @@ function newFloatingObject () {
}
function drawBackground () {
if (canvas.floatingSpace.isItFar(thisObject.payload)) { return }
if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { return }
thisObject.payload.uiObject.drawBackground()
}
function drawMiddleground () {
if (canvas.floatingSpace.isItFar(thisObject.payload)) { return }
if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { return }
thisObject.payload.uiObject.drawMiddleground()
}
function drawForeground () {
if (canvas.floatingSpace.isItFar(thisObject.payload)) { return }
if ((thisObject.isCollapsed === true && thisObject.collapsedManually === false) || thisObject.isParentCollapsed === true) { return }
thisObject.payload.uiObject.drawForeground()
}
+215
View File
@@ -0,0 +1,215 @@
function newFormulaEditor () {
const MODULE_NAME = 'Formula Editor'
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,
activate: activate,
physics: physics,
drawBackground: drawBackground,
drawForeground: drawForeground,
getContainer: getContainer,
finalize: finalize,
initialize: initialize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isClickeable = false
thisObject.container.isDraggeable = false
thisObject.container.detectMouseOver = false
thisObject.container.frame.radius = 0
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
let isMouseOver = false
return thisObject
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 () {
if (thisObject.visible === true) {
thisObject.visible = false
let textArea = document.getElementById('textArea')
textArea.style.display = 'none'
thisObject.payload.node.code = textArea.value
}
}
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: 12px;' +
'background-color: rgb(' + UI_COLOR.MANGANESE_PURPLE + ');' +
'color:rgb(255, 255, 255);' +
'width: ' + thisObject.container.frame.width + 'px;' +
'height: ' + thisObject.container.frame.height + 'px'
textArea.style.display = 'block'
textArea.focus()
}
function getContainer (point) {
let container
if (thisObject.visible === true) {
if (point.x === VERY_LARGE_NUMBER) {
/* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that
anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is
triggered. We compensate recognizing this coordinate and returning our container. */
return thisObject.container
}
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
return thisObject.container
} else {
return undefined
}
}
}
function physics () {
if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) {
if (thisObject.currentRadius < thisObject.targetRadius) {
thisObject.currentRadius = thisObject.currentRadius + 0.5
} else {
thisObject.currentRadius = thisObject.currentRadius - 0.5
}
}
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 (thisObject.visible === true) {
let textAreaDiv = document.getElementById('textAreaDiv')
textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; '
}
}
function drawBackground () {
if (thisObject.visible === true) {
let position = {
x: 0,
y: 0
}
position = thisObject.container.frame.frameThisPoint(position)
let radius = thisObject.container.frame.radius * 2
if (radius > 0.5) {
browserCanvasContext.beginPath()
browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')'
browserCanvasContext.fill()
browserCanvasContext.beginPath()
browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', ' + 1 + ')'
browserCanvasContext.fill()
}
}
}
function drawForeground () {
let iconPosition = {
x: 0,
y: thisObject.currentRadius * 1.5
}
iconPosition = thisObject.container.frame.frameThisPoint(iconPosition)
/* Menu Item */
if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) {
browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2)
/* Menu Label */
let label = 'Code looks good!'
let labelPoint
let fontSize = 10
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) {
labelPoint = {
x: iconPosition.x + thisObject.currentRadius + 10,
y: iconPosition.y + fontSize * FONT_ASPECT_RATIO
}
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
}
}
+108 -11
View File
@@ -15,6 +15,9 @@ function newUiObject () {
container: undefined,
payload: undefined,
codeEditor: undefined,
configEditor: undefined,
conditionEditor: undefined,
formulaEditor: undefined,
uiObjectTitle: undefined,
circularProgressBar: undefined,
isExecuting: undefined,
@@ -115,6 +118,21 @@ function newUiObject () {
thisObject.codeEditor = undefined
}
if (thisObject.configEditor !== undefined) {
thisObject.configEditor.finalize()
thisObject.configEditor = undefined
}
if (thisObject.conditionEditor !== undefined) {
thisObject.conditionEditor.finalize()
thisObject.conditionEditor = undefined
}
if (thisObject.formulaEditor !== undefined) {
thisObject.formulaEditor.finalize()
thisObject.formulaEditor = undefined
}
icon = undefined
chainAttachToNode = undefined
referenceAttachToNode = undefined
@@ -156,6 +174,21 @@ function newUiObject () {
if (container !== undefined) { return container }
}
if (thisObject.configEditor !== undefined) {
container = thisObject.configEditor.getContainer(point)
if (container !== undefined) { return container }
}
if (thisObject.conditionEditor !== undefined) {
container = thisObject.conditionEditor.getContainer(point)
if (container !== undefined) { return container }
}
if (thisObject.formulaEditor !== undefined) {
container = thisObject.formulaEditor.getContainer(point)
if (container !== undefined) { return container }
}
container = thisObject.uiObjectTitle.getContainer(point)
if (container !== undefined) { return container }
@@ -178,6 +211,18 @@ function newUiObject () {
thisObject.codeEditor.physics()
}
if (thisObject.configEditor !== undefined) {
thisObject.configEditor.physics()
}
if (thisObject.conditionEditor !== undefined) {
thisObject.conditionEditor.physics()
}
if (thisObject.formulaEditor !== undefined) {
thisObject.formulaEditor.physics()
}
if (thisObject.payload.chainParent === undefined || thisObject.payload.chainParent.payload === undefined) {
thisObject.payload.targetPosition.x = thisObject.payload.position.x,
thisObject.payload.targetPosition.y = thisObject.payload.position.y
@@ -505,7 +550,7 @@ function newUiObject () {
compatibleType = '->' + 'Situation' + '->'
compatibleSubType = undefined
break
case 'Code':
case 'Javascript Code':
compatibleType = '->' + 'Condition' + '->' + 'Procedure Initialization' + '->' + 'Procedure Loop' + '->' + 'Plotter Module' + '->' + 'Plotter Panel' + '->'
compatibleSubType = undefined
break
@@ -564,7 +609,7 @@ function newUiObject () {
if (thisObject.payload.node.type === 'Take Profit' && nearbyNode.takeProfit !== undefined) { continue }
if (thisObject.payload.node.type === 'Formula' && nearbyNode.formula !== undefined) { continue }
if (thisObject.payload.node.type === 'Next Phase Event' && nearbyNode.nextPhaseEvent !== undefined) { continue }
if (thisObject.payload.node.type === 'Code' && nearbyNode.code !== undefined) { continue }
if (thisObject.payload.node.type === 'Javascript Code' && nearbyNode.javascriptCode !== undefined) { continue }
/* Here we check if the subtypes are compatible. */
if (nearbyNode.subType !== undefined && compatibleSubType !== undefined) {
if (compatibleSubType.indexOf('->' + nearbyNode.subType + '->') < 0) {
@@ -711,6 +756,10 @@ function newUiObject () {
compatibleType = '->' + 'Process Definition' + '->'
compatibleSubType = undefined
break
case 'Product Definition':
compatibleType = '->' + 'Plotter Module' + '->'
compatibleSubType = undefined
break
default:
return
}
@@ -835,11 +884,12 @@ function newUiObject () {
highlightCounter = 30
}
function setErrorMessage (message) {
function setErrorMessage (message, duration) {
if (message !== undefined) {
errorMessage = message
hasError = true
errorMessageCounter = 100
if (duration === undefined) { duration = 1 }
errorMessageCounter = 100 * duration
}
}
@@ -923,6 +973,15 @@ function newUiObject () {
if (thisObject.codeEditor !== undefined) {
thisObject.codeEditor.deactivate()
}
if (thisObject.configEditor !== undefined) {
thisObject.configEditor.deactivate()
}
if (thisObject.conditionEditor !== undefined) {
thisObject.conditionEditor.deactivate()
}
if (thisObject.formulaEditor !== undefined) {
thisObject.formulaEditor.deactivate()
}
}
function onDisplace (event) {
@@ -934,6 +993,15 @@ function newUiObject () {
if (thisObject.codeEditor !== undefined) {
thisObject.codeEditor.deactivate()
}
if (thisObject.configEditor !== undefined) {
thisObject.configEditor.deactivate()
}
if (thisObject.conditionEditor !== undefined) {
thisObject.conditionEditor.deactivate()
}
if (thisObject.formulaEditor !== undefined) {
thisObject.formulaEditor.deactivate()
}
isDragging = true
if (event.button === 2) {
rightDragging = true
@@ -1004,16 +1072,43 @@ function newUiObject () {
thisObject.codeEditor.drawBackground()
thisObject.codeEditor.drawForeground()
}
if (thisObject.configEditor !== undefined) {
thisObject.configEditor.drawBackground()
thisObject.configEditor.drawForeground()
}
if (thisObject.conditionEditor !== undefined) {
thisObject.conditionEditor.drawBackground()
thisObject.conditionEditor.drawForeground()
}
if (thisObject.formulaEditor !== undefined) {
thisObject.formulaEditor.drawBackground()
thisObject.formulaEditor.drawForeground()
}
let drawMenu = true
if (thisObject.codeEditor !== undefined) {
if (thisObject.codeEditor.visible === false) {
drawBodyAndPicture()
if (isDragging === false) {
thisObject.menu.drawBackground()
thisObject.menu.drawForeground()
}
if (thisObject.codeEditor.visible === true) {
drawMenu = false
}
} else {
}
if (thisObject.configEditor !== undefined) {
if (thisObject.configEditor.visible === true) {
drawMenu = false
}
}
if (thisObject.conditionEditor !== undefined) {
if (thisObject.conditionEditor.visible === true) {
drawMenu = false
}
}
if (thisObject.formulaEditor !== undefined) {
if (thisObject.formulaEditor.visible === true) {
drawMenu = false
}
}
if (drawMenu === true) {
drawBodyAndPicture()
if (isDragging === false) {
thisObject.menu.drawBackground()
@@ -1089,6 +1184,8 @@ function newUiObject () {
function drawReferenceLine () {
if (thisObject.payload.referenceParent === undefined) { return }
if (thisObject.payload.referenceParent.payload === undefined) { return }
if (thisObject.payload.referenceParent.payload.floatingObject === undefined) { return }
if (thisObject.payload.referenceParent.payload.floatingObject.isParentCollapsed === true) { return }
let targetPoint = {
File diff suppressed because it is too large. Load diff
+122
View File
@@ -0,0 +1,122 @@
function newPlotterPanel () {
const MODULE_NAME = 'Plotter Panel'
const ERROR_LOG = true
const INTENSIVE_LOG = false
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
fitFunction: undefined,
onRecordChange: onRecordChange,
container: undefined,
draw: draw,
getContainer: getContainer,
initialize: initialize
}
let container = newContainer()
container.initialize()
thisObject.container = container
container.frame.containerName = 'Plotter Panel'
let currentRecord
let panelTabButton
let panelNode
return thisObject
function initialize (pPanelNode) {
panelNode = pPanelNode
container.frame.containerName = panelNode.name
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL
thisObject.container.frame.position.x = viewPort.visibleArea.topRight.x - thisObject.container.frame.width * 5
thisObject.container.frame.position.y = viewPort.visibleArea.bottomLeft.y - thisObject.container.frame.height
panelTabButton = newPanelTabButton()
panelTabButton.parentContainer = thisObject.container
panelTabButton.container.frame.parentFrame = thisObject.container.frame
panelTabButton.fitFunction = thisObject.fitFunction
panelTabButton.initialize()
}
function getContainer (point) {
let container
container = panelTabButton.getContainer(point)
if (container !== undefined) { return container }
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
let checkPoint = {
x: point.x,
y: point.y
}
checkPoint = thisObject.fitFunction(checkPoint)
if (point.x === checkPoint.x && point.y === checkPoint.y) {
return thisObject.container
}
}
}
function onRecordChange (pCurrentRecord) {
currentRecord = pCurrentRecord
}
function draw () {
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction)
plotCurrentRecordData()
panelTabButton.draw()
}
function plotCurrentRecordData () {
const frameBodyHeight = thisObject.container.frame.getBodyHeight()
const frameTitleHeight = thisObject.container.frame.height - frameBodyHeight
const X_AXIS = thisObject.container.frame.width / 2
const Y_AXIS = frameTitleHeight + frameBodyHeight / 2
const PANEL_HEIGHT = frameTitleHeight + frameBodyHeight
if (currentRecord === undefined) { return }
if (currentRecord.data === undefined) { return }
try {
eval(panelNode.javascriptCode.code)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
}
function printLabel (labelToPrint, x, y, opacity) {
let labelPoint
let fontSize = 10
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY
let label = '' + labelToPrint
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
labelPoint = {
x: x - xOffset,
y: y
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
labelPoint = thisObject.fitFunction(labelPoint)
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
browserCanvasContext.closePath()
browserCanvasContext.fill()
}
}
+6 -3
View File
@@ -152,10 +152,13 @@ function newProductCard () {
let team = ecosystem.getTeam(thisObject.product.plotter.devTeam)
let plotter = ecosystem.getPlotter(team, thisObject.product.plotter.codeName)
let plotterModule = ecosystem.getPlotterModule(plotter, thisObject.product.plotter.moduleName)
thisObject.product.plotter.profilePicture = plotterModule.profilePicture
thisObject.product.plotter.module = plotterModule
if (plotter !== undefined) {
let plotterModule = ecosystem.getPlotterModule(plotter, thisObject.product.plotter.moduleName)
thisObject.product.plotter.profilePicture = plotterModule.profilePicture
thisObject.product.plotter.module = plotterModule
}
/* Lets set the basic dimensions of this thisObject. */
+129 -17
View File
@@ -66,6 +66,7 @@ function newProductsPanel () {
ecosystem = getUserEcosystem()
}
/* For legacy plotters, we will add product cards based on the old ecosystem file */
for (let i = 0; i < ecosystem.devTeams.length; i++) {
let devTeam = ecosystem.devTeams[i]
@@ -83,6 +84,116 @@ function newProductsPanel () {
}
}
/* For new plotters defined at the UI, we will add product cards based on what we find at the workspace */
let workspaceNode = canvas.designerSpace.workspace.workspaceNode
for (let i = 0; i < workspaceNode.rootNodes.length; i++) {
let rootNode = workspaceNode.rootNodes[i]
if (rootNode.type === 'Team') {
let teamNode = rootNode
let team = {}
if (teamNode.code === undefined) { continue }
try {
let code = JSON.parse(teamNode.code)
team.codeName = code.codeName
} catch (err) {
continue
}
for (let j = 0; j < teamNode.indicatorBots.length; j++) {
let botNode = teamNode.indicatorBots[j]
let bot = {}
if (botNode.code === undefined) { continue }
try {
let code = JSON.parse(botNode.code)
bot.codeName = code.codeName
} catch (err) {
continue
}
for (let k = 0; k < botNode.products.length; k++) {
let productNode = botNode.products[k]
let product = {}
if (productNode.code === undefined) { continue }
try {
let code = JSON.parse(productNode.code)
product.codeName = code.codeName
} catch (err) {
continue
}
if (productNode.payload.referenceParent === undefined) { continue }
let plotterModuleNode = productNode.payload.referenceParent
let plotterModule = {}
if (plotterModuleNode.code === undefined) { continue }
try {
let code = JSON.parse(plotterModuleNode.code)
plotterModule.codeName = code.codeName
} catch (err) {
continue
}
if (plotterModuleNode.payload.parentNode === undefined) { continue }
let plotterNode = plotterModuleNode.payload.parentNode
let plotter = {}
if (plotterNode.code === undefined) { continue }
try {
let code = JSON.parse(plotterNode.code)
plotter.codeName = code.codeName
} catch (err) {
continue
}
if (plotterNode.payload.parentNode === undefined) { continue }
let plotterTeamNode = plotterNode.payload.parentNode
let plotterTeam = {}
if (plotterTeamNode.code === undefined) { continue }
try {
let code = JSON.parse(plotterTeamNode.code)
plotterTeam.codeName = code.codeName
} catch (err) {
continue
}
if (plotterModuleNode.javascriptCode === undefined) { continue }
if (plotterModuleNode.javascriptCode.code === undefined) { continue }
/* Conversion to fit old format */
product.plotter = plotter
product.plotter.devTeam = plotterTeam.codeName
product.plotter.moduleName = plotterModule.codeName
product.plotter.legacy = false
product.plotter.module = { panels: [] }
product.displayName = productNode.name
product.dataSets = []
product.exchangeList = [{'name': 'Poloniex'}]
product.node = productNode
team.displayName = teamNode.name
team.host = {'url': 'localhost'}
bot.displayName = botNode.name
for (let m = 0; m < productNode.datasets.length; m++) {
let dataset = productNode.datasets[m]
if (dataset.code === undefined) { continue }
try {
let code = JSON.parse(dataset.code)
product.dataSets.push(code)
} catch (err) {
continue
}
}
addProductCard(team, bot, product)
}
}
}
}
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
isInitialized = true
}
@@ -313,27 +424,28 @@ function newProductsPanel () {
if (process.session !== undefined) {
if (process.session.layerManager !== undefined) {
let layerManager = process.session.layerManager
if (layerManager.payload.floatingObject.isCollapsed !== true) {
if (bot.products !== undefined) {
for (let k = 0; k < bot.products.length; k++) {
let product = bot.products[k]
if (bot.products !== undefined) {
for (let k = 0; k < bot.products.length; k++) {
let product = bot.products[k]
for (let p = 0; p < layerManager.layers.length; p++) {
let layer = layerManager.layers[p]
let layerCode
try {
layerCode = JSON.parse(layer.code)
} catch (err) {
for (let p = 0; p < layerManager.layers.length; p++) {
let layer = layerManager.layers[p]
let layerCode
try {
layerCode = JSON.parse(layer.code)
} catch (err) {
// if we can not parse this, then we ignore this trading engine.
}
}
if (product.codeName === layerCode.product) {
if (product.codeName === layerCode.product) {
/* We have a layer that is matching the current product */
let cardCode = exchange + '-' + market.assetB + '/' + market.assetA + '-' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName + '-' + process.session.id
let cardFound = removeFromLocalProductCards(cardCode)
if (cardFound !== true) {
productCard = addProductCard(devTeam, bot, product, process.session)
onProductCardStatusChanged(productCard)
let cardCode = exchange + '-' + market.assetB + '/' + market.assetA + '-' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName + '-' + process.session.id
let cardFound = removeFromLocalProductCards(cardCode)
if (cardFound !== true) {
productCard = addProductCard(devTeam, bot, product, process.session)
onProductCardStatusChanged(productCard)
}
}
}
}
+521
View File
@@ -0,0 +1,521 @@
function newPlotter () {
const MODULE_NAME = 'Plotter'
const ERROR_LOG = true
const INTENSIVE_LOG = false
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
/* Events declared outside the plotter. */
onDailyFileLoaded: onDailyFileLoaded,
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
getContainer: getContainer,
setTimePeriod: setTimePeriod,
setDatetime: setDatetime,
recalculateScale: recalculateScale,
draw: draw,
// Secondary functions and properties.
currentRecord: undefined // ---> Check Here
}
let container = newContainer()
container.initialize()
thisObject.container = container
let timeLineCoordinateSystem = newTimeLineCoordinateSystem() // Needed to be able to plot on the timeline, otherwise not.
let timePeriod // This will hold the current Time Period the user is at.
let datetime // This will hold the current Datetime the user is at.
let marketFile // This is the current Market File being plotted.
let fileCursor // This is the current File Cursor being used to retrieve Daily Files.
let marketFiles // This object will provide the different Market Files at different Time Periods.
let dailyFiles // This object will provide the different File Cursors at different Time Periods.
let productDefinition // Here we store a snapshot of the product definition which references this plotter.
let records = [] // We will have the information to be plotted here.
let zoomChangedEventSubscriptionId
let offsetChangedEventSubscriptionId
let dragFinishedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let marketFilesUpdatedEventSubscriptionId
let dailyFilesUpdatedEventSubscriptionId
return thisObject
function finalize () {
try {
/* Stop listening to the necesary events. */
viewPort.eventHandler.stopListening(zoomChangedEventSubscriptionId)
viewPort.eventHandler.stopListening(offsetChangedEventSubscriptionId)
canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId)
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId)
dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId)
/* Clear References */
marketFiles = undefined
dailyFiles = undefined
datetime = undefined
timePeriod = undefined
marketFile = undefined
fileCursor = undefined
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
}
}
function initialize (pStorage, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction, pProductDefinition) {
try {
/* Store the information received. */
marketFiles = pStorage.marketFiles[0]
dailyFiles = pStorage.dailyFiles[0]
datetime = pDatetime
timePeriod = pTimePeriod
productDefinition = pProductDefinition
/* We need a Market File in order to calculate the Y scale, since this scale depends on actual data. */
marketFile = marketFiles.getFile(ONE_DAY_IN_MILISECONDS) // This file is the one processed faster.
recalculateScale()
/* Now we set the right files according to current Period. */
marketFile = marketFiles.getFile(pTimePeriod)
fileCursor = dailyFiles.getFileCursor(pTimePeriod)
/* Listen to the necesary events. */
zoomChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
offsetChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent('Offset Changed', onOffsetChanged)
dragFinishedEventSubscriptionId = canvas.eventHandler.listenToEvent('Drag Finished', onDragFinished)
marketFilesUpdatedEventSubscriptionId = marketFiles.eventHandler.listenToEvent('Files Updated', onMarketFilesUpdated)
dailyFilesUpdatedEventSubscriptionId = dailyFiles.eventHandler.listenToEvent('Files Updated', onDailyFilesUpdated)
/* Get ready for plotting. */
recalculate()
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculateScale()
recalculate()
})
callBackFunction()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
function onMarketFilesUpdated () {
try {
let newMarketFile = marketFiles.getFile(timePeriod)
if (newMarketFile !== undefined) {
marketFile = newMarketFile
recalculate()
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onMarketFilesUpdated -> err = ' + err.stack) }
}
}
function onDailyFilesUpdated () {
try {
let newFileCursor = dailyFiles.getFileCursor(timePeriod)
if (newFileCursor !== undefined) {
fileCursor = newFileCursor
recalculate()
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDailyFilesUpdated -> err = ' + err.stack) }
}
}
function getContainer (point) {
try {
let container
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point) === true) {
return this.container
} else {
/* This point does not belong to this space. */
return undefined
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] getContainer -> err = ' + err) }
}
}
function setTimePeriod (pTimePeriod) {
try {
if (timePeriod !== pTimePeriod) {
timePeriod = pTimePeriod
if (timePeriod >= _1_HOUR_IN_MILISECONDS) {
let newMarketFile = marketFiles.getFile(pTimePeriod)
if (newMarketFile !== undefined) {
marketFile = newMarketFile
recalculate()
}
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimePeriod)
if (newFileCursor !== undefined) {
fileCursor = newFileCursor
recalculate()
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] setTimePeriod -> err = ' + err) }
}
}
function setDatetime (pDatetime) {
datetime = pDatetime
}
function onDailyFileLoaded (event) {
try {
if (event.currentValue === event.totalValue) {
/* This happens only when all of the files in the cursor have been loaded. */
recalculate()
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDailyFileLoaded -> err = ' + err) }
}
}
function draw () {
try {
this.container.frame.draw()
plotChart()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] draw -> err = ' + err) }
}
}
function recalculate () {
try {
if (timePeriod >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles()
} else {
recalculateUsingDailyFiles()
}
thisObject.container.eventHandler.raiseEvent('CandleStairs Changed', records) // --> Check This
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] recalculate -> err = ' + err) }
}
}
function jsonifyDataFile (dataFile, recordDefinition, farLeftDate, farRightDate) {
/*
This function has as an input the raw data on files and creates with it an array of JSON objects
with not calculated properties for later being consumed by Formulas
*/
let jsonifiedArray = []
let previous
for (let i = 0; i < dataFile.length; i++) {
let record = {}
for (let j = 0; j < recordDefinition.properties.length; j++) {
let property = recordDefinition.properties[j]
if (property.code.isCalculated !== true) {
record[property.code.codeName] = dataFile[i][j]
}
}
if (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) {
record.previous = previous
jsonifiedArray.push(record)
previous = record
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
thisObject.currentRecord = record
thisObject.container.eventHandler.raiseEvent('Current Record Changed', thisObject.currentRecord)
}
}
}
return jsonifiedArray
}
function calculationsProcedure (jsonArray, recordDefinition, calculationsProcedure, timePeriod) {
/*
This function has as an input an array of JSON objects, and it adds calculated properties to
complete the set of properties that will be available.
*/
let system = { // These are the available system variables to be used in User Code and Formulas
timePeriod: timePeriod,
ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS
}
let variable = {} // This is the structure where the user will define its own variables that will be shared across different code blocks and formulas.
let results = []
/* This is Initialization Code */
if (calculationsProcedure.initialization !== undefined) {
if (calculationsProcedure.initialization.javascriptCode !== undefined) {
try {
eval(calculationsProcedure.initialization.javascriptCode.code)
} catch (err) {
logger.write('[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Error = ' + err.stack)
logger.write('[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Code = ' + calculationsProcedure.initialization.javascriptCode.code)
throw ('Error Executing User Code.')
}
}
}
/* This is Initialization Code */
if (calculationsProcedure.loop !== undefined) {
if (calculationsProcedure.loop.javascriptCode !== undefined) {
for (let index = 0; index < jsonArray.length; index++) {
let product = jsonArray[index]
/* This is Loop Code */
try {
eval(calculationsProcedure.loop.javascriptCode.code)
} catch (err) {
logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. Error = ' + err.stack)
logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. product = ' + JSON.stringify(product))
logger.write('[ERROR] calculationsProcedure -> loop -> Error executing User Code. Code = ' + calculationsProcedure.loop.javascriptCode.code)
throw ('Error Executing User Code.')
}
/* For each calculated property we apply its formula */
for (let j = 0; j < recordDefinition.properties.length; j++) {
let property = recordDefinition.properties[j]
if (property.code.isCalculated === true) {
if (property.formula !== undefined) {
if (property.formula.code !== undefined) {
try {
let newValue = eval(property.formula.code)
let currentRecord = product
currentRecord[property.code.codeName] = newValue
} catch (err) {
logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Error = ' + err.stack)
logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. product = ' + JSON.stringify(product))
logger.write('[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Code = ' + property.formula.code)
throw ('Error Executing User Code.')
}
}
}
}
}
/* Adding the new element to the resulting array */
results.push(product)
}
}
}
return results
}
function recalculateUsingDailyFiles () {
try {
if (fileCursor === undefined) { return } // We need to wait until there is a fileCursor
if (fileCursor.files.size === 0) { return } // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timePeriod)
let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem)
let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, timeLineCoordinateSystem)
let dateDiff = rightDate.valueOf() - leftDate.valueOf()
let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5)
let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5)
let currentDate = new Date(farLeftDate.valueOf())
records = []
while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) {
let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2)
let dailyFile = fileCursor.files.get(stringDate)
if (dailyFile !== undefined) {
/* Transform the current file content into an array of JSON objects */
let jsonData = jsonifyDataFile(dailyFile, productDefinition.record, farLeftDate, farRightDate)
/* Add the calculated properties */
if (productDefinition.calculations !== undefined) {
let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timePeriod)
records.push(...calculationsResult) // This adds records to the current array.
} else {
records.push(...jsonData)// This adds records to the current array.
}
}
currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS)
}
/* Lests check if all the visible screen is going to be covered by candle-record. */
let lowerEnd = leftDate.valueOf()
let upperEnd = rightDate.valueOf()
if (records.length > 0) {
if (records[0].begin > lowerEnd || records[records.length - 1].end < upperEnd) {
setTimeout(recalculate, 2000)
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingDailyFiles -> err = ' + err) }
}
}
function recalculateUsingMarketFiles () {
try {
if (marketFile === undefined) { return } // Initialization not complete yet.
let daysOnSides = getSideDays(timePeriod)
let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem)
let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, timeLineCoordinateSystem)
let dateDiff = rightDate.valueOf() - leftDate.valueOf()
leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5)
rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5)
records = []
/* Transform the current file content into an array of JSON objects */
let jsonData = jsonifyDataFile(marketFile, productDefinition.record, leftDate, rightDate)
/* Add the calculated properties */
if (productDefinition.calculations !== undefined) {
let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timePeriod)
records.push(...calculationsResult) // This adds records to the current array.
} else {
records.push(...jsonData)// This adds records to the current array.
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] recalculateUsingMarketFiles -> err = ' + err) }
}
}
function recalculateScale () {
try {
if (timeLineCoordinateSystem.maxValue > 0) { return } // Already calculated.
let minValue = {
x: MIN_PLOTABLE_DATE.valueOf(),
y: 0
}
let maxValue = {
x: MAX_PLOTABLE_DATE.valueOf(),
y: nextPorwerOf10(USDT_BTC_HTH) / 4 // TODO: This 4 is temporary
}
timeLineCoordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
thisObject.container.frame.height
)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] recalculateScale -> err = ' + err) }
}
}
function plotChart () {
try {
let userPosition = getUserPosition()
let userPositionDate = userPosition.point.x
/* Clean the pannel at places where there is no record. */
let currentRecord = {
data: undefined
}
thisObject.container.eventHandler.raiseEvent('Current Record Changed', currentRecord)
for (let i = 0; i < records.length; i++) {
let record = records[i]
let beginPoint = {
x: record.begin,
y: 0
}
let endPoint = {
x: record.end,
y: 0
}
beginPoint = timeLineCoordinateSystem.transformThisPoint(beginPoint)
endPoint = timeLineCoordinateSystem.transformThisPoint(endPoint)
beginPoint = transformThisPoint(beginPoint, thisObject.container)
endPoint = transformThisPoint(endPoint, thisObject.container)
if (endPoint.x < viewPort.visibleArea.bottomLeft.x || beginPoint.x > viewPort.visibleArea.bottomRight.x) {
continue
}
let atMousePosition = false
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
atMousePosition = true
let currentRecord = {
data: record
}
thisObject.container.eventHandler.raiseEvent('Current Record Changed', currentRecord)
}
eval(productDefinition.referenceParent.javascriptCode.code)
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] plotChart -> err = ' + err) }
}
}
function onZoomChanged (event) {
try {
recalculate()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onZoomChanged -> err = ' + err) }
}
}
function onDragFinished () {
try {
recalculate()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDragFinished -> err = ' + err) }
}
}
function onOffsetChanged (event) {
try {
if (event !== undefined) {
if (event.recalculate === true) {
recalculate()
return
}
}
if (Math.random() * 100 > 95) {
recalculate()
};
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onOffsetChanged -> err = ' + err) }
}
}
}
+28 -11
View File
@@ -14,13 +14,6 @@ function newTimePeriodScale () {
const TIME_PERIOD_DEFAULT_VALUE = 0
const MIN_HEIGHT = 50
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = false
thisObject.container.isWheelable = true
let mouse = {
position: {
x: 0,
@@ -36,33 +29,57 @@ function newTimePeriodScale () {
let timePeriodsMasterArray = [marketFilesPeriods, dailyFilePeriods]
let timePeriodLabel = ''
let onMouseWheelEventSubscriptionId
let onMouseOverEventSubscriptionId
let onMouseNotOverEventSubscriptionId
let onZoomChangedEventSubscriptionId
setupContainer()
return thisObject
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = false
thisObject.container.isWheelable = true
}
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onZoomChangedEventSubscriptionId)
timeLineCoordinateSystem = undefined
objectStorage = undefined
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
}
function initialize (pTimeLineCoordinateSystem) {
timeLineCoordinateSystem = pTimeLineCoordinateSystem
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
readObjectState()
newTimePeriod()
thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
mouse.position.x = event.x
mouse.position.y = event.y
visible = true
})
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) {
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) {
visible = false
})
viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
onZoomChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
}
function onZoomChanged (event) {
+14 -9
View File
@@ -30,17 +30,21 @@ function newChartSpace () {
finalize: finalize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.isWheelable = false
let canvasBrowserResizedEventSubscriptionId
const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25
setupContainer()
return thisObject
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.isWheelable = false
}
function finalize () {
for (let i = 0; i < thisObject.timeMachines.length; i++) {
let timeMachine = thisObject.timeMachines[i]
@@ -51,9 +55,10 @@ function newChartSpace () {
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
}
function initialize (callBackFunction) {
function initialize () {
let initializedCounter = 0
let toInitialize = 1
@@ -75,14 +80,14 @@ function newChartSpace () {
initializedCounter++
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
callBackFunction(err)
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> Initialization Failed. -> Err ' + err.message) }
return
}
thisObject.timeMachines.push(timeMachine)
if (initializedCounter === toInitialize) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
viewPort.raiseEvents() // These events will impacts on objects just initialized.
}
}
}
+21
View File
@@ -9,6 +9,9 @@
fullscreen: undefined,
toTop: toTop,
toBottom: toBottom,
toMiddle: toMiddle,
moveUp: moveUp,
moveDown: moveDown,
draw: draw,
physics: physics,
getContainer: getContainer,
@@ -87,6 +90,24 @@
thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT
}
function toMiddle () {
thisObject.container.frame.position.y = browserCanvas.height / 2 - COCKPIT_SPACE_HEIGHT
}
function moveUp () {
thisObject.container.frame.position.y = thisObject.container.frame.position.y - browserCanvas.height / 10
if (thisObject.container.frame.position.y < 0) {
thisObject.container.frame.position.y = 0
}
}
function moveDown () {
thisObject.container.frame.position.y = thisObject.container.frame.position.y + browserCanvas.height / 10
if (thisObject.container.frame.position.y > browserCanvas.height - COCKPIT_SPACE_HEIGHT) {
thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT
}
}
function physics () {
thisObjectPhysics()
childrenPhysics()
+12 -5
View File
@@ -3,7 +3,6 @@ function newDesignerSpace () {
const MODULE_NAME = 'Strategy Space'
let thisObject = {
sidePanel: undefined,
strategizerGateway: undefined,
container: undefined,
iconCollection: undefined,
iconByUiObjectType: undefined,
@@ -27,12 +26,10 @@ function newDesignerSpace () {
return thisObject
async function initialize () {
function initialize () {
loadIconCollection()
buildIconByUiObjectTypeMap()
thisObject.strategizerGateway = newStrategizerGateway()
thisObject.workspace = newWorkspace()
thisObject.workspace.initialize()
}
@@ -89,7 +86,7 @@ function newDesignerSpace () {
['Next Phase Event', 'pantone'],
['Situation', 'pyramid'],
['Condition', 'testing'],
['Code', 'html'],
['Javascript Code', 'html'],
['Team', 'team'],
['Sensor Bot', 'bot-sensor'],
['Indicator Bot', 'bot-indicator'],
@@ -121,6 +118,16 @@ function newDesignerSpace () {
let icon = thisObject.iconCollection.get(record[1])
thisObject.iconByUiObjectType.set(record[0], icon)
}
/* Take types-icons relationships defined at the schema */
for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) {
let nodeDefinition = APP_SCHEMA_ARRAY[i]
let iconName = nodeDefinition.icon
if (iconName !== undefined) {
let icon = thisObject.iconCollection.get(iconName)
thisObject.iconByUiObjectType.set(nodeDefinition.type, icon)
}
}
}
function loadIconCollection () {
+77 -1
View File
@@ -20,6 +20,8 @@ function newFloatingSpace () {
positionAtNode: positionAtNode,
fitIntoVisibleArea: fitIntoVisibleArea,
isThisPointVisible: isThisPointVisible,
isItFar: isItFar,
warmUp: warmUp,
makeVisible: makeVisible,
makeInvisible: makeInvisible,
draw: draw,
@@ -46,15 +48,27 @@ function newFloatingSpace () {
thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2
let visible = false
let warmingUpCounter = 0
const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25
let eventSubscriptionId
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(eventSubscriptionId)
thisObject.floatingLayer.finalize()
thisObject.profileBalls.finalize()
thisObject.uiObjectConstructor.finalize()
thisObject.noteSets.finalize()
thisObject.container.finalize()
thisObject.floatingLayer = undefined
thisObject.profileBalls = undefined
thisObject.uiObjectConstructor = undefined
thisObject.noteSets = undefined
thisObject.container = undefined
}
function initialize (callBackFunction) {
@@ -70,7 +84,69 @@ function newFloatingSpace () {
thisObject.uiObjectConstructor = newUiObjectConstructor()
thisObject.uiObjectConstructor.initialize(thisObject.floatingLayer)
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
eventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
}
function warmUp () {
warmingUpCounter = 0
}
function isItFar (payload, dontCheckParent) {
/* If for any reason the paylaod is undefined we return false */
if (payload === undefined) { return false }
/*
We need a warm up in order to allow all objects to stabilize into a consistant state.
After that we will start evaluating which ones are too far from the current user view.
*/
if (warmingUpCounter < 10000) {
warmingUpCounter++
return false
}
let radarFactor = 2 // How big is the margin
/* If the chain parent is not far, they we dont consither this far. */
if (dontCheckParent !== true) {
if (payload.chainParent !== undefined) {
if (isItFar(payload.chainParent.payload, true) === false) { return false }
}
}
/* Exceptions that are never considered far. */
if (
payload.node.type === 'Definition' ||
payload.node.type === 'Network' ||
payload.node.type === 'Team'
) {
return false
}
/* Another exception are the ones who have reference parents */
if (payload.referenceParent !== undefined) { return false }
/* Here we will check the position of a floatingobject to see if it is outside the screen, with a margin of one screen around. */
let point = thisObject.container.frame.frameThisPoint(payload.position)
if (point.x > browserCanvas.width + browserCanvas.width * radarFactor) {
return true
}
if (point.x < 0 - browserCanvas.width * radarFactor) {
return true
}
let bottom = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT
let heightDiff = browserCanvas.height - bottom
if (point.y < bottom - heightDiff * radarFactor) {
return true
}
if (point.y > browserCanvas.height + heightDiff * radarFactor) {
return true
}
return false
}
function fitIntoVisibleArea (point) {
+15 -6
View File
@@ -35,7 +35,7 @@ function newPanelsSpace () {
}
function createNewPanel (pType, pParameters, pOwner, pSession) {
function createNewPanel (pType, pParameters, pOwner, pSession, pPanelCode) {
let panel
switch (pType) {
@@ -56,11 +56,20 @@ function newPanelsSpace () {
}
case 'Plotter Panel':
{
panel = getNewPlotterPanel(pParameters.devTeam, pParameters.plotterCodeName, pParameters.moduleCodeName, pParameters.panelCodeName)
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
panel.session = pSession
panel.initialize()
if (pPanelCode !== undefined) {
panel = newPlotterPanel()
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
panel.session = pSession
panel.initialize(pPanelCode)
} else {
panel = getNewPlotterPanel(pParameters.devTeam, pParameters.plotterCodeName, pParameters.moduleCodeName, pParameters.panelCodeName)
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
panel.session = pSession
panel.initialize()
}
break
}
}
+4 -3
View File
@@ -57,13 +57,14 @@ function newSplashScreen () {
function draw () {
if (splashScreenNeeded === false) {
stepsInitializationCounter = 100
canDrawLogo = false
fadeOutCounter++
if (fadeOutCounter > 20) {
if (fadeOutCounter > 2) {
return
}
opacity = opacity - 0.1
opacity = opacity - 1
}
thisObject.container.frame.draw(false, false)
@@ -100,7 +101,7 @@ function newSplashScreen () {
/* Second the % of Advance. */
let label = '' + Math.trunc(stepsInitializationCounter) + ' %'
stepsInitializationCounter = stepsInitializationCounter + 2.0
stepsInitializationCounter = stepsInitializationCounter + 5.0
if (stepsInitializationCounter > 99) {
splashScreenNeeded = false